diff options
author | Tejun Heo <tj@kernel.org> | 2013-12-06 15:11:56 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-12-06 15:11:56 -0500 |
commit | 9d403e99238ed6d7151a2c07db6cf8f6932ef3d5 (patch) | |
tree | dd97c3a1b82fe0f3ac66938c53af36a5b1d47ea8 /kernel/cgroup.c | |
parent | 0d80255e42b54419cfc6b10a3ec74b60fe04b8d7 (diff) | |
download | lwn-9d403e99238ed6d7151a2c07db6cf8f6932ef3d5.tar.gz lwn-9d403e99238ed6d7151a2c07db6cf8f6932ef3d5.zip |
cgroup: combine css handling loops in cgroup_create()
Now that css operations in cgroup_create() are back-to-back, there
isn't much point in allocating css's in one loop and onlining them in
another. Merge the two loops so that a css is allocated and onlined
on each iteration.
css_ar[] is no longer necessary and replaced with a single pointer.
This also simplifies the error handling path.
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.c | 25 |
1 files changed, 7 insertions, 18 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 30a2670df3cf..39e2295466ec 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -4084,7 +4084,7 @@ static void offline_css(struct cgroup_subsys_state *css) static long cgroup_create(struct cgroup *parent, struct dentry *dentry, umode_t mode) { - struct cgroup_subsys_state *css_ar[CGROUP_SUBSYS_COUNT] = { }; + struct cgroup_subsys_state *css = NULL; struct cgroup *cgrp; struct cgroup_name *name; struct cgroupfs_root *root = parent->root; @@ -4173,26 +4173,20 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, if (err) goto err_destroy; + /* let's create and online css's */ for_each_root_subsys(root, ss) { - struct cgroup_subsys_state *css; - css = ss->css_alloc(cgroup_css(parent, ss)); if (IS_ERR(css)) { err = PTR_ERR(css); + css = NULL; goto err_destroy; } - css_ar[ss->subsys_id] = css; err = percpu_ref_init(&css->refcnt, css_release); if (err) goto err_destroy; init_css(css, ss, cgrp); - } - - /* creation succeeded, notify subsystems */ - for_each_root_subsys(root, ss) { - struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; err = cgroup_populate_dir(cgrp, 1 << ss->subsys_id); if (err) @@ -4202,12 +4196,11 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, if (err) goto err_destroy; - /* each css holds a ref to the cgroup's dentry and parent css */ dget(dentry); css_get(css->parent); /* mark it consumed for error path */ - css_ar[ss->subsys_id] = NULL; + css = NULL; if (ss->broken_hierarchy && !ss->warned_broken_hierarchy && parent->parent) { @@ -4237,13 +4230,9 @@ err_free_cgrp: return err; err_destroy: - for_each_root_subsys(root, ss) { - struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; - - if (css) { - percpu_ref_cancel_init(&css->refcnt); - ss->css_free(css); - } + if (css) { + percpu_ref_cancel_init(&css->refcnt); + css->ss->css_free(css); } cgroup_destroy_locked(cgrp); mutex_unlock(&cgroup_mutex); |