)]}'
{
  "commit": "f938a5015a27aaeca7c6e31bea0344da2f396768",
  "tree": "469539cdbe09b9cda407410bc40e6bb65891cda4",
  "parents": [
    "981cd338614c96070cf9854679014fd027c1fb1d"
  ],
  "author": {
    "name": "Tejun Heo",
    "email": "tj@kernel.org",
    "time": "Thu Apr 30 16:27:33 2026 -1000"
  },
  "committer": {
    "name": "Tejun Heo",
    "email": "tj@kernel.org",
    "time": "Thu Apr 30 16:27:33 2026 -1000"
  },
  "message": "cgroup: Defer css percpu_ref kill on rmdir until cgroup is depopulated\n\nA chain of commits going back to v7.0 reworked rmdir to satisfy the\ncontroller invariant that a subsystem\u0027s -\u003ecss_offline() must not run while\ntasks are still doing kernel-side work in the cgroup.\n\n[1] d245698d727a (\"cgroup: Defer task cgroup unlink until after the task is done switching out\")\n[2] a72f73c4dd9b (\"cgroup: Don\u0027t expose dead tasks in cgroup\")\n[3] 1b164b876c36 (\"cgroup: Wait for dying tasks to leave on rmdir\")\n[4] 4c56a8ac6869 (\"cgroup: Fix cgroup_drain_dying() testing the wrong condition\")\n[5] 13e786b64bd3 (\"cgroup: Increment nr_dying_subsys_* from rmdir context\")\n\n[1] moved task cset unlink from do_exit() to finish_task_switch() so a\ntask\u0027s cset link drops only after the task has fully stopped scheduling.\nThat made tasks past exit_signals() linger on cset-\u003etasks until their final\ncontext switch, which led to a series of problems as what userspace expected\nto see after rmdir diverged from what the kernel needs to wait for. [2]-[5]\ntried to bridge that divergence: [2] filtered the exiting tasks from\ncgroup.procs; [3] had rmdir(2) sleep in TASK_UNINTERRUPTIBLE for them; [4]\nfixed the wait\u0027s condition; [5] made nr_dying_subsys_* visible\nsynchronously.\n\nThe cgroup_drain_dying() wait in [3] turned out to be a dead end. When the\nrmdir caller is also the reaper of a zombie that pins a pidns teardown (e.g.\nhost PID 1 systemd reaping orphan pids that were re-parented to it during\nthe same teardown), rmdir blocks in TASK_UNINTERRUPTIBLE waiting for those\npids to free, the pids can\u0027t free because PID 1 is the reaper and it\u0027s stuck\nin rmdir, and the system A-A deadlocks. No internal lock ordering breaks\nthis; the wait itself is the bug.\n\nThe css killing side that drove the original reorder, however, can be made\ncleanly asynchronous: -\u003ecss_offline() is already async, run from\ncss_killed_work_fn() driven by percpu_ref_kill_and_confirm(). The fix is to\nmake that chain start only after all tasks have left the cgroup. rmdir\u0027s\nuser-visible side then returns as soon as cgroup.procs and friends are\nempty, while -\u003ecss_offline() still runs only after the cgroup is fully\ndrained.\n\nVerified by the original reproducer (pidns teardown + zombie reaper, runs\nunder vng) which hangs vanilla and succeeds here, and by per-commit\ndeterministic repros for [2], [3], [4], [5] with a boot parameter that\nwidens the post-exit_signals() window so each state is reliably reachable.\nSome stress tests on top of that.\n\nThis seems like the right approach and I don\u0027t see problems with it. The\nchanges are somewhat invasive but not excessively so, so backporting to\n-stable should be okay. If something does turn out to be wrong, the fallback\nis to revert the entire chain ([1]-[5]) and rework in the development branch\ninstead.\n\nFixes: 1b164b876c36 (\"cgroup: Wait for dying tasks to leave on rmdir\")\nCc: stable@vger.kernel.org # v7.0+\nReported-by: Martin Pitt \u003cmartin@piware.de\u003e\nLink: https://lore.kernel.org/all/afHNg2VX2jy9bW7y@piware.de/\nLink: https://lore.kernel.org/all/35e0670adb4abeab13da2c321582af9f@kernel.org/\nSigned-off-by: Tejun Heo \u003ctj@kernel.org\u003e\nCc: Sebastian Andrzej Siewior \u003cbigeasy@linutronix.de\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "f42563739d2e53670da74c4948046f3c5c9a0bc9",
      "old_mode": 33188,
      "old_path": "include/linux/cgroup-defs.h",
      "new_id": "50a784da7a81aa3c826fcd7d85257c70e29ea814",
      "new_mode": 33188,
      "new_path": "include/linux/cgroup-defs.h"
    },
    {
      "type": "modify",
      "old_id": "c928dea9dea6bde8efdff09d15af36a5c4540e6a",
      "old_mode": 33188,
      "old_path": "kernel/cgroup/cgroup.c",
      "new_id": "5634bac9cb9cd3ad63dd86e851da549c91cc791e",
      "new_mode": 33188,
      "new_path": "kernel/cgroup/cgroup.c"
    }
  ]
}
