aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;