diff options
author | Oleg Nesterov <oleg@tv-sign.ru> | 2008-02-08 04:19:04 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 09:22:26 -0800 |
commit | 96fabbf55ae79826f2e8a86f4066d7e8834315ae (patch) | |
tree | e4b3259a744a1e0c8fa477e3dfba02e4ea1993c8 /kernel/exit.c | |
parent | 1bad95c3bee183719e15eebffef66afc3fb3f8b0 (diff) | |
download | linux-96fabbf55ae79826f2e8a86f4066d7e8834315ae.tar.gz linux-96fabbf55ae79826f2e8a86f4066d7e8834315ae.tar.bz2 linux-96fabbf55ae79826f2e8a86f4066d7e8834315ae.zip |
do_wait: cleanup delay_group_leader() usage
eligible_child() == 2 means delay_group_leader(). With the previous patch
this only matters for EXIT_ZOMBIE task, we can move that special check to
the only place it is really needed.
Also, with this patch we don't skip security_task_wait() for the group
leaders in a non-empty thread group. I don't really understand the exact
semantics of security_task_wait(), but imho this change is a bugfix.
Also rearrange the code a bit to kill an ugly "check_continued" backdoor.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Eric Paris <eparis@redhat.com>
Cc: James Morris <jmorris@namei.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 17 |
1 files changed, 4 insertions, 13 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 190a4cdcdb4d..9ee229ea97e4 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1140,12 +1140,6 @@ static int eligible_child(pid_t pid, int options, struct task_struct *p) if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0)) && !(options & __WALL)) return 0; - /* - * Do not consider thread group leaders that are - * in a non-empty thread group: - */ - if (delay_group_leader(p)) - return 2; err = security_task_wait(p); if (err) @@ -1497,10 +1491,9 @@ repeat: tsk = current; do { struct task_struct *p; - int ret; list_for_each_entry(p, &tsk->children, sibling) { - ret = eligible_child(pid, options, p); + int ret = eligible_child(pid, options, p); if (!ret) continue; @@ -1524,19 +1517,17 @@ repeat: retval = wait_task_stopped(p, (options & WNOWAIT), infop, stat_addr, ru); - } else if (p->exit_state == EXIT_ZOMBIE) { + } else if (p->exit_state == EXIT_ZOMBIE && + !delay_group_leader(p)) { /* - * Eligible but we cannot release it yet: + * We don't reap group leaders with subthreads. */ - if (ret == 2) - goto check_continued; if (!likely(options & WEXITED)) continue; retval = wait_task_zombie(p, (options & WNOWAIT), infop, stat_addr, ru); } else if (p->exit_state != EXIT_DEAD) { -check_continued: /* * It's running now, so it might later * exit, stop, or stop and then continue. |