aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-12-06 15:11:56 -0500
committerTejun Heo <tj@kernel.org>2013-12-06 15:11:56 -0500
commit9d403e99238ed6d7151a2c07db6cf8f6932ef3d5 (patch)
treedd97c3a1b82fe0f3ac66938c53af36a5b1d47ea8
parent0d80255e42b54419cfc6b10a3ec74b60fe04b8d7 (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.c25
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)
4084static long cgroup_create(struct cgroup *parent, struct dentry *dentry, 4084static 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
4239err_destroy: 4232err_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);