diff options
author | Tejun Heo <tj@kernel.org> | 2013-06-25 14:53:37 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-06-25 14:53:37 -0400 |
commit | 30159ec7a9db7f3c91e2b27e66389c49302efd5c (patch) | |
tree | 68ff4165c8cab6f029a713e3a0a084f16f384ce6 /kernel | |
parent | 82fe9b0da0d50e2795a49c268676fd132cbc3eea (diff) |
cgroup: implement for_each_[builtin_]subsys()
There are quite a few places where all loaded [builtin] subsys are
iterated. Implement for_each_[builtin_]subsys() and replace manual
iterations with those to simplify those places a bit. The new
iterators automatically skip NULL subsystems. This shouldn't cause
any functional difference.
Iteration loops which scan all subsystems and then skipping modular
ones explicitly are converted to use for_each_builtin_subsys().
While at it, reorder variable declarations and adjust whitespaces a
bit in the affected functions.
v2: Add lockdep_assert_held() in for_each_subsys() and add comments
about synchronization 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 | 147 |
1 files changed, 71 insertions, 76 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 3409698bd9fd..cef688128fb8 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -259,6 +259,31 @@ static int notify_on_release(const struct cgroup *cgrp) | |||
259 | return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); | 259 | return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); |
260 | } | 260 | } |
261 | 261 | ||
262 | /** | ||
263 | * for_each_subsys - iterate all loaded cgroup subsystems | ||
264 | * @ss: the iteration cursor | ||
265 | * @i: the index of @ss, CGROUP_SUBSYS_COUNT after reaching the end | ||
266 | * | ||
267 | * Should be called under cgroup_mutex. | ||
268 | */ | ||
269 | #define for_each_subsys(ss, i) \ | ||
270 | for ((i) = 0; (i) < CGROUP_SUBSYS_COUNT; (i)++) \ | ||
271 | if (({ lockdep_assert_held(&cgroup_mutex); \ | ||
272 | !((ss) = cgroup_subsys[i]); })) { } \ | ||
273 | else | ||
274 | |||
275 | /** | ||
276 | * for_each_builtin_subsys - iterate all built-in cgroup subsystems | ||
277 | * @ss: the iteration cursor | ||
278 | * @i: the index of @ss, CGROUP_BUILTIN_SUBSYS_COUNT after reaching the end | ||
279 | * | ||
280 | * Bulit-in subsystems are always present and iteration itself doesn't | ||
281 | * require any synchronization. | ||
282 | */ | ||
283 | #define for_each_builtin_subsys(ss, i) \ | ||
284 | for ((i) = 0; (i) < CGROUP_BUILTIN_SUBSYS_COUNT && \ | ||
285 | (((ss) = cgroup_subsys[i]) || true); (i)++) | ||
286 | |||
262 | /* iterate each subsystem attached to a hierarchy */ | 287 | /* iterate each subsystem attached to a hierarchy */ |
263 | #define for_each_root_subsys(root, ss) \ | 288 | #define for_each_root_subsys(root, ss) \ |
264 | list_for_each_entry((ss), &(root)->subsys_list, sibling) | 289 | list_for_each_entry((ss), &(root)->subsys_list, sibling) |
@@ -356,10 +381,11 @@ static DEFINE_HASHTABLE(css_set_table, CSS_SET_HASH_BITS); | |||
356 | 381 | ||
357 | static unsigned long css_set_hash(struct cgroup_subsys_state *css[]) | 382 | static unsigned long css_set_hash(struct cgroup_subsys_state *css[]) |
358 | { | 383 | { |
359 | int i; | ||
360 | unsigned long key = 0UL; | 384 | unsigned long key = 0UL; |
385 | struct cgroup_subsys *ss; | ||
386 | int i; | ||
361 | 387 | ||
362 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) | 388 | for_each_subsys(ss, i) |
363 | key += (unsigned long)css[i]; | 389 | key += (unsigned long)css[i]; |
364 | key = (key >> 16) ^ key; | 390 | key = (key >> 16) ^ key; |
365 | 391 | ||
@@ -514,6 +540,7 @@ static struct css_set *find_existing_css_set(struct css_set *old_cset, | |||
514 | struct cgroup_subsys_state *template[]) | 540 | struct cgroup_subsys_state *template[]) |
515 | { | 541 | { |
516 | struct cgroupfs_root *root = cgrp->root; | 542 | struct cgroupfs_root *root = cgrp->root; |
543 | struct cgroup_subsys *ss; | ||
517 | struct css_set *cset; | 544 | struct css_set *cset; |
518 | unsigned long key; | 545 | unsigned long key; |
519 | int i; | 546 | int i; |
@@ -523,7 +550,7 @@ static struct css_set *find_existing_css_set(struct css_set *old_cset, | |||
523 | * new css_set. while subsystems can change globally, the entries here | 550 | * new css_set. while subsystems can change globally, the entries here |
524 | * won't change, so no need for locking. | 551 | * won't change, so no need for locking. |
525 | */ | 552 | */ |
526 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 553 | for_each_subsys(ss, i) { |
527 | if (root->subsys_mask & (1UL << i)) { | 554 | if (root->subsys_mask & (1UL << i)) { |
528 | /* Subsystem is in this hierarchy. So we want | 555 | /* Subsystem is in this hierarchy. So we want |
529 | * the subsystem state from the new | 556 | * the subsystem state from the new |
@@ -982,23 +1009,19 @@ static int rebind_subsystems(struct cgroupfs_root *root, | |||
982 | unsigned long added_mask, unsigned removed_mask) | 1009 | unsigned long added_mask, unsigned removed_mask) |
983 | { | 1010 | { |
984 | struct cgroup *cgrp = &root->top_cgroup; | 1011 | struct cgroup *cgrp = &root->top_cgroup; |
1012 | struct cgroup_subsys *ss; | ||
985 | int i; | 1013 | int i; |
986 | 1014 | ||
987 | BUG_ON(!mutex_is_locked(&cgroup_mutex)); | 1015 | BUG_ON(!mutex_is_locked(&cgroup_mutex)); |
988 | BUG_ON(!mutex_is_locked(&cgroup_root_mutex)); | 1016 | BUG_ON(!mutex_is_locked(&cgroup_root_mutex)); |
989 | 1017 | ||
990 | /* Check that any added subsystems are currently free */ | 1018 | /* Check that any added subsystems are currently free */ |
991 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 1019 | for_each_subsys(ss, i) { |
992 | unsigned long bit = 1UL << i; | 1020 | unsigned long bit = 1UL << i; |
993 | struct cgroup_subsys *ss = cgroup_subsys[i]; | 1021 | |
994 | if (!(bit & added_mask)) | 1022 | if (!(bit & added_mask)) |
995 | continue; | 1023 | continue; |
996 | /* | 1024 | |
997 | * Nobody should tell us to do a subsys that doesn't exist: | ||
998 | * parse_cgroupfs_options should catch that case and refcounts | ||
999 | * ensure that subsystems won't disappear once selected. | ||
1000 | */ | ||
1001 | BUG_ON(ss == NULL); | ||
1002 | if (ss->root != &cgroup_dummy_root) { | 1025 | if (ss->root != &cgroup_dummy_root) { |
1003 | /* Subsystem isn't free */ | 1026 | /* Subsystem isn't free */ |
1004 | return -EBUSY; | 1027 | return -EBUSY; |
@@ -1013,12 +1036,11 @@ static int rebind_subsystems(struct cgroupfs_root *root, | |||
1013 | return -EBUSY; | 1036 | return -EBUSY; |
1014 | 1037 | ||
1015 | /* Process each subsystem */ | 1038 | /* Process each subsystem */ |
1016 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 1039 | for_each_subsys(ss, i) { |
1017 | struct cgroup_subsys *ss = cgroup_subsys[i]; | ||
1018 | unsigned long bit = 1UL << i; | 1040 | unsigned long bit = 1UL << i; |
1041 | |||
1019 | if (bit & added_mask) { | 1042 | if (bit & added_mask) { |
1020 | /* We're binding this subsystem to this hierarchy */ | 1043 | /* We're binding this subsystem to this hierarchy */ |
1021 | BUG_ON(ss == NULL); | ||
1022 | BUG_ON(cgrp->subsys[i]); | 1044 | BUG_ON(cgrp->subsys[i]); |
1023 | BUG_ON(!cgroup_dummy_top->subsys[i]); | 1045 | BUG_ON(!cgroup_dummy_top->subsys[i]); |
1024 | BUG_ON(cgroup_dummy_top->subsys[i]->cgroup != cgroup_dummy_top); | 1046 | BUG_ON(cgroup_dummy_top->subsys[i]->cgroup != cgroup_dummy_top); |
@@ -1034,7 +1056,6 @@ static int rebind_subsystems(struct cgroupfs_root *root, | |||
1034 | root->subsys_mask |= bit; | 1056 | root->subsys_mask |= bit; |
1035 | } else if (bit & removed_mask) { | 1057 | } else if (bit & removed_mask) { |
1036 | /* We're removing this subsystem */ | 1058 | /* We're removing this subsystem */ |
1037 | BUG_ON(ss == NULL); | ||
1038 | BUG_ON(cgrp->subsys[i] != cgroup_dummy_top->subsys[i]); | 1059 | BUG_ON(cgrp->subsys[i] != cgroup_dummy_top->subsys[i]); |
1039 | BUG_ON(cgrp->subsys[i]->cgroup != cgrp); | 1060 | BUG_ON(cgrp->subsys[i]->cgroup != cgrp); |
1040 | 1061 | ||
@@ -1050,7 +1071,6 @@ static int rebind_subsystems(struct cgroupfs_root *root, | |||
1050 | root->subsys_mask &= ~bit; | 1071 | root->subsys_mask &= ~bit; |
1051 | } else if (bit & root->subsys_mask) { | 1072 | } else if (bit & root->subsys_mask) { |
1052 | /* Subsystem state should already exist */ | 1073 | /* Subsystem state should already exist */ |
1053 | BUG_ON(ss == NULL); | ||
1054 | BUG_ON(!cgrp->subsys[i]); | 1074 | BUG_ON(!cgrp->subsys[i]); |
1055 | /* | 1075 | /* |
1056 | * a refcount was taken, but we already had one, so | 1076 | * a refcount was taken, but we already had one, so |
@@ -1117,8 +1137,9 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1117 | char *token, *o = data; | 1137 | char *token, *o = data; |
1118 | bool all_ss = false, one_ss = false; | 1138 | bool all_ss = false, one_ss = false; |
1119 | unsigned long mask = (unsigned long)-1; | 1139 | unsigned long mask = (unsigned long)-1; |
1120 | int i; | ||
1121 | bool module_pin_failed = false; | 1140 | bool module_pin_failed = false; |
1141 | struct cgroup_subsys *ss; | ||
1142 | int i; | ||
1122 | 1143 | ||
1123 | BUG_ON(!mutex_is_locked(&cgroup_mutex)); | 1144 | BUG_ON(!mutex_is_locked(&cgroup_mutex)); |
1124 | 1145 | ||
@@ -1195,10 +1216,7 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1195 | continue; | 1216 | continue; |
1196 | } | 1217 | } |
1197 | 1218 | ||
1198 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 1219 | for_each_subsys(ss, i) { |
1199 | struct cgroup_subsys *ss = cgroup_subsys[i]; | ||
1200 | if (ss == NULL) | ||
1201 | continue; | ||
1202 | if (strcmp(token, ss->name)) | 1220 | if (strcmp(token, ss->name)) |
1203 | continue; | 1221 | continue; |
1204 | if (ss->disabled) | 1222 | if (ss->disabled) |
@@ -1221,16 +1239,10 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1221 | * otherwise if 'none', 'name=' and a subsystem name options | 1239 | * otherwise if 'none', 'name=' and a subsystem name options |
1222 | * were not specified, let's default to 'all' | 1240 | * were not specified, let's default to 'all' |
1223 | */ | 1241 | */ |
1224 | if (all_ss || (!one_ss && !opts->none && !opts->name)) { | 1242 | if (all_ss || (!one_ss && !opts->none && !opts->name)) |
1225 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 1243 | for_each_subsys(ss, i) |
1226 | struct cgroup_subsys *ss = cgroup_subsys[i]; | 1244 | if (!ss->disabled) |
1227 | if (ss == NULL) | 1245 | set_bit(i, &opts->subsys_mask); |
1228 | continue; | ||
1229 | if (ss->disabled) | ||
1230 | continue; | ||
1231 | set_bit(i, &opts->subsys_mask); | ||
1232 | } | ||
1233 | } | ||
1234 | 1246 | ||
1235 | /* Consistency checks */ | 1247 | /* Consistency checks */ |
1236 | 1248 | ||
@@ -1274,10 +1286,8 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1274 | * take duplicate reference counts on a subsystem that's already used, | 1286 | * take duplicate reference counts on a subsystem that's already used, |
1275 | * but rebind_subsystems handles this case. | 1287 | * but rebind_subsystems handles this case. |
1276 | */ | 1288 | */ |
1277 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 1289 | for_each_subsys(ss, i) { |
1278 | unsigned long bit = 1UL << i; | 1290 | if (!(opts->subsys_mask & (1UL << i))) |
1279 | |||
1280 | if (!(bit & opts->subsys_mask)) | ||
1281 | continue; | 1291 | continue; |
1282 | if (!try_module_get(cgroup_subsys[i]->module)) { | 1292 | if (!try_module_get(cgroup_subsys[i]->module)) { |
1283 | module_pin_failed = true; | 1293 | module_pin_failed = true; |
@@ -1306,11 +1316,11 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1306 | 1316 | ||
1307 | static void drop_parsed_module_refcounts(unsigned long subsys_mask) | 1317 | static void drop_parsed_module_refcounts(unsigned long subsys_mask) |
1308 | { | 1318 | { |
1319 | struct cgroup_subsys *ss; | ||
1309 | int i; | 1320 | int i; |
1310 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | ||
1311 | unsigned long bit = 1UL << i; | ||
1312 | 1321 | ||
1313 | if (!(bit & subsys_mask)) | 1322 | for_each_subsys(ss, i) { |
1323 | if (!(subsys_mask & (1UL << i))) | ||
1314 | continue; | 1324 | continue; |
1315 | module_put(cgroup_subsys[i]->module); | 1325 | module_put(cgroup_subsys[i]->module); |
1316 | } | 1326 | } |
@@ -4822,7 +4832,9 @@ EXPORT_SYMBOL_GPL(cgroup_unload_subsys); | |||
4822 | */ | 4832 | */ |
4823 | int __init cgroup_init_early(void) | 4833 | int __init cgroup_init_early(void) |
4824 | { | 4834 | { |
4835 | struct cgroup_subsys *ss; | ||
4825 | int i; | 4836 | int i; |
4837 | |||
4826 | atomic_set(&init_css_set.refcount, 1); | 4838 | atomic_set(&init_css_set.refcount, 1); |
4827 | INIT_LIST_HEAD(&init_css_set.cgrp_links); | 4839 | INIT_LIST_HEAD(&init_css_set.cgrp_links); |
4828 | INIT_LIST_HEAD(&init_css_set.tasks); | 4840 | INIT_LIST_HEAD(&init_css_set.tasks); |
@@ -4837,13 +4849,8 @@ int __init cgroup_init_early(void) | |||
4837 | list_add(&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links); | 4849 | list_add(&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links); |
4838 | list_add(&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links); | 4850 | list_add(&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links); |
4839 | 4851 | ||
4840 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 4852 | /* at bootup time, we don't worry about modular subsystems */ |
4841 | struct cgroup_subsys *ss = cgroup_subsys[i]; | 4853 | for_each_builtin_subsys(ss, i) { |
4842 | |||
4843 | /* at bootup time, we don't worry about modular subsystems */ | ||
4844 | if (!ss || ss->module) | ||
4845 | continue; | ||
4846 | |||
4847 | BUG_ON(!ss->name); | 4854 | BUG_ON(!ss->name); |
4848 | BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN); | 4855 | BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN); |
4849 | BUG_ON(!ss->css_alloc); | 4856 | BUG_ON(!ss->css_alloc); |
@@ -4868,20 +4875,15 @@ int __init cgroup_init_early(void) | |||
4868 | */ | 4875 | */ |
4869 | int __init cgroup_init(void) | 4876 | int __init cgroup_init(void) |
4870 | { | 4877 | { |
4871 | int err; | 4878 | struct cgroup_subsys *ss; |
4872 | int i; | ||
4873 | unsigned long key; | 4879 | unsigned long key; |
4880 | int i, err; | ||
4874 | 4881 | ||
4875 | err = bdi_init(&cgroup_backing_dev_info); | 4882 | err = bdi_init(&cgroup_backing_dev_info); |
4876 | if (err) | 4883 | if (err) |
4877 | return err; | 4884 | return err; |
4878 | 4885 | ||
4879 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 4886 | for_each_builtin_subsys(ss, i) { |
4880 | struct cgroup_subsys *ss = cgroup_subsys[i]; | ||
4881 | |||
4882 | /* at bootup time, we don't worry about modular subsystems */ | ||
4883 | if (!ss || ss->module) | ||
4884 | continue; | ||
4885 | if (!ss->early_init) | 4887 | if (!ss->early_init) |
4886 | cgroup_init_subsys(ss); | 4888 | cgroup_init_subsys(ss); |
4887 | if (ss->use_id) | 4889 | if (ss->use_id) |
@@ -4990,6 +4992,7 @@ out: | |||
4990 | /* Display information about each subsystem and each hierarchy */ | 4992 | /* Display information about each subsystem and each hierarchy */ |
4991 | static int proc_cgroupstats_show(struct seq_file *m, void *v) | 4993 | static int proc_cgroupstats_show(struct seq_file *m, void *v) |
4992 | { | 4994 | { |
4995 | struct cgroup_subsys *ss; | ||
4993 | int i; | 4996 | int i; |
4994 | 4997 | ||
4995 | seq_puts(m, "#subsys_name\thierarchy\tnum_cgroups\tenabled\n"); | 4998 | seq_puts(m, "#subsys_name\thierarchy\tnum_cgroups\tenabled\n"); |
@@ -4999,14 +5002,12 @@ static int proc_cgroupstats_show(struct seq_file *m, void *v) | |||
4999 | * subsys/hierarchy state. | 5002 | * subsys/hierarchy state. |
5000 | */ | 5003 | */ |
5001 | mutex_lock(&cgroup_mutex); | 5004 | mutex_lock(&cgroup_mutex); |
5002 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 5005 | |
5003 | struct cgroup_subsys *ss = cgroup_subsys[i]; | 5006 | for_each_subsys(ss, i) |
5004 | if (ss == NULL) | ||
5005 | continue; | ||
5006 | seq_printf(m, "%s\t%d\t%d\t%d\n", | 5007 | seq_printf(m, "%s\t%d\t%d\t%d\n", |
5007 | ss->name, ss->root->hierarchy_id, | 5008 | ss->name, ss->root->hierarchy_id, |
5008 | ss->root->number_of_cgroups, !ss->disabled); | 5009 | ss->root->number_of_cgroups, !ss->disabled); |
5009 | } | 5010 | |
5010 | mutex_unlock(&cgroup_mutex); | 5011 | mutex_unlock(&cgroup_mutex); |
5011 | return 0; | 5012 | return 0; |
5012 | } | 5013 | } |
@@ -5060,6 +5061,7 @@ void cgroup_fork(struct task_struct *child) | |||
5060 | */ | 5061 | */ |
5061 | void cgroup_post_fork(struct task_struct *child) | 5062 | void cgroup_post_fork(struct task_struct *child) |
5062 | { | 5063 | { |
5064 | struct cgroup_subsys *ss; | ||
5063 | int i; | 5065 | int i; |
5064 | 5066 | ||
5065 | /* | 5067 | /* |
@@ -5096,12 +5098,9 @@ void cgroup_post_fork(struct task_struct *child) | |||
5096 | * of the array can be freed at module unload, so we | 5098 | * of the array can be freed at module unload, so we |
5097 | * can't touch that. | 5099 | * can't touch that. |
5098 | */ | 5100 | */ |
5099 | for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) { | 5101 | for_each_builtin_subsys(ss, i) |
5100 | struct cgroup_subsys *ss = cgroup_subsys[i]; | ||
5101 | |||
5102 | if (ss->fork) | 5102 | if (ss->fork) |
5103 | ss->fork(child); | 5103 | ss->fork(child); |
5104 | } | ||
5105 | } | 5104 | } |
5106 | } | 5105 | } |
5107 | 5106 | ||
@@ -5142,6 +5141,7 @@ void cgroup_post_fork(struct task_struct *child) | |||
5142 | */ | 5141 | */ |
5143 | void cgroup_exit(struct task_struct *tsk, int run_callbacks) | 5142 | void cgroup_exit(struct task_struct *tsk, int run_callbacks) |
5144 | { | 5143 | { |
5144 | struct cgroup_subsys *ss; | ||
5145 | struct css_set *cset; | 5145 | struct css_set *cset; |
5146 | int i; | 5146 | int i; |
5147 | 5147 | ||
@@ -5167,13 +5167,12 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks) | |||
5167 | * fork/exit callbacks are supported only for builtin | 5167 | * fork/exit callbacks are supported only for builtin |
5168 | * subsystems, see cgroup_post_fork() for details. | 5168 | * subsystems, see cgroup_post_fork() for details. |
5169 | */ | 5169 | */ |
5170 | for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) { | 5170 | for_each_builtin_subsys(ss, i) { |
5171 | struct cgroup_subsys *ss = cgroup_subsys[i]; | ||
5172 | |||
5173 | if (ss->exit) { | 5171 | if (ss->exit) { |
5174 | struct cgroup *old_cgrp = | 5172 | struct cgroup *old_cgrp = |
5175 | rcu_dereference_raw(cset->subsys[i])->cgroup; | 5173 | rcu_dereference_raw(cset->subsys[i])->cgroup; |
5176 | struct cgroup *cgrp = task_cgroup(tsk, i); | 5174 | struct cgroup *cgrp = task_cgroup(tsk, i); |
5175 | |||
5177 | ss->exit(cgrp, old_cgrp, tsk); | 5176 | ss->exit(cgrp, old_cgrp, tsk); |
5178 | } | 5177 | } |
5179 | } | 5178 | } |
@@ -5280,23 +5279,19 @@ static void cgroup_release_agent(struct work_struct *work) | |||
5280 | 5279 | ||
5281 | static int __init cgroup_disable(char *str) | 5280 | static int __init cgroup_disable(char *str) |
5282 | { | 5281 | { |
5283 | int i; | 5282 | struct cgroup_subsys *ss; |
5284 | char *token; | 5283 | char *token; |
5284 | int i; | ||
5285 | 5285 | ||
5286 | while ((token = strsep(&str, ",")) != NULL) { | 5286 | while ((token = strsep(&str, ",")) != NULL) { |
5287 | if (!*token) | 5287 | if (!*token) |
5288 | continue; | 5288 | continue; |
5289 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | ||
5290 | struct cgroup_subsys *ss = cgroup_subsys[i]; | ||
5291 | |||
5292 | /* | ||
5293 | * cgroup_disable, being at boot time, can't | ||
5294 | * know about module subsystems, so we don't | ||
5295 | * worry about them. | ||
5296 | */ | ||
5297 | if (!ss || ss->module) | ||
5298 | continue; | ||
5299 | 5289 | ||
5290 | /* | ||
5291 | * cgroup_disable, being at boot time, can't know about | ||
5292 | * module subsystems, so we don't worry about them. | ||
5293 | */ | ||
5294 | for_each_builtin_subsys(ss, i) { | ||
5300 | if (!strcmp(token, ss->name)) { | 5295 | if (!strcmp(token, ss->name)) { |
5301 | ss->disabled = 1; | 5296 | ss->disabled = 1; |
5302 | printk(KERN_INFO "Disabling %s control group" | 5297 | printk(KERN_INFO "Disabling %s control group" |