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.

Tested-by: Michal Schmidt <[email protected]>
Signed-off-by: Oleg Nesterov <[email protected]>
---
 kernel/exit.c |   17 +++++++----------
 1 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/kernel/exit.c b/kernel/exit.c
index c702824..aaad08d 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1042,7 +1042,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;
        /*
@@ -1142,18 +1142,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);
        }
-- 
1.5.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to