hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/kernel/pid_namespace.c
....@@ -251,7 +251,24 @@
251251 set_current_state(TASK_INTERRUPTIBLE);
252252 if (pid_ns->pid_allocated == init_pids)
253253 break;
254
+ /*
255
+ * Release tasks_rcu_exit_srcu to avoid following deadlock:
256
+ *
257
+ * 1) TASK A unshare(CLONE_NEWPID)
258
+ * 2) TASK A fork() twice -> TASK B (child reaper for new ns)
259
+ * and TASK C
260
+ * 3) TASK B exits, kills TASK C, waits for TASK A to reap it
261
+ * 4) TASK A calls synchronize_rcu_tasks()
262
+ * -> synchronize_srcu(tasks_rcu_exit_srcu)
263
+ * 5) *DEADLOCK*
264
+ *
265
+ * It is considered safe to release tasks_rcu_exit_srcu here
266
+ * because we assume the current task can not be concurrently
267
+ * reaped at this point.
268
+ */
269
+ exit_tasks_rcu_stop();
254270 schedule();
271
+ exit_tasks_rcu_start();
255272 }
256273 __set_current_state(TASK_RUNNING);
257274