diff options
-rw-r--r-- | include/linux/cgroup.h | 3 | ||||
-rw-r--r-- | kernel/cgroup.c | 31 | ||||
-rw-r--r-- | kernel/sched.c | 6 |
3 files changed, 22 insertions, 18 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index ce104e33cd22..38117d937332 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -474,7 +474,8 @@ struct cgroup_subsys { | |||
474 | struct cgroup *old_cgrp, struct task_struct *tsk, | 474 | struct cgroup *old_cgrp, struct task_struct *tsk, |
475 | bool threadgroup); | 475 | bool threadgroup); |
476 | void (*fork)(struct cgroup_subsys *ss, struct task_struct *task); | 476 | void (*fork)(struct cgroup_subsys *ss, struct task_struct *task); |
477 | void (*exit)(struct cgroup_subsys *ss, struct task_struct *task); | 477 | void (*exit)(struct cgroup_subsys *ss, struct cgroup *cgrp, |
478 | struct cgroup *old_cgrp, struct task_struct *task); | ||
478 | int (*populate)(struct cgroup_subsys *ss, | 479 | int (*populate)(struct cgroup_subsys *ss, |
479 | struct cgroup *cgrp); | 480 | struct cgroup *cgrp); |
480 | void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp); | 481 | void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp); |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index b24d7027b83c..f6495f33a355 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -4230,20 +4230,8 @@ void cgroup_post_fork(struct task_struct *child) | |||
4230 | */ | 4230 | */ |
4231 | void cgroup_exit(struct task_struct *tsk, int run_callbacks) | 4231 | void cgroup_exit(struct task_struct *tsk, int run_callbacks) |
4232 | { | 4232 | { |
4233 | int i; | ||
4234 | struct css_set *cg; | 4233 | struct css_set *cg; |
4235 | 4234 | int i; | |
4236 | if (run_callbacks && need_forkexit_callback) { | ||
4237 | /* | ||
4238 | * modular subsystems can't use callbacks, so no need to lock | ||
4239 | * the subsys array | ||
4240 | */ | ||
4241 | for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) { | ||
4242 | struct cgroup_subsys *ss = subsys[i]; | ||
4243 | if (ss->exit) | ||
4244 | ss->exit(ss, tsk); | ||
4245 | } | ||
4246 | } | ||
4247 | 4235 | ||
4248 | /* | 4236 | /* |
4249 | * Unlink from the css_set task list if necessary. | 4237 | * Unlink from the css_set task list if necessary. |
@@ -4261,7 +4249,24 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks) | |||
4261 | task_lock(tsk); | 4249 | task_lock(tsk); |
4262 | cg = tsk->cgroups; | 4250 | cg = tsk->cgroups; |
4263 | tsk->cgroups = &init_css_set; | 4251 | tsk->cgroups = &init_css_set; |
4252 | |||
4253 | if (run_callbacks && need_forkexit_callback) { | ||
4254 | /* | ||
4255 | * modular subsystems can't use callbacks, so no need to lock | ||
4256 | * the subsys array | ||
4257 | */ | ||
4258 | for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) { | ||
4259 | struct cgroup_subsys *ss = subsys[i]; | ||
4260 | if (ss->exit) { | ||
4261 | struct cgroup *old_cgrp = | ||
4262 | rcu_dereference_raw(cg->subsys[i])->cgroup; | ||
4263 | struct cgroup *cgrp = task_cgroup(tsk, i); | ||
4264 | ss->exit(ss, cgrp, old_cgrp, tsk); | ||
4265 | } | ||
4266 | } | ||
4267 | } | ||
4264 | task_unlock(tsk); | 4268 | task_unlock(tsk); |
4269 | |||
4265 | if (cg) | 4270 | if (cg) |
4266 | put_css_set_taskexit(cg); | 4271 | put_css_set_taskexit(cg); |
4267 | } | 4272 | } |
diff --git a/kernel/sched.c b/kernel/sched.c index e142e92f38da..79e611cd83dd 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -606,9 +606,6 @@ static inline struct task_group *task_group(struct task_struct *p) | |||
606 | struct task_group *tg; | 606 | struct task_group *tg; |
607 | struct cgroup_subsys_state *css; | 607 | struct cgroup_subsys_state *css; |
608 | 608 | ||
609 | if (p->flags & PF_EXITING) | ||
610 | return &root_task_group; | ||
611 | |||
612 | css = task_subsys_state_check(p, cpu_cgroup_subsys_id, | 609 | css = task_subsys_state_check(p, cpu_cgroup_subsys_id, |
613 | lockdep_is_held(&task_rq(p)->lock)); | 610 | lockdep_is_held(&task_rq(p)->lock)); |
614 | tg = container_of(css, struct task_group, css); | 611 | tg = container_of(css, struct task_group, css); |
@@ -8863,7 +8860,8 @@ cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, | |||
8863 | } | 8860 | } |
8864 | 8861 | ||
8865 | static void | 8862 | static void |
8866 | cpu_cgroup_exit(struct cgroup_subsys *ss, struct task_struct *task) | 8863 | cpu_cgroup_exit(struct cgroup_subsys *ss, struct cgroup *cgrp, |
8864 | struct cgroup *old_cgrp, struct task_struct *task) | ||
8867 | { | 8865 | { |
8868 | /* | 8866 | /* |
8869 | * cgroup_exit() is called in the copy_process() failure path. | 8867 | * cgroup_exit() is called in the copy_process() failure path. |