From ba552461e389361a0efeaa963bd84a20719234bd Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 8 Feb 2008 04:19:06 -0800 Subject: [PATCH] --- yaml --- r: 84655 b: refs/heads/master c: f2cc3eb133baa2e9dc8efd40f417106b2ee520f3 h: refs/heads/master i: 84653: b49faafc79dda3e3ff490931b3088165c1738dae 84651: 959df5d6cedf1c02ad35b2a84343aa282b98329c 84647: 9bf711bfb469185a3a9588390e0182cfa329b84d 84639: 7d3a65a050f27ea90180b4ac587aeec6f117e9ae v: v3 --- [refs] | 2 +- trunk/kernel/exit.c | 39 ++++++++++++++++++--------------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/[refs] b/[refs] index 6daf470068f7..5d6986842520 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 96fabbf55ae79826f2e8a86f4066d7e8834315ae +refs/heads/master: f2cc3eb133baa2e9dc8efd40f417106b2ee520f3 diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 9ee229ea97e4..ee607720ae58 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -1142,10 +1142,14 @@ static int eligible_child(pid_t pid, int options, struct task_struct *p) return 0; err = security_task_wait(p); - if (err) - return err; + if (likely(!err)) + return 1; - return 1; + if (pid <= 0) + return 0; + /* This child was explicitly requested, abort */ + read_unlock(&tasklist_lock); + return err; } static int wait_noreap_copyout(struct task_struct *p, pid_t pid, uid_t uid, @@ -1476,7 +1480,6 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop, DECLARE_WAITQUEUE(wait, current); struct task_struct *tsk; int flag, retval; - int allowed, denied; add_wait_queue(¤t->signal->wait_chldexit,&wait); repeat: @@ -1484,8 +1487,7 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop, * We will set this flag if we see any child that might later * match our criteria, even if we are not able to reap it yet. */ - flag = 0; - allowed = denied = 0; + flag = retval = 0; current->state = TASK_INTERRUPTIBLE; read_lock(&tasklist_lock); tsk = current; @@ -1498,13 +1500,8 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop, continue; if (unlikely(ret < 0)) { - denied = ret; - continue; - } - allowed = 1; - - retval = 0; - if (task_is_stopped_or_traced(p)) { + retval = ret; + } else if (task_is_stopped_or_traced(p)) { /* * It's stopped now, so it might later * continue, exit, or stop again. @@ -1544,11 +1541,14 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop, } if (!flag) { list_for_each_entry(p, &tsk->ptrace_children, - ptrace_list) { - if (!eligible_child(pid, options, p)) + ptrace_list) { + flag = eligible_child(pid, options, p); + if (!flag) continue; - flag = 1; - break; + if (likely(flag > 0)) + break; + retval = flag; + goto end; } } if (options & __WNOTHREAD) @@ -1556,10 +1556,9 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop, tsk = next_thread(tsk); BUG_ON(tsk->signal != current->signal); } while (tsk != current); - read_unlock(&tasklist_lock); + if (flag) { - retval = 0; if (options & WNOHANG) goto end; retval = -ERESTARTSYS; @@ -1569,8 +1568,6 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop, goto repeat; } retval = -ECHILD; - if (unlikely(denied) && !allowed) - retval = denied; end: current->state = TASK_RUNNING; remove_wait_queue(¤t->signal->wait_chldexit,&wait);