All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: roland@redhat.com, oleg@redhat.com, jan.kratochvil@redhat.com,
	linux-kernel@vger.kernel.org
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
	Tejun Heo <tj@kernel.org>
Subject: [PATCH 07/10] signal: use GROUP_STOP_PENDING to stop once for a single group stop
Date: Fri, 28 Jan 2011 16:08:41 +0100	[thread overview]
Message-ID: <1296227324-25295-8-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1296227324-25295-1-git-send-email-tj@kernel.org>

Currently task->signal->group_stop_count is used to decide whether to
stop for group stop.  However, if there is a task in the group which
is taking a long time to stop, other tasks which are continued by
ptrace would repeatedly stop for the same group stop until the group
stop is complete.

Conversely, if a ptraced task is in TASK_TRACED state, the debugger
won't get notified of group stops which is inconsistent compared to
the ptraced task in any other state.

This patch introduces GROUP_STOP_PENDING which tracks whether a task
is yet to stop for the group stop in progress.  The flag is set when a
group stop starts and cleared when the task stops the first time for
the group stop, and consulted whenever whether the task should
participate in a group stop needs to be determined.  Note that now
tasks in TASK_TRACED also participate in group stop.

This results in the following behavior changes.

* For a single group stop, a ptracer would see at most one stop
  reported.

* A ptracee in TASK_TRACED now also participates in group stop and the
  tracer would get the notification.  However, as a ptraced task could
  be in TASK_STOPPED state or any ptrace trap could consume group
  stop, the notification may still be missing.  These will be
  addressed with further patches.

* A ptracee may start a group stop while one is still in progress if
  the tracer let it continue with stop signal delivery.  Group stop
  code handles this correctly.

Oleg:

* Spotted that a task might skip signal check even when its
  GROUP_STOP_PENDING is set.  Fixed by updating
  recalc_sigpending_tsk() to check GROUP_STOP_PENDING instead of
  group_stop_count.

* Pointed out that task->group_stop should be cleared whenever
  task->signal->group_stop_count is cleared.  Fixed accordingly.

* Pointed out the behavior inconsistency between TASK_TRACED and
  RUNNING and the last behavior change.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Roland McGrath <roland@redhat.com>
