aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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