diff options
author | Tejun Heo <tj@kernel.org> | 2013-06-24 18:21:47 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-06-24 18:21:47 -0400 |
commit | a8a648c4acee2095262f7fa65b0d8a68a03c32e4 (patch) | |
tree | 8547cf0629054715b3541b9bbf2de6642ec9deba /kernel | |
parent | 9871bf9550d25e488cd2f0ce958d3f59f17fa720 (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.c | 22 |
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 | */ |
988 | static int rebind_subsystems(struct cgroupfs_root *root, | 988 | static 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 | ||