aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-03-19 10:23:53 -0400
committerTejun Heo <tj@kernel.org>2014-03-19 10:23:53 -0400
commit172a2c0685ff3bc0b7a611b308aac0694de34594 (patch)
tree3cafd39bf2053827001d9af18f62ebd2e649b8c1 /kernel
parent5d77381fd8aa631a8fda718c395da1319afb5d2d (diff)
cgroup: reorganize cgroup bootstrapping
* Fields of init_css_set and css_set_count are now set using initializer instead of programmatically from cgroup_init_early(). * init_cgroup_root() now also takes @opts and performs the optional part of initialization too. The leftover part of cgroup_root_from_opts() is collapsed into its only caller - cgroup_mount(). * Initialization of cgroup_root_count and linking of init_css_set are moved from cgroup_init_early() to to cgroup_init(). None of the early_init users depends on init_css_set being linked. * Subsystem initializations are moved after dummy hierarchy init and init_css_set linking. These changes reorganize the bootstrap logic so that the dummy hierarchy can share the usual hierarchy init path and be made more normal. These changes don't make noticeable behavior changes. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cgroup.c100
1 files changed, 49 insertions, 51 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index b604c7e0cfc6..e66b9ee5ecc1 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -338,16 +338,24 @@ struct cgrp_cset_link {
338 struct list_head cgrp_link; 338 struct list_head cgrp_link;
339}; 339};
340 340
341/* The default css_set - used by init and its children prior to any 341/*
342 * The default css_set - used by init and its children prior to any
342 * hierarchies being mounted. It contains a pointer to the root state 343 * hierarchies being mounted. It contains a pointer to the root state
343 * for each subsystem. Also used to anchor the list of css_sets. Not 344 * for each subsystem. Also used to anchor the list of css_sets. Not
344 * reference-counted, to improve performance when child cgroups 345 * reference-counted, to improve performance when child cgroups
345 * haven't been created. 346 * haven't been created.
346 */ 347 */
348static struct css_set init_css_set = {
349 .refcount = ATOMIC_INIT(1),
350 .cgrp_links = LIST_HEAD_INIT(init_css_set.cgrp_links),
351 .tasks = LIST_HEAD_INIT(init_css_set.tasks),
352 .mg_tasks = LIST_HEAD_INIT(init_css_set.mg_tasks),
353 .mg_preload_node = LIST_HEAD_INIT(init_css_set.mg_preload_node),
354 .mg_node = LIST_HEAD_INIT(init_css_set.mg_node),
355};
347 356
348static struct css_set init_css_set;
349static struct cgrp_cset_link init_cgrp_cset_link; 357static struct cgrp_cset_link init_cgrp_cset_link;
350static int css_set_count; 358static int css_set_count = 1; /* 1 for init_css_set */
351 359
352/* 360/*
353 * hash table for cgroup groups. This improves the performance to find 361 * hash table for cgroup groups. This improves the performance to find
@@ -1352,7 +1360,8 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp)
1352 cgrp->dummy_css.cgroup = cgrp; 1360 cgrp->dummy_css.cgroup = cgrp;
1353} 1361}
1354 1362
1355static void init_cgroup_root(struct cgroupfs_root *root) 1363static void init_cgroup_root(struct cgroupfs_root *root,
1364 struct cgroup_sb_opts *opts)
1356{ 1365{
1357 struct cgroup *cgrp = &root->top_cgroup; 1366 struct cgroup *cgrp = &root->top_cgroup;
1358 1367
@@ -1361,20 +1370,6 @@ static void init_cgroup_root(struct cgroupfs_root *root)
1361 cgrp->root = root; 1370 cgrp->root = root;
1362 init_cgroup_housekeeping(cgrp); 1371 init_cgroup_housekeeping(cgrp);
1363 idr_init(&root->cgroup_idr); 1372 idr_init(&root->cgroup_idr);
1364}
1365
1366static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts)
1367{
1368 struct cgroupfs_root *root;
1369
1370 if (!opts->subsys_mask && !opts->none)
1371 return ERR_PTR(-EINVAL);
1372
1373 root = kzalloc(sizeof(*root), GFP_KERNEL);
1374 if (!root)
1375 return ERR_PTR(-ENOMEM);
1376
1377 init_cgroup_root(root);
1378 1373
1379 root->flags = opts->flags; 1374 root->flags = opts->flags;
1380 if (opts->release_agent) 1375 if (opts->release_agent)
@@ -1383,7 +1378,6 @@ static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts)
1383 strcpy(root->name, opts->name); 1378 strcpy(root->name, opts->name);
1384 if (opts->cpuset_clone_children) 1379 if (opts->cpuset_clone_children)
1385 set_bit(CGRP_CPUSET_CLONE_CHILDREN, &root->top_cgroup.flags); 1380 set_bit(CGRP_CPUSET_CLONE_CHILDREN, &root->top_cgroup.flags);
1386 return root;
1387} 1381}
1388 1382
1389static int cgroup_setup_root(struct cgroupfs_root *root, unsigned long ss_mask) 1383static int cgroup_setup_root(struct cgroupfs_root *root, unsigned long ss_mask)
@@ -1548,13 +1542,24 @@ retry:
1548 goto out_unlock; 1542 goto out_unlock;
1549 } 1543 }
1550 1544
1551 /* no such thing, create a new one */ 1545 /*
1552 root = cgroup_root_from_opts(&opts); 1546 * No such thing, create a new one. name= matching without subsys
1553 if (IS_ERR(root)) { 1547 * specification is allowed for already existing hierarchies but we
1554 ret = PTR_ERR(root); 1548 * can't create new one without subsys specification.
1549 */
1550 if (!opts.subsys_mask && !opts.none) {
1551 ret = -EINVAL;
1552 goto out_unlock;
1553 }
1554
1555 root = kzalloc(sizeof(*root), GFP_KERNEL);
1556 if (!root) {
1557 ret = -ENOMEM;
1555 goto out_unlock; 1558 goto out_unlock;
1556 } 1559 }
1557 1560
1561 init_cgroup_root(root, &opts);
1562
1558 ret = cgroup_setup_root(root, opts.subsys_mask); 1563 ret = cgroup_setup_root(root, opts.subsys_mask);
1559 if (ret) 1564 if (ret)
1560 cgroup_free_root(root); 1565 cgroup_free_root(root);
@@ -4030,26 +4035,13 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
4030 */ 4035 */
4031int __init cgroup_init_early(void) 4036int __init cgroup_init_early(void)
4032{ 4037{
4038 static struct cgroup_sb_opts __initdata opts = { };
4033 struct cgroup_subsys *ss; 4039 struct cgroup_subsys *ss;
4034 int i; 4040 int i;
4035 4041
4036 atomic_set(&init_css_set.refcount, 1); 4042 init_cgroup_root(&cgroup_dummy_root, &opts);
4037 INIT_LIST_HEAD(&init_css_set.cgrp_links);
4038 INIT_LIST_HEAD(&init_css_set.tasks);
4039 INIT_LIST_HEAD(&init_css_set.mg_tasks);
4040 INIT_LIST_HEAD(&init_css_set.mg_preload_node);
4041 INIT_LIST_HEAD(&init_css_set.mg_node);
4042 INIT_HLIST_NODE(&init_css_set.hlist);
4043 css_set_count = 1;
4044 init_cgroup_root(&cgroup_dummy_root);
4045 cgroup_root_count = 1;
4046 RCU_INIT_POINTER(init_task.cgroups, &init_css_set); 4043 RCU_INIT_POINTER(init_task.cgroups, &init_css_set);
4047 4044
4048 init_cgrp_cset_link.cset = &init_css_set;
4049 init_cgrp_cset_link.cgrp = cgroup_dummy_top;
4050 list_add(&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links);
4051 list_add(&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links);
4052
4053 for_each_subsys(ss, i) { 4045 for_each_subsys(ss, i) {
4054 WARN(!ss->css_alloc || !ss->css_free || ss->name || ss->id, 4046 WARN(!ss->css_alloc || !ss->css_free || ss->name || ss->id,
4055 "invalid cgroup_subsys %d:%s css_alloc=%p css_free=%p name:id=%d:%s\n", 4047 "invalid cgroup_subsys %d:%s css_alloc=%p css_free=%p name:id=%d:%s\n",
@@ -4077,22 +4069,10 @@ int __init cgroup_init(void)
4077{ 4069{
4078 struct cgroup_subsys *ss; 4070 struct cgroup_subsys *ss;
4079 unsigned long key; 4071 unsigned long key;
4080 int i, err; 4072 int ssid, err;
4081 4073
4082 BUG_ON(cgroup_init_cftypes(NULL, cgroup_base_files)); 4074 BUG_ON(cgroup_init_cftypes(NULL, cgroup_base_files));
4083 4075
4084 for_each_subsys(ss, i) {
4085 if (!ss->early_init)
4086 cgroup_init_subsys(ss);
4087
4088 /*
4089 * cftype registration needs kmalloc and can't be done
4090 * during early_init. Register base cftypes separately.
4091 */
4092 if (ss->base_cftypes)
4093 WARN_ON(cgroup_add_cftypes(ss, ss->base_cftypes));
4094 }
4095
4096 /* allocate id for the dummy hierarchy */ 4076 /* allocate id for the dummy hierarchy */
4097 mutex_lock(&cgroup_mutex); 4077 mutex_lock(&cgroup_mutex);
4098 4078
@@ -4106,8 +4086,26 @@ int __init cgroup_init(void)
4106 0, 1, GFP_KERNEL); 4086 0, 1, GFP_KERNEL);
4107 BUG_ON(err < 0); 4087 BUG_ON(err < 0);
4108 4088
4089 cgroup_root_count = 1;
4090 init_cgrp_cset_link.cset = &init_css_set;
4091 init_cgrp_cset_link.cgrp = cgroup_dummy_top;
4092 list_add(&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links);
4093 list_add(&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links);
4094
4109 mutex_unlock(&cgroup_mutex); 4095 mutex_unlock(&cgroup_mutex);
4110 4096
4097 for_each_subsys(ss, ssid) {
4098 if (!ss->early_init)
4099 cgroup_init_subsys(ss);
4100
4101 /*
4102 * cftype registration needs kmalloc and can't be done
4103 * during early_init. Register base cftypes separately.
4104 */
4105 if (ss->base_cftypes)
4106 WARN_ON(cgroup_add_cftypes(ss, ss->base_cftypes));
4107 }
4108
4111 cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj); 4109 cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj);
4112 if (!cgroup_kobj) 4110 if (!cgroup_kobj)
4113 return -ENOMEM; 4111 return -ENOMEM;