aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-06-24 18:21:47 -0400
committerTejun Heo <tj@kernel.org>2013-06-24 18:21:47 -0400
commita8a648c4acee2095262f7fa65b0d8a68a03c32e4 (patch)
tree8547cf0629054715b3541b9bbf2de6642ec9deba /kernel
parent9871bf9550d25e488cd2f0ce958d3f59f17fa720 (diff)
cgroup: remove cgroup->actual_subsys_mask
cgroup curiously has two subsystem masks, ->subsys_mask and ->actual_subsys_mask. The latter only exists because the new target subsys_mask is passed into rebind_subsystems() via @root>subsys_mask. rebind_subsystems() needs to know what the current mask is to decide how to reach the target mask so ->actual_subsys_mask is used as the temp location to remember the current state. Adding a temporary field to a permanent data structure is rather silly and can be misleading. Update rebind_subsystems() to take @added_mask and @removed_mask instead and remove @root->actual_subsys_mask. This patch shouldn't introduce any behavior changes. v2: Comment and description updated as suggested by Li. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cgroup.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 8f296b83b6a3..67fc953c816a 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -986,17 +986,14 @@ static void cgroup_d_remove_dir(struct dentry *dentry)
986 * returns an error, no reference counts are touched. 986 * returns an error, no reference counts are touched.
987 */ 987 */
988static int rebind_subsystems(struct cgroupfs_root *root, 988static int rebind_subsystems(struct cgroupfs_root *root,
989 unsigned long final_subsys_mask) 989 unsigned long added_mask, unsigned removed_mask)
990{ 990{
991 unsigned long added_mask, removed_mask;
992 struct cgroup *cgrp = &root->top_cgroup; 991 struct cgroup *cgrp = &root->top_cgroup;
993 int i; 992 int i;
994 993
995 BUG_ON(!mutex_is_locked(&cgroup_mutex)); 994 BUG_ON(!mutex_is_locked(&cgroup_mutex));
996 BUG_ON(!mutex_is_locked(&cgroup_root_mutex)); 995 BUG_ON(!mutex_is_locked(&cgroup_root_mutex));
997 996
998 removed_mask = root->actual_subsys_mask & ~final_subsys_mask;
999 added_mask = final_subsys_mask & ~root->actual_subsys_mask;
1000 /* Check that any added subsystems are currently free */ 997 /* Check that any added subsystems are currently free */
1001 for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { 998 for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
1002 unsigned long bit = 1UL << i; 999 unsigned long bit = 1UL << i;
@@ -1032,27 +1029,33 @@ static int rebind_subsystems(struct cgroupfs_root *root,
1032 BUG_ON(cgrp->subsys[i]); 1029 BUG_ON(cgrp->subsys[i]);
1033 BUG_ON(!cgroup_dummy_top->subsys[i]); 1030 BUG_ON(!cgroup_dummy_top->subsys[i]);
1034 BUG_ON(cgroup_dummy_top->subsys[i]->cgroup != cgroup_dummy_top); 1031 BUG_ON(cgroup_dummy_top->subsys[i]->cgroup != cgroup_dummy_top);
1032
1035 cgrp->subsys[i] = cgroup_dummy_top->subsys[i]; 1033 cgrp->subsys[i] = cgroup_dummy_top->subsys[i];
1036 cgrp->subsys[i]->cgroup = cgrp; 1034 cgrp->subsys[i]->cgroup = cgrp;
1037 list_move(&ss->sibling, &root->subsys_list); 1035 list_move(&ss->sibling, &root->subsys_list);
1038 ss->root = root; 1036 ss->root = root;
1039 if (ss->bind) 1037 if (ss->bind)
1040 ss->bind(cgrp); 1038 ss->bind(cgrp);
1039
1041 /* refcount was already taken, and we're keeping it */ 1040 /* refcount was already taken, and we're keeping it */
1041 root->subsys_mask |= bit;
1042 } else if (bit & removed_mask) { 1042 } else if (bit & removed_mask) {
1043 /* We're removing this subsystem */ 1043 /* We're removing this subsystem */
1044 BUG_ON(ss == NULL); 1044 BUG_ON(ss == NULL);
1045 BUG_ON(cgrp->subsys[i] != cgroup_dummy_top->subsys[i]); 1045 BUG_ON(cgrp->subsys[i] != cgroup_dummy_top->subsys[i]);
1046 BUG_ON(cgrp->subsys[i]->cgroup != cgrp); 1046 BUG_ON(cgrp->subsys[i]->cgroup != cgrp);
1047
1047 if (ss->bind) 1048 if (ss->bind)
1048 ss->bind(cgroup_dummy_top); 1049 ss->bind(cgroup_dummy_top);
1049 cgroup_dummy_top->subsys[i]->cgroup = cgroup_dummy_top; 1050 cgroup_dummy_top->subsys[i]->cgroup = cgroup_dummy_top;
1050 cgrp->subsys[i] = NULL; 1051 cgrp->subsys[i] = NULL;
1051 cgroup_subsys[i]->root = &cgroup_dummy_root; 1052 cgroup_subsys[i]->root = &cgroup_dummy_root;
1052 list_move(&ss->sibling, &cgroup_dummy_root.subsys_list); 1053 list_move(&ss->sibling, &cgroup_dummy_root.subsys_list);
1054
1053 /* subsystem is now free - drop reference on module */ 1055 /* subsystem is now free - drop reference on module */
1054 module_put(ss->module); 1056 module_put(ss->module);
1055 } else if (bit & final_subsys_mask) { 1057 root->subsys_mask &= ~bit;
1058 } else if (bit & root->subsys_mask) {
1056 /* Subsystem state should already exist */ 1059 /* Subsystem state should already exist */
1057 BUG_ON(ss == NULL); 1060 BUG_ON(ss == NULL);
1058 BUG_ON(!cgrp->subsys[i]); 1061 BUG_ON(!cgrp->subsys[i]);
@@ -1069,7 +1072,6 @@ static int rebind_subsystems(struct cgroupfs_root *root,
1069 BUG_ON(cgrp->subsys[i]); 1072 BUG_ON(cgrp->subsys[i]);
1070 } 1073 }
1071 } 1074 }
1072 root->subsys_mask = root->actual_subsys_mask = final_subsys_mask;
1073 1075
1074 return 0; 1076 return 0;
1075} 1077}
@@ -1343,7 +1345,7 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
1343 if (ret) 1345 if (ret)
1344 goto out_unlock; 1346 goto out_unlock;
1345 1347
1346 if (opts.subsys_mask != root->actual_subsys_mask || opts.release_agent) 1348 if (opts.subsys_mask != root->subsys_mask || opts.release_agent)
1347 pr_warning("cgroup: option changes via remount are deprecated (pid=%d comm=%s)\n", 1349 pr_warning("cgroup: option changes via remount are deprecated (pid=%d comm=%s)\n",
1348 task_tgid_nr(current), current->comm); 1350 task_tgid_nr(current), current->comm);
1349 1351
@@ -1365,7 +1367,7 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
1365 */ 1367 */
1366 cgroup_clear_directory(cgrp->dentry, false, removed_mask); 1368 cgroup_clear_directory(cgrp->dentry, false, removed_mask);
1367 1369
1368 ret = rebind_subsystems(root, opts.subsys_mask); 1370 ret = rebind_subsystems(root, added_mask, removed_mask);
1369 if (ret) { 1371 if (ret) {
1370 /* rebind_subsystems failed, re-populate the removed files */ 1372 /* rebind_subsystems failed, re-populate the removed files */
1371 cgroup_populate_dir(cgrp, false, removed_mask); 1373 cgroup_populate_dir(cgrp, false, removed_mask);
@@ -1634,7 +1636,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
1634 if (ret) 1636 if (ret)
1635 goto unlock_drop; 1637 goto unlock_drop;
1636 1638
1637 ret = rebind_subsystems(root, root->subsys_mask); 1639 ret = rebind_subsystems(root, root->subsys_mask, 0);
1638 if (ret == -EBUSY) { 1640 if (ret == -EBUSY) {
1639 free_cgrp_cset_links(&tmp_links); 1641 free_cgrp_cset_links(&tmp_links);
1640 goto unlock_drop; 1642 goto unlock_drop;
@@ -1727,7 +1729,7 @@ static void cgroup_kill_sb(struct super_block *sb) {
1727 mutex_lock(&cgroup_root_mutex); 1729 mutex_lock(&cgroup_root_mutex);
1728 1730
1729 /* Rebind all subsystems back to the default hierarchy */ 1731 /* Rebind all subsystems back to the default hierarchy */
1730 ret = rebind_subsystems(root, 0); 1732 ret = rebind_subsystems(root, 0, root->subsys_mask);
1731 /* Shouldn't be able to fail ... */ 1733 /* Shouldn't be able to fail ... */
1732 BUG_ON(ret); 1734 BUG_ON(ret);
1733 1735