aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-02-12 09:29:50 -0500
committerTejun Heo <tj@kernel.org>2014-02-12 09:29:50 -0500
commit3c9c825b8b50de7dbb015e6bfc04bb2da79364d9 (patch)
treed12fdc2cc0c232e07f1cccb1f72435210e18075e /kernel/cgroup.c
parente61734c55c24cdf11b07e52a74aec4dc4a7f4bd0 (diff)
cgroup: rename cgroupfs_root->number_of_cgroups to ->nr_cgrps and make it atomic_t
root->number_of_cgroups is currently an integer protected with cgroup_mutex. Except for sanity checks and proc reporting, the only place it's used is to check whether the root has any child during remount; however, this is a bit flawed as the counter is not decremented when the cgroup is unlinked but when it's released, meaning that there could be an extended period where all cgroups are removed but remount is still not allowed because some internal objects are lingering. While not perfect either, it'd be better to use emptiness test on root->top_cgroup.children. This patch updates cgroup_remount() to test top_cgroup's children instead, which makes number_of_cgroups only actual usage statistics printing in proc implemented in proc_cgroupstats_show(). Let's shorten its name and make it an atomic_t so that we don't have to worry about its synchronization. It's purely auxiliary at this point. 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.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 638df032fb94..cffdb6e2ad08 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -758,7 +758,7 @@ static void cgroup_put_root(struct cgroupfs_root *root)
758 } 758 }
759 mutex_lock(&cgroup_mutex); 759 mutex_lock(&cgroup_mutex);
760 760
761 BUG_ON(root->number_of_cgroups != 1); 761 BUG_ON(atomic_read(&root->nr_cgrps) != 1);
762 BUG_ON(!list_empty(&cgrp->children)); 762 BUG_ON(!list_empty(&cgrp->children));
763 763
764 /* Rebind all subsystems back to the default hierarchy */ 764 /* Rebind all subsystems back to the default hierarchy */
@@ -928,9 +928,7 @@ static void cgroup_free_fn(struct work_struct *work)
928{ 928{
929 struct cgroup *cgrp = container_of(work, struct cgroup, destroy_work); 929 struct cgroup *cgrp = container_of(work, struct cgroup, destroy_work);
930 930
931 mutex_lock(&cgroup_mutex); 931 atomic_dec(&cgrp->root->nr_cgrps);
932 cgrp->root->number_of_cgroups--;
933 mutex_unlock(&cgroup_mutex);
934 932
935 /* 933 /*
936 * We get a ref to the parent, and put the ref when this cgroup is 934 * We get a ref to the parent, and put the ref when this cgroup is
@@ -1320,7 +1318,7 @@ static int cgroup_remount(struct kernfs_root *kf_root, int *flags, char *data)
1320 } 1318 }
1321 1319
1322 /* remounting is not allowed for populated hierarchies */ 1320 /* remounting is not allowed for populated hierarchies */
1323 if (root->number_of_cgroups > 1) { 1321 if (!list_empty(&root->top_cgroup.children)) {
1324 ret = -EBUSY; 1322 ret = -EBUSY;
1325 goto out_unlock; 1323 goto out_unlock;
1326 } 1324 }
@@ -1360,7 +1358,7 @@ static void init_cgroup_root(struct cgroupfs_root *root)
1360 1358
1361 atomic_set(&root->refcnt, 1); 1359 atomic_set(&root->refcnt, 1);
1362 INIT_LIST_HEAD(&root->root_list); 1360 INIT_LIST_HEAD(&root->root_list);
1363 root->number_of_cgroups = 1; 1361 atomic_set(&root->nr_cgrps, 1);
1364 cgrp->root = root; 1362 cgrp->root = root;
1365 init_cgroup_housekeeping(cgrp); 1363 init_cgroup_housekeeping(cgrp);
1366 idr_init(&root->cgroup_idr); 1364 idr_init(&root->cgroup_idr);
@@ -1463,7 +1461,7 @@ static int cgroup_setup_root(struct cgroupfs_root *root)
1463 write_unlock(&css_set_lock); 1461 write_unlock(&css_set_lock);
1464 1462
1465 BUG_ON(!list_empty(&root_cgrp->children)); 1463 BUG_ON(!list_empty(&root_cgrp->children));
1466 BUG_ON(root->number_of_cgroups != 1); 1464 BUG_ON(atomic_read(&root->nr_cgrps) != 1);
1467 1465
1468 kernfs_activate(root_cgrp->kn); 1466 kernfs_activate(root_cgrp->kn);
1469 ret = 0; 1467 ret = 0;
@@ -3709,7 +3707,7 @@ static long cgroup_create(struct cgroup *parent, const char *name,
3709 3707
3710 /* allocation complete, commit to creation */ 3708 /* allocation complete, commit to creation */
3711 list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children); 3709 list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children);
3712 root->number_of_cgroups++; 3710 atomic_inc(&root->nr_cgrps);
3713 3711
3714 /* 3712 /*
3715 * Grab a reference on the root and parent so that they don't get 3713 * Grab a reference on the root and parent so that they don't get
@@ -4281,7 +4279,7 @@ static int proc_cgroupstats_show(struct seq_file *m, void *v)
4281 for_each_subsys(ss, i) 4279 for_each_subsys(ss, i)
4282 seq_printf(m, "%s\t%d\t%d\t%d\n", 4280 seq_printf(m, "%s\t%d\t%d\t%d\n",
4283 ss->name, ss->root->hierarchy_id, 4281 ss->name, ss->root->hierarchy_id,
4284 ss->root->number_of_cgroups, !ss->disabled); 4282 atomic_read(&ss->root->nr_cgrps), !ss->disabled);
4285 4283
4286 mutex_unlock(&cgroup_mutex); 4284 mutex_unlock(&cgroup_mutex);
4287 return 0; 4285 return 0;