diff options
author | Tejun Heo <tj@kernel.org> | 2012-11-19 11:13:37 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2012-11-19 11:13:37 -0500 |
commit | a31f2d3ff7fe20cbe2a143515a7d7c408b29dd0d (patch) | |
tree | fd9e909ad92609eb189d406c4812325788d25bbc /kernel/cgroup.c | |
parent | 42809dd4225b2f3127a4804314a1b33608620d96 (diff) |
cgroup: introduce CSS_ONLINE flag and on/offline_css() helpers
New helpers on/offline_css() respectively wrap ->post_create() and
->pre_destroy() invocations. online_css() sets CSS_ONLINE after
->post_create() is complete and offline_css() invokes ->pre_destroy()
iff CSS_ONLINE is set and clears it while also handling the temporary
dropping of cgroup_mutex.
This patch doesn't introduce any behavior change at the moment but
will be used to improve cgroup_create() failure path and allow
->post_create() to fail.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 65 |
1 files changed, 42 insertions, 23 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 4412d9694f13..78a3d5c0968e 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -4035,6 +4035,42 @@ static void init_cgroup_css(struct cgroup_subsys_state *css, | |||
4035 | INIT_WORK(&css->dput_work, css_dput_fn); | 4035 | INIT_WORK(&css->dput_work, css_dput_fn); |
4036 | } | 4036 | } |
4037 | 4037 | ||
4038 | /* invoke ->post_create() on a new CSS and mark it online */ | ||
4039 | static void online_css(struct cgroup_subsys *ss, struct cgroup *cgrp) | ||
4040 | { | ||
4041 | lockdep_assert_held(&cgroup_mutex); | ||
4042 | |||
4043 | if (ss->post_create) | ||
4044 | ss->post_create(cgrp); | ||
4045 | cgrp->subsys[ss->subsys_id]->flags |= CSS_ONLINE; | ||
4046 | } | ||
4047 | |||
4048 | /* if the CSS is online, invoke ->pre_destory() on it and mark it offline */ | ||
4049 | static void offline_css(struct cgroup_subsys *ss, struct cgroup *cgrp) | ||
4050 | __releases(&cgroup_mutex) __acquires(&cgroup_mutex) | ||
4051 | { | ||
4052 | struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id]; | ||
4053 | |||
4054 | lockdep_assert_held(&cgroup_mutex); | ||
4055 | |||
4056 | if (!(css->flags & CSS_ONLINE)) | ||
4057 | return; | ||
4058 | |||
4059 | /* | ||
4060 | * pre_destroy() should be called with cgroup_mutex unlocked. See | ||
4061 | * 3fa59dfbc3 ("cgroup: fix potential deadlock in pre_destroy") for | ||
4062 | * details. This temporary unlocking should go away once | ||
4063 | * cgroup_mutex is unexported from controllers. | ||
4064 | */ | ||
4065 | if (ss->pre_destroy) { | ||
4066 | mutex_unlock(&cgroup_mutex); | ||
4067 | ss->pre_destroy(cgrp); | ||
4068 | mutex_lock(&cgroup_mutex); | ||
4069 | } | ||
4070 | |||
4071 | cgrp->subsys[ss->subsys_id]->flags &= ~CSS_ONLINE; | ||
4072 | } | ||
4073 | |||
4038 | /* | 4074 | /* |
4039 | * cgroup_create - create a cgroup | 4075 | * cgroup_create - create a cgroup |
4040 | * @parent: cgroup that will be parent of the new cgroup | 4076 | * @parent: cgroup that will be parent of the new cgroup |
@@ -4137,8 +4173,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4137 | dget(dentry); | 4173 | dget(dentry); |
4138 | 4174 | ||
4139 | /* creation succeeded, notify subsystems */ | 4175 | /* creation succeeded, notify subsystems */ |
4140 | if (ss->post_create) | 4176 | online_css(ss, cgrp); |
4141 | ss->post_create(cgrp); | ||
4142 | } | 4177 | } |
4143 | 4178 | ||
4144 | err = cgroup_populate_dir(cgrp, true, root->subsys_mask); | 4179 | err = cgroup_populate_dir(cgrp, true, root->subsys_mask); |
@@ -4240,18 +4275,9 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | |||
4240 | } | 4275 | } |
4241 | set_bit(CGRP_REMOVED, &cgrp->flags); | 4276 | set_bit(CGRP_REMOVED, &cgrp->flags); |
4242 | 4277 | ||
4243 | /* | 4278 | /* tell subsystems to initate destruction */ |
4244 | * Tell subsystems to initate destruction. pre_destroy() should be | ||
4245 | * called with cgroup_mutex unlocked. See 3fa59dfbc3 ("cgroup: fix | ||
4246 | * potential deadlock in pre_destroy") for details. This temporary | ||
4247 | * unlocking should go away once cgroup_mutex is unexported from | ||
4248 | * controllers. | ||
4249 | */ | ||
4250 | mutex_unlock(&cgroup_mutex); | ||
4251 | for_each_subsys(cgrp->root, ss) | 4279 | for_each_subsys(cgrp->root, ss) |
4252 | if (ss->pre_destroy) | 4280 | offline_css(ss, cgrp); |
4253 | ss->pre_destroy(cgrp); | ||
4254 | mutex_lock(&cgroup_mutex); | ||
4255 | 4281 | ||
4256 | /* | 4282 | /* |
4257 | * Put all the base refs. Each css holds an extra reference to the | 4283 | * Put all the base refs. Each css holds an extra reference to the |
@@ -4354,9 +4380,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss) | |||
4354 | BUG_ON(!list_empty(&init_task.tasks)); | 4380 | BUG_ON(!list_empty(&init_task.tasks)); |
4355 | 4381 | ||
4356 | ss->active = 1; | 4382 | ss->active = 1; |
4357 | 4383 | online_css(ss, dummytop); | |
4358 | if (ss->post_create) | ||
4359 | ss->post_create(dummytop); | ||
4360 | 4384 | ||
4361 | mutex_unlock(&cgroup_mutex); | 4385 | mutex_unlock(&cgroup_mutex); |
4362 | 4386 | ||
@@ -4469,9 +4493,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss) | |||
4469 | write_unlock(&css_set_lock); | 4493 | write_unlock(&css_set_lock); |
4470 | 4494 | ||
4471 | ss->active = 1; | 4495 | ss->active = 1; |
4472 | 4496 | online_css(ss, dummytop); | |
4473 | if (ss->post_create) | ||
4474 | ss->post_create(dummytop); | ||
4475 | 4497 | ||
4476 | /* success! */ | 4498 | /* success! */ |
4477 | mutex_unlock(&cgroup_mutex); | 4499 | mutex_unlock(&cgroup_mutex); |
@@ -4501,12 +4523,9 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss) | |||
4501 | */ | 4523 | */ |
4502 | BUG_ON(ss->root != &rootnode); | 4524 | BUG_ON(ss->root != &rootnode); |
4503 | 4525 | ||
4504 | /* ->pre_destroy() should be called outside cgroup_mutex for now */ | ||
4505 | if (ss->pre_destroy) | ||
4506 | ss->pre_destroy(dummytop); | ||
4507 | |||
4508 | mutex_lock(&cgroup_mutex); | 4526 | mutex_lock(&cgroup_mutex); |
4509 | 4527 | ||
4528 | offline_css(ss, dummytop); | ||
4510 | ss->active = 0; | 4529 | ss->active = 0; |
4511 | 4530 | ||
4512 | if (ss->use_id) { | 4531 | if (ss->use_id) { |