X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=kernel%2Fpid_namespace.c;h=fc21c5d5fd5de7932cfd3329840ac68e0fd341af;hb=refs%2Fheads%2Ftizen-6.1.y;hp=f4f8cb0435b4557c9473d4864be13e98eac3d861;hpb=42efa5e3a8888c45c15fc5a567cd77049a2e30f1;p=platform%2Fkernel%2Flinux-starfive.git diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index f4f8cb0..fc21c5d 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -244,7 +244,24 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) set_current_state(TASK_INTERRUPTIBLE); if (pid_ns->pid_allocated == init_pids) break; + /* + * Release tasks_rcu_exit_srcu to avoid following deadlock: + * + * 1) TASK A unshare(CLONE_NEWPID) + * 2) TASK A fork() twice -> TASK B (child reaper for new ns) + * and TASK C + * 3) TASK B exits, kills TASK C, waits for TASK A to reap it + * 4) TASK A calls synchronize_rcu_tasks() + * -> synchronize_srcu(tasks_rcu_exit_srcu) + * 5) *DEADLOCK* + * + * It is considered safe to release tasks_rcu_exit_srcu here + * because we assume the current task can not be concurrently + * reaped at this point. + */ + exit_tasks_rcu_stop(); schedule(); + exit_tasks_rcu_start(); } __set_current_state(TASK_RUNNING);