---
 fs/exec.c             |    1 +
 include/linux/sched.h |    3 +++
 kernel/signal.c       |   36 +++++++++++++++++++++---------------
 3 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index c62efcb..0928da8 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1653,6 +1653,7 @@ static int zap_process(struct task_struct *start, int exit_code)
 
 	t = start;
 	do {
+		task_clear_group_stop_pending(t);
 		if (t != current && t->mm) {
 			sigaddset(&t->pending.signal, SIGKILL);
 			signal_wake_up(t, 1);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 58df43d..0fc6c5e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1776,8 +1776,11 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *
 /*
  * task->group_stop flags
  */
+#define GROUP_STOP_PENDING	(1 << 16) /* task should stop for group stop */
 #define GROUP_STOP_CONSUME	(1 << 17) /* consume group stop count */
 
+extern void task_clear_group_stop_pending(struct task_struct *task);
+
 #ifdef CONFIG_PREEMPT_RCU
 
 #define RCU_READ_UNLOCK_BLOCKED (1 << 0) /* blocked while in RCU read-side. */
diff --git a/kernel/signal.c b/kernel/signal.c
index 238eeba..7527778 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -124,7 +124,7 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
 
 static int recalc_sigpending_tsk(struct task_struct *t)
 {
-	if (t->signal->group_stop_count > 0 ||
+	if ((t->group_stop & GROUP_STOP_PENDING) ||
 	    PENDING(&t->pending, &t->blocked) ||
 	    PENDING(&t->signal->shared_pending, &t->blocked)) {
 		set_tsk_thread_flag(t, TIF_SIGPENDING);
@@ -232,19 +232,19 @@ static inline void print_dropped_signal(int sig)
  * CONTEXT:
  * Must be called with @task->sighand->siglock held.
  */
-static void task_clear_group_stop_pending(struct task_struct *task)
+void task_clear_group_stop_pending(struct task_struct *task)
 {
-	task->group_stop &= ~GROUP_STOP_CONSUME;
+	task->group_stop &= ~(GROUP_STOP_PENDING | GROUP_STOP_CONSUME);
 }
 
 /**
  * task_participate_group_stop - participate in a group stop
  * @task: task participating in a group stop
  *
- * @task is participating in a group stop.  Group stop states are cleared
- * and the group stop count is consumed if %GROUP_STOP_CONSUME was set.  If
- * the consumption completes the group stop, the appropriate %SIGNAL_*
- * flags are set.
+ * @task has GROUP_STOP_PENDING set and is participating in a group stop.
+ * Group stop states are cleared and the group stop count is consumed if
+ * %GROUP_STOP_CONSUME was set.  If the consumption completes the group
+ * stop, the appropriate %SIGNAL_* flags are set.
  *
  * CONTEXT:
  * Must be called with @task->sighand->siglock held.
@@ -254,6 +254,8 @@ static bool task_participate_group_stop(struct task_struct *task)
 	struct signal_struct *sig = task->signal;
 	bool consume = task->group_stop & GROUP_STOP_CONSUME;
 
+	WARN_ON_ONCE(!(task->group_stop & GROUP_STOP_PENDING));
+
 	task_clear_group_stop_pending(task);
 
 	if (!consume)
@@ -765,6 +767,9 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns)
 		t = p;
 		do {
 			unsigned int state;
+
+			task_clear_group_stop_pending(t);
+
 			rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
 			/*
 			 * If there is a handler for SIGCONT, we must make
@@ -906,6 +911,7 @@ static void complete_signal(int sig, struct task_struct *p, int group)
 			signal->group_stop_count = 0;
 			t = p;
 			do {
+				task_clear_group_stop_pending(t);
 				sigaddset(&t->pending.signal, SIGKILL);
 				signal_wake_up(t, 1);
 			} while_each_thread(p, t);
@@ -1139,6 +1145,7 @@ int zap_other_threads(struct task_struct *p)
 	p->signal->group_stop_count = 0;
 
 	while_each_thread(p, t) {
+		task_clear_group_stop_pending(t);
 		count++;
 
 		/* Don't bother with already dead threads */
@@ -1690,7 +1697,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
 	 * If there is a group stop in progress,
 	 * we must participate in the bookkeeping.
 	 */
-	if (current->signal->group_stop_count > 0)
+	if (current->group_stop & GROUP_STOP_PENDING)
 		task_participate_group_stop(current);
 
 	current->last_siginfo = info;
@@ -1775,8 +1782,8 @@ static int do_signal_stop(int signr)
 	struct signal_struct *sig = current->signal;
 	int notify = 0;
 
-	if (!sig->group_stop_count) {
-		unsigned int gstop = GROUP_STOP_CONSUME;
+	if (!(current->group_stop & GROUP_STOP_PENDING)) {
+		unsigned int gstop = GROUP_STOP_PENDING | GROUP_STOP_CONSUME;
 		struct task_struct *t;
 
 		if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) ||
@@ -1796,8 +1803,7 @@ static int do_signal_stop(int signr)
 			 * stop is always done with the siglock held,
 			 * so this check has no races.
 			 */
-			if (!(t->flags & PF_EXITING) &&
-			    !task_is_stopped_or_traced(t)) {
+			if (!(t->flags & PF_EXITING) && !task_is_stopped(t)) {
 				t->group_stop = gstop;
 				sig->group_stop_count++;
 				signal_wake_up(t, 0);
@@ -1926,8 +1932,8 @@ relock:
 		if (unlikely(signr != 0))
 			ka = return_ka;
 		else {
-			if (unlikely(signal->group_stop_count > 0) &&
-			    do_signal_stop(0))
+			if (unlikely(current->group_stop &
+				     GROUP_STOP_PENDING) && do_signal_stop(0))
 				goto relock;
 
 			signr = dequeue_signal(current, &current->blocked,
@@ -2073,7 +2079,7 @@ void exit_signals(struct task_struct *tsk)
 		if (!signal_pending(t) && !(t->flags & PF_EXITING))
 			recalc_sigpending_and_wake(t);
 
-	if (unlikely(tsk->signal->group_stop_count) &&
+	if (unlikely(tsk->group_stop & GROUP_STOP_PENDING) &&
 	    task_participate_group_stop(tsk))
 		group_stop = CLD_STOPPED;
 out:
-- 
1.7.1


  parent reply	other threads:[~2011-01-28 15:09 UTC|newest]

Thread overview: 161+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-28 15:08 [PATCHSET] ptrace,signal: group stop / ptrace updates Tejun Heo
2011-01-28 15:08 ` [PATCH 01/10] signal: fix SIGCONT notification code Tejun Heo
2011-01-28 15:08 ` [PATCH 02/10] ptrace: remove the extra wake_up_process() from ptrace_detach() Tejun Heo
2011-01-28 18:46   ` Roland McGrath
2011-01-31 10:38     ` Tejun Heo
2011-02-01 10:26       ` [PATCH] ptrace: use safer wake up on ptrace_detach() Tejun Heo
2011-02-01 13:40         ` Oleg Nesterov
2011-02-01 15:07           ` Tejun Heo
2011-02-01 19:17             ` Oleg Nesterov
2011-02-02  5:31             ` Roland McGrath
2011-02-02 10:35               ` Tejun Heo
2011-02-02  0:27         ` Andrew Morton
2011-02-02  5:33           ` Roland McGrath
2011-02-02  5:38             ` Andrew Morton
2011-02-02 10:34               ` Tejun Heo
2011-02-02 19:33                 ` Andrew Morton
2011-02-02 20:01                   ` Tejun Heo
2011-02-02 21:40             ` Oleg Nesterov
2011-02-02  5:29         ` Roland McGrath
2011-02-02  5:28       ` [PATCH 02/10] ptrace: remove the extra wake_up_process() from ptrace_detach() Roland McGrath
2011-01-28 15:08 ` [PATCH 03/10] signal: remove superflous try_to_freeze() loop in do_signal_stop() Tejun Heo
2011-01-28 18:46   ` Roland McGrath
2011-01-28 15:08 ` [PATCH 04/10] ptrace: kill tracehook_notify_jctl() Tejun Heo
2011-01-28 21:09   ` Roland McGrath
2011-01-28 15:08 ` [PATCH 05/10] ptrace: add @why to ptrace_stop() Tejun Heo
2011-01-28 18:48   ` Roland McGrath
2011-01-28 15:08 ` [PATCH 06/10] signal: fix premature completion of group stop when interfered by ptrace Tejun Heo
2011-01-28 21:22   ` Roland McGrath
2011-01-31 11:00     ` Tejun Heo
2011-02-02  5:44       ` Roland McGrath
2011-02-02 10:56         ` Tejun Heo
2011-01-28 15:08 ` Tejun Heo [this message]
2011-01-28 15:08 ` [PATCH 08/10] ptrace: participate in group stop from ptrace_stop() iff the task is trapping for group stop Tejun Heo
2011-01-28 21:30   ` Roland McGrath
2011-01-31 11:26     ` Tejun Heo
2011-02-02  5:57       ` Roland McGrath
2011-02-02 10:53         ` Tejun Heo
2011-02-03 10:02           ` Tejun Heo
2011-02-01 19:36     ` Oleg Nesterov
2011-01-28 15:08 ` [PATCH 09/10] ptrace: make do_signal_stop() use ptrace_stop() if the task is being ptraced Tejun Heo
2011-01-28 15:08 ` [PATCH 10/10] ptrace: clean transitions between TASK_STOPPED and TRACED Tejun Heo
2011-02-03 20:41   ` [PATCH 0/1] (Was: ptrace: clean transitions between TASK_STOPPED and TRACED) Oleg Nesterov
2011-02-03 20:41     ` [PATCH 1/1] ptrace: make sure do_wait() won't hang after PTRACE_ATTACH Oleg Nesterov
2011-02-03 21:36       ` Roland McGrath
2011-02-03 21:44         ` Oleg Nesterov
2011-02-04 10:53           ` Tejun Heo
2011-02-04 13:04             ` Oleg Nesterov
2011-02-04 14:48               ` Tejun Heo
2011-02-04 17:06                 ` Oleg Nesterov
2011-02-05 13:39                   ` Tejun Heo
2011-02-07 13:42                     ` Oleg Nesterov
2011-02-07 14:11                       ` Tejun Heo
2011-02-07 15:37                         ` Oleg Nesterov
2011-02-07 16:31                           ` Tejun Heo
2011-02-07 17:48                             ` Oleg Nesterov
2011-02-09 14:18                               ` Tejun Heo
2011-02-09 14:21                                 ` Tejun Heo
2011-02-09 21:25                                 ` Oleg Nesterov
2011-02-13 23:01                                   ` Denys Vlasenko
2011-02-14  9:03                                     ` Jan Kratochvil
2011-02-14 11:39                                       ` Denys Vlasenko
2011-02-14 17:32                                         ` Oleg Nesterov
2011-02-14 16:01                                       ` Oleg Nesterov
2011-02-26  3:59                                       ` Pavel Machek
2011-02-14 15:51                                     ` Oleg Nesterov
2011-02-14 14:50                                   ` Tejun Heo
2011-02-14 18:53                                     ` Oleg Nesterov
2011-02-13 22:25                                 ` Denys Vlasenko
2011-02-14 15:13                                   ` Tejun Heo
2011-02-14 16:15                                     ` Oleg Nesterov
2011-02-14 16:33                                       ` Tejun Heo
2011-02-14 17:23                                         ` Oleg Nesterov
2011-02-14 17:20                                     ` Denys Vlasenko
2011-02-14 17:30                                       ` Tejun Heo
2011-02-14 17:45                                         ` Oleg Nesterov
2011-02-14 17:54                                         ` Denys Vlasenko
2011-02-21 15:16                                           ` Tejun Heo
2011-02-21 15:28                                             ` Oleg Nesterov
2011-02-21 16:11                                               ` [pseudo patch] ptrace should respect the group stop Oleg Nesterov
2011-02-22 16:24                                               ` [PATCH 1/1] ptrace: make sure do_wait() won't hang after PTRACE_ATTACH Tejun Heo
2011-02-24 21:08                                                 ` Oleg Nesterov
2011-02-25 15:45                                                   ` Tejun Heo
2011-02-25 17:42                                                     ` Roland McGrath
2011-02-28 15:23                                                     ` Oleg Nesterov
2011-02-14 17:51                                       ` Oleg Nesterov
2011-02-14 18:55                                         ` Denys Vlasenko
2011-02-14 19:01                                           ` Oleg Nesterov
2011-02-14 19:42                                             ` Denys Vlasenko
2011-02-14 20:01                                               ` Oleg Nesterov
2011-02-15 15:24                                                 ` Tejun Heo
2011-02-15 15:58                                                   ` Oleg Nesterov
2011-02-15 17:31                                                   ` Roland McGrath
2011-02-15 20:27                                                     ` Oleg Nesterov
2011-02-18 17:02                                                       ` Tejun Heo
2011-02-18 19:37                                                         ` Oleg Nesterov
2011-02-21 16:22                                                           ` Tejun Heo
2011-02-21 16:49                                                             ` Oleg Nesterov
2011-02-21 16:59                                                               ` Tejun Heo
2011-02-23 19:31                                                                 ` Oleg Nesterov
2011-02-25 15:10                                                                   ` Tejun Heo
2011-02-24 20:29                                                             ` Oleg Nesterov
2011-02-25 15:51                                                               ` Tejun Heo
2011-02-26  2:48                                                                 ` Denys Vlasenko
2011-02-28 12:56                                                                   ` Tejun Heo
2011-02-28 13:16                                                                     ` Denys Vlasenko
2011-02-28 13:29                                                                       ` Tejun Heo
2011-02-28 13:41                                                                         ` Denys Vlasenko
2011-02-28 13:53                                                                           ` Tejun Heo
2011-02-28 14:25                                                                             ` Denys Vlasenko
2011-02-28 14:39                                                                               ` Tejun Heo
2011-02-28 16:48                                                                                 ` Oleg Nesterov
2011-02-28 14:36                                                                   ` Oleg Nesterov
2011-02-16 21:51                                       ` Jan Kratochvil
2011-02-17  3:37                                         ` Denys Vlasenko
2011-02-17 19:19                                           ` Oleg Nesterov
2011-02-18 21:11                                             ` Jan Kratochvil
2011-02-19 20:16                                               ` Oleg Nesterov
2011-02-17 16:49                                         ` Oleg Nesterov
2011-02-17 18:58                                           ` Roland McGrath
2011-02-17 19:33                                             ` Oleg Nesterov
2011-02-18 21:34                                           ` Jan Kratochvil
2011-02-19 20:06                                             ` Oleg Nesterov
2011-02-20  9:40                                               ` Jan Kratochvil
2011-02-20 17:06                                                 ` Denys Vlasenko
2011-02-20 17:48                                                   ` Oleg Nesterov
2011-02-20 19:10                                                   ` Jan Kratochvil
2011-02-20 19:16                                                     ` Oleg Nesterov
2011-02-20 17:16                                                 ` Oleg Nesterov
2011-02-20 18:52                                                   ` Jan Kratochvil
2011-02-20 20:38                                                     ` Oleg Nesterov
2011-02-20 21:06                                                       ` `(T) stopped' preservation after _exit() [Re: [PATCH 1/1] ptrace: make sure do_wait() won't hang after PTRACE_ATTACH] Jan Kratochvil
2011-02-20 21:19                                                         ` Oleg Nesterov
2011-02-20 21:20                                                       ` [PATCH 1/1] ptrace: make sure do_wait() won't hang after PTRACE_ATTACH Jan Kratochvil
2011-02-21 14:23                                                         ` Oleg Nesterov
2011-02-23 16:44                                                           ` Jan Kratochvil
2011-02-14 15:31                                   ` Oleg Nesterov
2011-02-14 17:24                                     ` Denys Vlasenko
2011-02-14 17:39                                       ` Oleg Nesterov
2011-02-14 17:57                                         ` Denys Vlasenko
2011-02-14 18:00                                           ` Oleg Nesterov
2011-02-14 18:06                                             ` Oleg Nesterov
2011-02-14 18:59                                         ` Denys Vlasenko
2011-02-13 21:24                 ` Denys Vlasenko
2011-02-14 15:06                   ` Oleg Nesterov
2011-02-14 15:19                     ` Tejun Heo
2011-02-14 16:20                       ` Oleg Nesterov
2011-02-14 17:05                     ` Denys Vlasenko
2011-02-14 17:18                       ` Oleg Nesterov
2011-01-28 16:54 ` [PATCHSET] ptrace,signal: group stop / ptrace updates Ingo Molnar
2011-01-28 17:41   ` Thomas Gleixner
2011-01-28 18:04     ` Anca Emanuel
2011-01-28 18:36       ` Mathieu Desnoyers
2011-01-28 17:55   ` Oleg Nesterov
2011-01-28 18:29     ` Bash not reacting to Ctrl-C Ingo Molnar
2011-02-05 20:34       ` Oleg Nesterov
2011-02-07 13:08         ` Oleg Nesterov
2011-02-09  6:17           ` Michael Witten
2011-02-09 14:53             ` Ingo Molnar
2011-02-09 19:37               ` Michael Witten
2011-02-11 14:41           ` Pavel Machek
2011-03-05 10:36 [PATCHSET] ptrace,signal: group stop / ptrace updates, take#2 Tejun Heo
2011-03-05 10:37 ` [PATCH 07/10] signal: use GROUP_STOP_PENDING to stop once for a single group stop Tejun Heo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1296227324-25295-8-git-send-email-tj@kernel.org \
    --to=tj@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=jan.kratochvil@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg@redhat.com \
    --cc=roland@redhat.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.