diff options
author | Tejun Heo <tj@kernel.org> | 2013-08-13 20:22:50 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-08-13 20:22:50 -0400 |
commit | ae7f164a09408bf21ab3c82a9e80a3ff37aa9e3e (patch) | |
tree | 0259abbfa2fb842dc7b55480b297f72a0ce0f9cd | |
parent | 623f926b050e12b0f5e3a2f4d11c36e4ddd63541 (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.c | 21 |
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) | |||
4366 | static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | 4367 | static 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 | ||
4512 | err_free_all: | 4513 | err_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 | ||