Skip to content

Commit

Permalink
wait: use EXIT_TRACE only if thread_group_leader(zombie)
Browse files Browse the repository at this point in the history
wait_task_zombie() always uses EXIT_TRACE/ptrace_unlink() if
ptrace_reparented().  This is suboptimal and a bit confusing: we do not
need do_notify_parent(p) if !thread_group_leader(p) and in this case we
also do not need ptrace_unlink(), we can rely on ptrace_release_task().

Change wait_task_zombie() to check thread_group_leader() along with
ptrace_reparented() and simplify the final p->exit_state transition.

Signed-off-by: Oleg Nesterov <[email protected]>
Tested-by: Michal Schmidt <[email protected]>
Cc: Jan Kratochvil <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Lennart Poettering <[email protected]>
Cc: Roland McGrath <[email protected]>
Cc: Tejun Heo <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
oleg-nesterov authored and torvalds committed Apr 7, 2014
1 parent abd50b3 commit b436069
Showing 1 changed file with 7 additions and 10 deletions.
17 changes: 7 additions & 10 deletions kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
/*
* Move the task's state to DEAD/TRACE, only one thread can do this.
*/
state = traced ? EXIT_TRACE : EXIT_DEAD;
state = traced && thread_group_leader(p) ? EXIT_TRACE : EXIT_DEAD;
if (cmpxchg(&p->exit_state, EXIT_ZOMBIE, state) != EXIT_ZOMBIE)
return 0;
/*
Expand Down Expand Up @@ -1140,18 +1140,15 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
if (!retval)
retval = pid;

if (traced) {
if (state == EXIT_TRACE) {
write_lock_irq(&tasklist_lock);
/* We dropped tasklist, ptracer could die and untrace */
ptrace_unlink(p);
/*
* If this is not a sub-thread, notify the parent.
* If parent wants a zombie, don't release it now.
*/
state = EXIT_DEAD;
if (thread_group_leader(p) &&
!do_notify_parent(p, p->exit_signal))
state = EXIT_ZOMBIE;

/* If parent wants a zombie, don't release it now */
state = EXIT_ZOMBIE;
if (do_notify_parent(p, p->exit_signal))
state = EXIT_DEAD;
p->exit_state = state;
write_unlock_irq(&tasklist_lock);
}
Expand Down

0 comments on commit b436069

Please sign in to comment.