From f03449f8829a218e9518fb455d0e5305aa1784a5 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Thu, 2 Apr 2009 16:57:58 -0700 Subject: [PATCH] --- yaml --- r: 139679 b: refs/heads/master c: 90bc8d8b1a38f1ab131a2399a202e1889db95de8 h: refs/heads/master i: 139677: a0d66c63f1aa22c12209f6fc9eb99a7766a53c32 139675: 3c87c74b584b8d62b11427e1acaf7da352869989 139671: 369ba4b5fa30125bcc7a68bf7439475d5e8f8613 139663: 10a3cebea39bf5deb6e0092b2502aa85101d51e7 139647: 138eab6fee5c199db58315c9ea06863436a038a3 v: v3 --- [refs] | 2 +- trunk/kernel/exit.c | 30 ++++++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/[refs] b/[refs] index b5f041de964e..47cb8fd8f56e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6d7b2f5f9e88902b19f91d0c8a7ef58a5455f1a2 +refs/heads/master: 90bc8d8b1a38f1ab131a2399a202e1889db95de8 diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 167e1e3ad7c6..0c06b9efae3b 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -1417,6 +1417,18 @@ static int wait_task_zombie(struct task_struct *p, int options, return retval; } +static int *task_stopped_code(struct task_struct *p, bool ptrace) +{ + if (ptrace) { + if (task_is_stopped_or_traced(p)) + return &p->exit_code; + } else { + if (p->signal->flags & SIGNAL_STOP_STOPPED) + return &p->signal->group_exit_code; + } + return NULL; +} + /* * Handle sys_wait4 work for one task in state TASK_STOPPED. We hold * read_lock(&tasklist_lock) on entry. If we return zero, we still hold @@ -1427,7 +1439,7 @@ static int wait_task_stopped(int ptrace, struct task_struct *p, int options, struct siginfo __user *infop, int __user *stat_addr, struct rusage __user *ru) { - int retval, exit_code, why; + int retval, exit_code, *p_code, why; uid_t uid = 0; /* unneeded, required by compiler */ pid_t pid; @@ -1437,22 +1449,16 @@ static int wait_task_stopped(int ptrace, struct task_struct *p, exit_code = 0; spin_lock_irq(&p->sighand->siglock); - if (unlikely(!task_is_stopped_or_traced(p))) - goto unlock_sig; - - if (!ptrace && p->signal->group_stop_count > 0) - /* - * A group stop is in progress and this is the group leader. - * We won't report until all threads have stopped. - */ + p_code = task_stopped_code(p, ptrace); + if (unlikely(!p_code)) goto unlock_sig; - exit_code = p->exit_code; + exit_code = *p_code; if (!exit_code) goto unlock_sig; if (!unlikely(options & WNOWAIT)) - p->exit_code = 0; + *p_code = 0; /* don't need the RCU readlock here as we're holding a spinlock */ uid = __task_cred(p)->uid; @@ -1608,7 +1614,7 @@ static int wait_consider_task(struct task_struct *parent, int ptrace, */ *notask_error = 0; - if (task_is_stopped_or_traced(p)) + if (task_stopped_code(p, ptrace)) return wait_task_stopped(ptrace, p, options, infop, stat_addr, ru);