return ret;
 }
 
+/* Returns nonzero if the tracee should be released. */
+int __ptrace_detach(struct task_struct *tracer, struct task_struct *p)
+{
+       __ptrace_unlink(p);
+
+       if (p->exit_state != EXIT_ZOMBIE)
+               return 0;
+       /*
+        * If it's a zombie, our attachedness prevented normal
+        * parent notification or self-reaping.  Do notification
+        * now if it would have happened earlier.  If it should
+        * reap itself we return true.
+        *
+        * If it's our own child, there is no notification to do.
+        * But if our normal children self-reap, then this child
+        * was prevented by ptrace and we must reap it now.
+        */
+       if (!task_detached(p) && thread_group_empty(p)) {
+               if (!same_thread_group(p->real_parent, tracer))
+                       do_notify_parent(p, p->exit_signal);
+               else if (ignoring_children(tracer->sighand))
+                       p->exit_signal = -1;
+       }
+
+       if (!task_detached(p))
+               return 0;
+
+       /* Mark it as in the process of being reaped. */
+       p->exit_state = EXIT_DEAD;
+       return 1;
+}
+
 /*
  * Detach all tasks we were using ptrace on.
  * Any that need to be release_task'd are put on the @dead list.
        struct task_struct *p, *n;
 
        list_for_each_entry_safe(p, n, &parent->ptraced, ptrace_entry) {
-               __ptrace_unlink(p);
-
-               if (p->exit_state != EXIT_ZOMBIE)
-                       continue;
-
-               /*
-                * If it's a zombie, our attachedness prevented normal
-                * parent notification or self-reaping.  Do notification
-                * now if it would have happened earlier.  If it should
-                * reap itself, add it to the @dead list.  We can't call
-                * release_task() here because we already hold tasklist_lock.
-                *
-                * If it's our own child, there is no notification to do.
-                * But if our normal children self-reap, then this child
-                * was prevented by ptrace and we must reap it now.
-                */
-               if (!task_detached(p) && thread_group_empty(p)) {
-                       if (!same_thread_group(p->real_parent, parent))
-                               do_notify_parent(p, p->exit_signal);
-                       else if (ignoring_children(parent->sighand))
-                               p->exit_signal = -1;
-               }
-
-               if (task_detached(p)) {
-                       /*
-                        * Mark it as in the process of being reaped.
-                        */
-                       p->exit_state = EXIT_DEAD;
+               if (__ptrace_detach(parent, p))
                        list_add(&p->ptrace_entry, dead);
-               }
        }
 }