aboutsummaryrefslogtreecommitdiff
path: root/scripts/gdb
diff options
context:
space:
mode:
authorOleg Nesterov <[email protected]>2019-01-28 17:00:13 +0100
committerTejun Heo <[email protected]>2019-01-31 06:55:57 -0800
commit51bee5abeab2058ea5813c5615d6197a23dbf041 (patch)
tree5747f7ee7faf9589d1cf49ca690e598b222cef92 /scripts/gdb
parentaf0c9af1b3f66052c369d08be3f60fa9a9559e48 (diff)
cgroup/pids: turn cgroup_subsys->free() into cgroup_subsys->release() to fix the accounting
The only user of cgroup_subsys->free() callback is pids_cgrp_subsys which needs pids_free() to uncharge the pid. However, ->free() is called from __put_task_struct()->cgroup_free() and this is too late. Even the trivial program which does for (;;) { int pid = fork(); assert(pid >= 0); if (pid) wait(NULL); else exit(0); } can run out of limits because release_task()->call_rcu(delayed_put_task_struct) implies an RCU gp after the task/pid goes away and before the final put(). Test-case: mkdir -p /tmp/CG mount -t cgroup2 none /tmp/CG echo '+pids' > /tmp/CG/cgroup.subtree_control mkdir /tmp/CG/PID echo 2 > /tmp/CG/PID/pids.max perl -e 'while ($p = fork) { wait; } $p // die "fork failed: $!\n"' & echo $! > /tmp/CG/PID/cgroup.procs Without this patch the forking process fails soon after migration. Rename cgroup_subsys->free() to cgroup_subsys->release() and move the callsite into the new helper, cgroup_release(), called by release_task() which actually frees the pid(s). Reported-by: Herton R. Krzesinski <[email protected]> Reported-by: Jan Stancek <[email protected]> Signed-off-by: Oleg Nesterov <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
Diffstat (limited to 'scripts/gdb')
0 files changed, 0 insertions, 0 deletions