aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-08-13 20:22:50 -0400
committerTejun Heo <tj@kernel.org>2013-08-13 20:22:50 -0400
commitae7f164a09408bf21ab3c82a9e80a3ff37aa9e3e (patch)
tree0259abbfa2fb842dc7b55480b297f72a0ce0f9cd
parent623f926b050e12b0f5e3a2f4d11c36e4ddd63541 (diff)
cgroup: move cgroup->subsys[] assignment to online_css()
Currently, css (cgroup_subsys_state) lifetime is tied to that of the associated cgroup. With the planned unified hierarchy, css's will be dynamically created and destroyed within the lifetime of a cgroup. To enable such usages, css's will be individually RCU protected instead of being tied to the cgroup. In preparation, this patch moves cgroup->subsys[] assignment from init_css() to online_css(). As this means that a newly initialized css should be remembered separately and that cgroup_css() returns NULL between init and online, cgroup_create() is updated so that it stores newly created css's in a local array css_ar[] and cgroup_init/load_subsys() are updated to use local variable @css instead of using cgroup_css(). This change also slightly simplifies error path of cgroup_create(). While this patch changes when cgroup->subsys[] is initialized, this change isn't visible to subsystems or userland. v2: This patch wasn't updated accordingly after the previous "cgroup: reorganize css init / exit paths" was updated leading to missing a css_ar[] conversion in cgroup_create() and thus boot failure. Fix it. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com>
-rw-r--r--kernel/cgroup.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index a1ebc445f350..b9f736c3b36d 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4321,7 +4321,6 @@ static void init_css(struct cgroup_subsys_state *css, struct cgroup_subsys *ss,
4321 css->flags |= CSS_ROOT; 4321 css->flags |= CSS_ROOT;
4322 4322
4323 BUG_ON(cgroup_css(cgrp, ss->subsys_id)); 4323 BUG_ON(cgroup_css(cgrp, ss->subsys_id));
4324 rcu_assign_pointer(cgrp->subsys[ss->subsys_id], css);
4325} 4324}
4326 4325
4327/* invoke ->css_online() on a new CSS and mark it online if successful */ 4326/* invoke ->css_online() on a new CSS and mark it online if successful */
@@ -4334,8 +4333,10 @@ static int online_css(struct cgroup_subsys_state *css)
4334 4333
4335 if (ss->css_online) 4334 if (ss->css_online)
4336 ret = ss->css_online(css); 4335 ret = ss->css_online(css);
4337 if (!ret) 4336 if (!ret) {
4338 css->flags |= CSS_ONLINE; 4337 css->flags |= CSS_ONLINE;
4338 rcu_assign_pointer(css->cgroup->subsys[ss->subsys_id], css);
4339 }
4339 return ret; 4340 return ret;
4340} 4341}
4341 4342
@@ -4366,6 +4367,7 @@ static void offline_css(struct cgroup_subsys_state *css)
4366static long cgroup_create(struct cgroup *parent, struct dentry *dentry, 4367static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4367 umode_t mode) 4368 umode_t mode)
4368{ 4369{
4370 struct cgroup_subsys_state *css_ar[CGROUP_SUBSYS_COUNT] = { };
4369 struct cgroup *cgrp; 4371 struct cgroup *cgrp;
4370 struct cgroup_name *name; 4372 struct cgroup_name *name;
4371 struct cgroupfs_root *root = parent->root; 4373 struct cgroupfs_root *root = parent->root;
@@ -4433,12 +4435,11 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4433 err = PTR_ERR(css); 4435 err = PTR_ERR(css);
4434 goto err_free_all; 4436 goto err_free_all;
4435 } 4437 }
4438 css_ar[ss->subsys_id] = css;
4436 4439
4437 err = percpu_ref_init(&css->refcnt, css_release); 4440 err = percpu_ref_init(&css->refcnt, css_release);
4438 if (err) { 4441 if (err)
4439 ss->css_free(css);
4440 goto err_free_all; 4442 goto err_free_all;
4441 }
4442 4443
4443 init_css(css, ss, cgrp); 4444 init_css(css, ss, cgrp);
4444 4445
@@ -4467,7 +4468,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4467 4468
4468 /* each css holds a ref to the cgroup's dentry and the parent css */ 4469 /* each css holds a ref to the cgroup's dentry and the parent css */
4469 for_each_root_subsys(root, ss) { 4470 for_each_root_subsys(root, ss) {
4470 struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id); 4471 struct cgroup_subsys_state *css = css_ar[ss->subsys_id];
4471 4472
4472 dget(dentry); 4473 dget(dentry);
4473 percpu_ref_get(&css->parent->refcnt); 4474 percpu_ref_get(&css->parent->refcnt);
@@ -4478,7 +4479,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4478 4479
4479 /* creation succeeded, notify subsystems */ 4480 /* creation succeeded, notify subsystems */
4480 for_each_root_subsys(root, ss) { 4481 for_each_root_subsys(root, ss) {
4481 struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id); 4482 struct cgroup_subsys_state *css = css_ar[ss->subsys_id];
4482 4483
4483 err = online_css(css); 4484 err = online_css(css);
4484 if (err) 4485 if (err)
@@ -4511,7 +4512,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4511 4512
4512err_free_all: 4513err_free_all:
4513 for_each_root_subsys(root, ss) { 4514 for_each_root_subsys(root, ss) {
4514 struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id); 4515 struct cgroup_subsys_state *css = css_ar[ss->subsys_id];
4515 4516
4516 if (css) { 4517 if (css) {
4517 percpu_ref_cancel_init(&css->refcnt); 4518 percpu_ref_cancel_init(&css->refcnt);
@@ -4793,7 +4794,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
4793 * need to invoke fork callbacks here. */ 4794 * need to invoke fork callbacks here. */
4794 BUG_ON(!list_empty(&init_task.tasks)); 4795 BUG_ON(!list_empty(&init_task.tasks));
4795 4796
4796 BUG_ON(online_css(cgroup_css(cgroup_dummy_top, ss->subsys_id))); 4797 BUG_ON(online_css(css));
4797 4798
4798 mutex_unlock(&cgroup_mutex); 4799 mutex_unlock(&cgroup_mutex);
4799 4800
@@ -4897,7 +4898,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
4897 } 4898 }
4898 write_unlock(&css_set_lock); 4899 write_unlock(&css_set_lock);
4899 4900
4900 ret = online_css(cgroup_css(cgroup_dummy_top, ss->subsys_id)); 4901 ret = online_css(css);
4901 if (ret) 4902 if (ret)
4902 goto err_unload; 4903 goto err_unload;
4903 4904