The patch titled reparent/untrace: do nothing if no childs/tracees has been removed from the -mm tree. Its filename was reparent-untrace-do-nothing-if-no-childs-tracees.patch This patch was dropped because an updated version will be merged The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/ ------------------------------------------------------ Subject: reparent/untrace: do nothing if no childs/tracees From: Oleg Nesterov <oleg@xxxxxxxxxx> forget_original_parent() and exit_ptrace() can avoid taking the global tasklist_lock if there are no childs/tracees. But I failed to invent the comment to explain why/when this is safe to do, that is why the separate patch/changelog. The problem is, we can race with the concurrent release_task() which can remove the last child form our ->children/ptraced list. This means that list_empty() can return the "false" positive, it is possible that release_task() is still in progress, it can use the caller's task_struct somehow, and it is even possible that list_del(sibling/ptrace_entry) has not yet completed. But this is fine, before our task_struct will be released we will take tasklist_lock at least once in release_task(), this will synchronize us with the possible release_task/ptrace_unlink in flight. However, forget_original_parent() has another problem. We can race with another thread which has already picked us for reparenting before we set PF_EXITING, so this patch also checks thread_group_empty(). It is possible to be more clever, we can take tasklist for reading, or ensure that ->thread_group.prev is not PF_EXITING, but this is nasty. Perhaps even this optimization is too ugly. Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx> Cc: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx> Cc: "Metzger, Markus T" <markus.t.metzger@xxxxxxxxx> Cc: Roland McGrath <roland@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- kernel/exit.c | 10 ++++++++++ kernel/ptrace.c | 3 +++ 2 files changed, 13 insertions(+) diff -puN kernel/exit.c~reparent-untrace-do-nothing-if-no-childs-tracees kernel/exit.c --- a/kernel/exit.c~reparent-untrace-do-nothing-if-no-childs-tracees +++ a/kernel/exit.c @@ -806,6 +806,16 @@ static void forget_original_parent(struc struct task_struct *p, *n, *reaper; LIST_HEAD(dead_children); + if (thread_group_empty(father)) { + /* + * Make sure no other thread can reparent to + * us after the list_empty(->children) check. + */ + smp_rmb(); + if (list_empty(&father->children)) + return; + } + write_lock_irq(&tasklist_lock); reaper = find_new_reaper(father); diff -puN kernel/ptrace.c~reparent-untrace-do-nothing-if-no-childs-tracees kernel/ptrace.c --- a/kernel/ptrace.c~reparent-untrace-do-nothing-if-no-childs-tracees +++ a/kernel/ptrace.c @@ -323,6 +323,9 @@ void exit_ptrace(struct task_struct *tra struct task_struct *p, *n; LIST_HEAD(ptrace_dead); + if (list_empty(&tracer->ptraced)) + return; + write_lock_irq(&tasklist_lock); list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) { if (__ptrace_detach(tracer, p)) _ Patches currently in -mm which might be from oleg@xxxxxxxxxx are origin.patch linux-next.patch pipe_rdwr_fasync-fix-the-error-handling-to-prevent-the-leak-crash.patch get_mm_hiwater_xxx-trivial-s-define-inline.patch getrusage-fill-ru_maxrss-value.patch do_wait-fix-waiting-for-the-group-stop-with-the-dead-leader.patch signals-remove-handler-parameter-to-tracehook-functions.patch signals-protect-init-from-unwanted-signals-more.patch ptrace-kill-__ptrace_detach-fix-exit_state-check.patch ptrace-simplify-ptrace_exit-ignoring_children-path.patch ptrace-simplify-ptrace_exit-ignoring_children-pathpatch-fix.patch ptrace-reintroduce-__ptrace_detach-as-a-callee-of-ptrace_exit.patch ptrace-reintroduce-__ptrace_detach-as-a-callee-of-ptrace_exit-fix.patch ptrace-fix-possible-zombie-leak-on-ptrace_detach.patch reparent_thread-dont-call-kill_orphaned_pgrp-if-task_detached.patch reparent_thread-fix-the-is-it-traced-check.patch reparent_thread-fix-a-zombie-leak-if-sbin-init-ignores-sigchld.patch forget_original_parent-split-out-the-un-ptrace-part.patch forget_original_parent-do-not-abuse-child-ptrace_entry.patch forget_original_parent-do-not-abuse-child-ptrace_entry-fix.patch reparent-untrace-do-nothing-if-no-childs-tracees.patch tracehook_notify_death-use-task_detached-helper.patch ptrace_detach-the-wrong-wakeup-breaks-the-erestartxxx-logic.patch ptrace_untrace-fix-the-signal_stop_stopped-check.patch workqueue-avoid-recursion-in-run_workqueue.patch kthreads-simplify-the-startup-synchronization.patch kthreads-rework-kthread_stop.patch kthreads-simplify-migration_thread-exit-path.patch pids-document-task_pgrp-task_session-is-not-safe-without-tasklist-rcu.patch pids-document-task_pgrp-task_session-is-not-safe-without-tasklist-rcu-fix.patch pids-improve-get_task_pid-to-fix-the-unsafe-sys_wait4-task_pgrp.patch pids-refactor-vnr-nr_ns-helpers-to-make-them-safe.patch pids-kill-now-unused-signal_struct-__pgrp-__session-and-friends.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html