Skip to content

Commit ae7f164

Browse files
committed
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 <[email protected]> Acked-by: Li Zefan <[email protected]>
1 parent 623f926 commit ae7f164

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

kernel/cgroup.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4321,7 +4321,6 @@ static void init_css(struct cgroup_subsys_state *css, struct cgroup_subsys *ss,
43214321
css->flags |= CSS_ROOT;
43224322

43234323
BUG_ON(cgroup_css(cgrp, ss->subsys_id));
4324-
rcu_assign_pointer(cgrp->subsys[ss->subsys_id], css);
43254324
}
43264325

43274326
/* 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)
43344333

43354334
if (ss->css_online)
43364335
ret = ss->css_online(css);
4337-
if (!ret)
4336+
if (!ret) {
43384337
css->flags |= CSS_ONLINE;
4338+
rcu_assign_pointer(css->cgroup->subsys[ss->subsys_id], css);
4339+
}
43394340
return ret;
43404341
}
43414342

@@ -4366,6 +4367,7 @@ static void offline_css(struct cgroup_subsys_state *css)
43664367
static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
43674368
umode_t mode)
43684369
{
4370+
struct cgroup_subsys_state *css_ar[CGROUP_SUBSYS_COUNT] = { };
43694371
struct cgroup *cgrp;
43704372
struct cgroup_name *name;
43714373
struct cgroupfs_root *root = parent->root;
@@ -4433,12 +4435,11 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
44334435
err = PTR_ERR(css);
44344436
goto err_free_all;
44354437
}
4438+
css_ar[ss->subsys_id] = css;
44364439

44374440
err = percpu_ref_init(&css->refcnt, css_release);
4438-
if (err) {
4439-
ss->css_free(css);
4441+
if (err)
44404442
goto err_free_all;
4441-
}
44424443

44434444
init_css(css, ss, cgrp);
44444445

@@ -4467,7 +4468,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
44674468

44684469
/* each css holds a ref to the cgroup's dentry and the parent css */
44694470
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];
44714472

44724473
dget(dentry);
44734474
percpu_ref_get(&css->parent->refcnt);
@@ -4478,7 +4479,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
44784479

44794480
/* creation succeeded, notify subsystems */
44804481
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];
44824483

44834484
err = online_css(css);
44844485
if (err)
@@ -4511,7 +4512,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
45114512

45124513
err_free_all:
45134514
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];
45154516

45164517
if (css) {
45174518
percpu_ref_cancel_init(&css->refcnt);
@@ -4793,7 +4794,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
47934794
* need to invoke fork callbacks here. */
47944795
BUG_ON(!list_empty(&init_task.tasks));
47954796

4796-
BUG_ON(online_css(cgroup_css(cgroup_dummy_top, ss->subsys_id)));
4797+
BUG_ON(online_css(css));
47974798

47984799
mutex_unlock(&cgroup_mutex);
47994800

@@ -4897,7 +4898,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
48974898
}
48984899
write_unlock(&css_set_lock);
48994900

4900-
ret = online_css(cgroup_css(cgroup_dummy_top, ss->subsys_id));
4901+
ret = online_css(css);
49014902
if (ret)
49024903
goto err_unload;
49034904

0 commit comments

Comments
 (0)