+
+ while (unlikely(traced)) {
+ /*
+ * We are zapping a thread and the thread it ptraces.
+ * The tracee won't come out of TASK_TRACED state until
+ * its ptracer detaches. That happens when the ptracer
+ * dies, but it synchronizes with us and so won't get
+ * that far until we finish the core dump. If we're
+ * waiting for the tracee to synchronize but it stays
+ * blocked in TASK_TRACED, then we deadlock. So, for
+ * this weirdo case we have to do another round with
+ * tasklist_lock write-locked to __ptrace_unlink the
+ * children that might cause this deadlock. That will
+ * wake them up to process their pending SIGKILL.
+ *
+ * First, give everyone we just killed a chance to run
+ * so they can all get into the coredump synchronization.
+ * That should leave only the TASK_TRACED stragglers for
+ * us to wake up. If a ptracer is still running, we'll
+ * have to come around again after letting it finish.
+ */
+ yield();
+ traced = 0;
+ write_lock_irq(&tasklist_lock);
+ do_each_thread(g,p) {
+ if (mm != p->mm || p == tsk ||
+ !p->ptrace || p->parent->mm != mm)
+ continue;
+ if ((p->parent->flags & (PF_SIGNALED|PF_EXITING)) ||
+ (p->parent->state & (TASK_TRACED|TASK_STOPPED))) {
+ /*
+ * The parent is in the process of exiting
+ * itself, or else it's stopped right now.
+ * It cannot be in a ptrace call, and would
+ * have to read_lock tasklist_lock before
+ * it could start one, so we are safe here.
+ */
+ __ptrace_unlink(p);
+ } else {
+ /*
+ * Blargh! The ptracer is not dying
+ * yet, so we cannot be sure that it
+ * isn't in the middle of a ptrace call.
+ * We'll have to let it run to get into
+ * coredump_wait and come around another
+ * time to detach its tracee.
+ */
+ traced = 1;
+ }
+ } while_each_thread(g,p);
+ write_unlock_irq(&tasklist_lock);
+ }