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 | |
parent | 0d80255e42b54419cfc6b10a3ec74b60fe04b8d7 (diff) |
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>
-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) | |||
4084 | static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | 4084 | static long cgroup_create(struct cgroup *parent, struct dentry *dentry, |
4085 | umode_t mode) | 4085 | umode_t mode) |
4086 | { | 4086 | { |
4087 | struct cgroup_subsys_state *css_ar[CGROUP_SUBSYS_COUNT] = { }; | 4087 | struct cgroup_subsys_state *css = NULL; |
4088 | struct cgroup *cgrp; | 4088 | struct cgroup *cgrp; |
4089 | struct cgroup_name *name; | 4089 | struct cgroup_name *name; |
4090 | struct cgroupfs_root *root = parent->root; | 4090 | struct cgroupfs_root *root = parent->root; |
@@ -4173,26 +4173,20 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4173 | if (err) | 4173 | if (err) |
4174 | goto err_destroy; | 4174 | goto err_destroy; |
4175 | 4175 | ||
4176 | /* let's create and online css's */ | ||
4176 | for_each_root_subsys(root, ss) { | 4177 | for_each_root_subsys(root, ss) { |
4177 | struct cgroup_subsys_state *css; | ||
4178 | |||
4179 | css = ss->css_alloc(cgroup_css(parent, ss)); | 4178 | css = ss->css_alloc(cgroup_css(parent, ss)); |
4180 | if (IS_ERR(css)) { | 4179 | if (IS_ERR(css)) { |
4181 | err = PTR_ERR(css); | 4180 | err = PTR_ERR(css); |
4181 | css = NULL; | ||
4182 | goto err_destroy; | 4182 | goto err_destroy; |
4183 | } | 4183 | } |
4184 | css_ar[ss->subsys_id] = css; | ||
4185 | 4184 | ||
4186 | err = percpu_ref_init(&css->refcnt, css_release); | 4185 | err = percpu_ref_init(&css->refcnt, css_release); |
4187 | if (err) | 4186 | if (err) |
4188 | goto err_destroy; | 4187 | goto err_destroy; |
4189 | 4188 | ||
4190 | init_css(css, ss, cgrp); | 4189 | init_css(css, ss, cgrp); |
4191 | } | ||
4192 | |||
4193 | /* creation succeeded, notify subsystems */ | ||
4194 | for_each_root_subsys(root, ss) { | ||
4195 | struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; | ||
4196 | 4190 | ||
4197 | err = cgroup_populate_dir(cgrp, 1 << ss->subsys_id); | 4191 | err = cgroup_populate_dir(cgrp, 1 << ss->subsys_id); |
4198 | if (err) | 4192 | if (err) |
@@ -4202,12 +4196,11 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4202 | if (err) | 4196 | if (err) |
4203 | goto err_destroy; | 4197 | goto err_destroy; |
4204 | 4198 | ||
4205 | /* each css holds a ref to the cgroup's dentry and parent css */ | ||
4206 | dget(dentry); | 4199 | dget(dentry); |
4207 | css_get(css->parent); | 4200 | css_get(css->parent); |
4208 | 4201 | ||
4209 | /* mark it consumed for error path */ | 4202 | /* mark it consumed for error path */ |
4210 | css_ar[ss->subsys_id] = NULL; | 4203 | css = NULL; |
4211 | 4204 | ||
4212 | if (ss->broken_hierarchy && !ss->warned_broken_hierarchy && | 4205 | if (ss->broken_hierarchy && !ss->warned_broken_hierarchy && |
4213 | parent->parent) { | 4206 | parent->parent) { |
@@ -4237,13 +4230,9 @@ err_free_cgrp: | |||
4237 | return err; | 4230 | return err; |
4238 | 4231 | ||
4239 | err_destroy: | 4232 | err_destroy: |
4240 | for_each_root_subsys(root, ss) { | 4233 | if (css) { |
4241 | struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; | 4234 | percpu_ref_cancel_init(&css->refcnt); |
4242 | 4235 | css->ss->css_free(css); | |
4243 | if (css) { | ||
4244 | percpu_ref_cancel_init(&css->refcnt); | ||
4245 | ss->css_free(css); | ||
4246 | } | ||
4247 | } | 4236 | } |
4248 | cgroup_destroy_locked(cgrp); | 4237 | cgroup_destroy_locked(cgrp); |
4249 | mutex_unlock(&cgroup_mutex); | 4238 | mutex_unlock(&cgroup_mutex); |