aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-11-19 11:13:37 -0500
committerTejun Heo <tj@kernel.org>2012-11-19 11:13:37 -0500
commita31f2d3ff7fe20cbe2a143515a7d7c408b29dd0d (patch)
treefd9e909ad92609eb189d406c4812325788d25bbc /kernel/cgroup.c
parent42809dd4225b2f3127a4804314a1b33608620d96 (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.c65
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 */
4039static 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 */
4049static 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) {