summaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2015-10-15 22:41:53 +0200
committerTejun Heo <tj@kernel.org>2015-10-15 22:41:53 +0200
commitafcf6c8b75444382e0f9996157207ebae34a8848 (patch)
tree6b8b8ccc4a99cfc7e156765c58ab285034980995 /kernel/cgroup.c
parentcgroup: keep zombies associated with their original cgroups (diff)
downloadlinux-afcf6c8b75444382e0f9996157207ebae34a8848.tar.xz
linux-afcf6c8b75444382e0f9996157207ebae34a8848.zip
cgroup: add cgroup_subsys->free() method and use it to fix pids controller
pids controller is completely broken in that it uncharges when a task exits allowing zombies to escape resource control. With the recent updates, cgroup core now maintains cgroup association till task free and pids controller can be fixed by uncharging on free instead of exit. This patch adds cgroup_subsys->free() method and update pids controller to use it instead of ->exit() for uncharging. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Aleksa Sarai <cyphar@cyphar.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 918658497625..867384369669 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -206,6 +206,7 @@ static u64 css_serial_nr_next = 1;
*/
static unsigned long have_fork_callback __read_mostly;
static unsigned long have_exit_callback __read_mostly;
+static unsigned long have_free_callback __read_mostly;
/* Ditto for the can_fork callback. */
static unsigned long have_canfork_callback __read_mostly;
@@ -5180,6 +5181,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
have_fork_callback |= (bool)ss->fork << ss->id;
have_exit_callback |= (bool)ss->exit << ss->id;
+ have_free_callback |= (bool)ss->free << ss->id;
have_canfork_callback |= (bool)ss->can_fork << ss->id;
/* At system boot, before all subsystems have been
@@ -5637,6 +5639,11 @@ void cgroup_exit(struct task_struct *tsk)
void cgroup_free(struct task_struct *task)
{
struct css_set *cset = task_css_set(task);
+ struct cgroup_subsys *ss;
+ int ssid;
+
+ for_each_subsys_which(ss, ssid, &have_free_callback)
+ ss->free(task);
put_css_set(cset);
}