diff options
author | Tejun Heo <tj@kernel.org> | 2014-02-08 10:36:58 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-02-08 10:36:58 -0500 |
commit | 3ed80a62bf959d34ebd4d553b026fbe7e6fbcc54 (patch) | |
tree | 3ec2ce050e41b056a8de66f24eac76dd2d5912e5 /kernel/cgroup.c | |
parent | af6363374cbda5007e46efa99f7346efd4eea5fc (diff) |
cgroup: drop module support
With module supported dropped from net_prio, no controller is using
cgroup module support. None of actual resource controllers can be
built as a module and we aren't gonna add new controllers which don't
control resources. This patch drops module support from cgroup.
* cgroup_[un]load_subsys() and cgroup_subsys->module removed.
* As there's no point in distinguishing IS_BUILTIN() and IS_MODULE(),
cgroup_subsys.h now uses IS_ENABLED() directly.
* enum cgroup_subsys_id now exactly matches the list of enabled
controllers as ordered in cgroup_subsys.h.
* cgroup_subsys[] is now a contiguously occupied array. Size
specification is no longer necessary and dropped.
* for_each_builtin_subsys() is removed and for_each_subsys() is
updated to not require any locking.
* module ref handling is removed from rebind_subsystems().
* Module related comments dropped.
v2: Rebased on top of fe1217c4f3f7 ("net: net_cls: move cgroupfs
classid handling into core").
v3: Added {} around the if (need_forkexit_callback) block in
cgroup_post_fork() for readability as suggested by Li.
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.c | 284 |
1 files changed, 16 insertions, 268 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index e2f46ba37f72..ccb16b47e293 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/string.h> | 47 | #include <linux/string.h> |
48 | #include <linux/sort.h> | 48 | #include <linux/sort.h> |
49 | #include <linux/kmod.h> | 49 | #include <linux/kmod.h> |
50 | #include <linux/module.h> | ||
51 | #include <linux/delayacct.h> | 50 | #include <linux/delayacct.h> |
52 | #include <linux/cgroupstats.h> | 51 | #include <linux/cgroupstats.h> |
53 | #include <linux/hashtable.h> | 52 | #include <linux/hashtable.h> |
@@ -120,15 +119,9 @@ static struct workqueue_struct *cgroup_destroy_wq; | |||
120 | */ | 119 | */ |
121 | static struct workqueue_struct *cgroup_pidlist_destroy_wq; | 120 | static struct workqueue_struct *cgroup_pidlist_destroy_wq; |
122 | 121 | ||
123 | /* | 122 | /* generate an array of cgroup subsystem pointers */ |
124 | * Generate an array of cgroup subsystem pointers. At boot time, this is | ||
125 | * populated with the built in subsystems, and modular subsystems are | ||
126 | * registered after that. The mutable section of this array is protected by | ||
127 | * cgroup_mutex. | ||
128 | */ | ||
129 | #define SUBSYS(_x) [_x ## _subsys_id] = &_x ## _subsys, | 123 | #define SUBSYS(_x) [_x ## _subsys_id] = &_x ## _subsys, |
130 | #define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option) | 124 | static struct cgroup_subsys *cgroup_subsys[] = { |
131 | static struct cgroup_subsys *cgroup_subsys[CGROUP_SUBSYS_COUNT] = { | ||
132 | #include <linux/cgroup_subsys.h> | 125 | #include <linux/cgroup_subsys.h> |
133 | }; | 126 | }; |
134 | 127 | ||
@@ -258,30 +251,13 @@ static int notify_on_release(const struct cgroup *cgrp) | |||
258 | else | 251 | else |
259 | 252 | ||
260 | /** | 253 | /** |
261 | * for_each_subsys - iterate all loaded cgroup subsystems | 254 | * for_each_subsys - iterate all enabled cgroup subsystems |
262 | * @ss: the iteration cursor | 255 | * @ss: the iteration cursor |
263 | * @ssid: the index of @ss, CGROUP_SUBSYS_COUNT after reaching the end | 256 | * @ssid: the index of @ss, CGROUP_SUBSYS_COUNT after reaching the end |
264 | * | ||
265 | * Iterates through all loaded subsystems. Should be called under | ||
266 | * cgroup_mutex or cgroup_root_mutex. | ||
267 | */ | 257 | */ |
268 | #define for_each_subsys(ss, ssid) \ | 258 | #define for_each_subsys(ss, ssid) \ |
269 | for (({ cgroup_assert_mutex_or_root_locked(); (ssid) = 0; }); \ | 259 | for ((ssid) = 0; (ssid) < CGROUP_SUBSYS_COUNT && \ |
270 | (ssid) < CGROUP_SUBSYS_COUNT; (ssid)++) \ | 260 | (((ss) = cgroup_subsys[ssid]) || true); (ssid)++) |
271 | if (!((ss) = cgroup_subsys[(ssid)])) { } \ | ||
272 | else | ||
273 | |||
274 | /** | ||
275 | * for_each_builtin_subsys - iterate all built-in cgroup subsystems | ||
276 | * @ss: the iteration cursor | ||
277 | * @i: the index of @ss, CGROUP_BUILTIN_SUBSYS_COUNT after reaching the end | ||
278 | * | ||
279 | * Bulit-in subsystems are always present and iteration itself doesn't | ||
280 | * require any synchronization. | ||
281 | */ | ||
282 | #define for_each_builtin_subsys(ss, i) \ | ||
283 | for ((i) = 0; (i) < CGROUP_BUILTIN_SUBSYS_COUNT && \ | ||
284 | (((ss) = cgroup_subsys[i]) || true); (i)++) | ||
285 | 261 | ||
286 | /* iterate across the active hierarchies */ | 262 | /* iterate across the active hierarchies */ |
287 | #define for_each_active_root(root) \ | 263 | #define for_each_active_root(root) \ |
@@ -975,50 +951,24 @@ static void cgroup_d_remove_dir(struct dentry *dentry) | |||
975 | remove_dir(dentry); | 951 | remove_dir(dentry); |
976 | } | 952 | } |
977 | 953 | ||
978 | /* | ||
979 | * Call with cgroup_mutex held. Drops reference counts on modules, including | ||
980 | * any duplicate ones that parse_cgroupfs_options took. If this function | ||
981 | * returns an error, no reference counts are touched. | ||
982 | */ | ||
983 | static int rebind_subsystems(struct cgroupfs_root *root, | 954 | static int rebind_subsystems(struct cgroupfs_root *root, |
984 | unsigned long added_mask, unsigned removed_mask) | 955 | unsigned long added_mask, unsigned removed_mask) |
985 | { | 956 | { |
986 | struct cgroup *cgrp = &root->top_cgroup; | 957 | struct cgroup *cgrp = &root->top_cgroup; |
987 | struct cgroup_subsys *ss; | 958 | struct cgroup_subsys *ss; |
988 | unsigned long pinned = 0; | ||
989 | int i, ret; | 959 | int i, ret; |
990 | 960 | ||
991 | BUG_ON(!mutex_is_locked(&cgroup_mutex)); | 961 | BUG_ON(!mutex_is_locked(&cgroup_mutex)); |
992 | BUG_ON(!mutex_is_locked(&cgroup_root_mutex)); | 962 | BUG_ON(!mutex_is_locked(&cgroup_root_mutex)); |
993 | 963 | ||
994 | /* Check that any added subsystems are currently free */ | 964 | /* Check that any added subsystems are currently free */ |
995 | for_each_subsys(ss, i) { | 965 | for_each_subsys(ss, i) |
996 | if (!(added_mask & (1 << i))) | 966 | if ((added_mask & (1 << i)) && ss->root != &cgroup_dummy_root) |
997 | continue; | 967 | return -EBUSY; |
998 | |||
999 | /* is the subsystem mounted elsewhere? */ | ||
1000 | if (ss->root != &cgroup_dummy_root) { | ||
1001 | ret = -EBUSY; | ||
1002 | goto out_put; | ||
1003 | } | ||
1004 | |||
1005 | /* pin the module */ | ||
1006 | if (!try_module_get(ss->module)) { | ||
1007 | ret = -ENOENT; | ||
1008 | goto out_put; | ||
1009 | } | ||
1010 | pinned |= 1 << i; | ||
1011 | } | ||
1012 | |||
1013 | /* subsys could be missing if unloaded between parsing and here */ | ||
1014 | if (added_mask != pinned) { | ||
1015 | ret = -ENOENT; | ||
1016 | goto out_put; | ||
1017 | } | ||
1018 | 968 | ||
1019 | ret = cgroup_populate_dir(cgrp, added_mask); | 969 | ret = cgroup_populate_dir(cgrp, added_mask); |
1020 | if (ret) | 970 | if (ret) |
1021 | goto out_put; | 971 | return ret; |
1022 | 972 | ||
1023 | /* | 973 | /* |
1024 | * Nothing can fail from this point on. Remove files for the | 974 | * Nothing can fail from this point on. Remove files for the |
@@ -1057,9 +1007,6 @@ static int rebind_subsystems(struct cgroupfs_root *root, | |||
1057 | RCU_INIT_POINTER(cgrp->subsys[i], NULL); | 1007 | RCU_INIT_POINTER(cgrp->subsys[i], NULL); |
1058 | 1008 | ||
1059 | cgroup_subsys[i]->root = &cgroup_dummy_root; | 1009 | cgroup_subsys[i]->root = &cgroup_dummy_root; |
1060 | |||
1061 | /* subsystem is now free - drop reference on module */ | ||
1062 | module_put(ss->module); | ||
1063 | root->subsys_mask &= ~bit; | 1010 | root->subsys_mask &= ~bit; |
1064 | } | 1011 | } |
1065 | } | 1012 | } |
@@ -1071,12 +1018,6 @@ static int rebind_subsystems(struct cgroupfs_root *root, | |||
1071 | root->flags |= CGRP_ROOT_SUBSYS_BOUND; | 1018 | root->flags |= CGRP_ROOT_SUBSYS_BOUND; |
1072 | 1019 | ||
1073 | return 0; | 1020 | return 0; |
1074 | |||
1075 | out_put: | ||
1076 | for_each_subsys(ss, i) | ||
1077 | if (pinned & (1 << i)) | ||
1078 | module_put(ss->module); | ||
1079 | return ret; | ||
1080 | } | 1021 | } |
1081 | 1022 | ||
1082 | static int cgroup_show_options(struct seq_file *seq, struct dentry *dentry) | 1023 | static int cgroup_show_options(struct seq_file *seq, struct dentry *dentry) |
@@ -4506,7 +4447,7 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) | |||
4506 | return ret; | 4447 | return ret; |
4507 | } | 4448 | } |
4508 | 4449 | ||
4509 | static void __init_or_module cgroup_init_cftsets(struct cgroup_subsys *ss) | 4450 | static void __init cgroup_init_cftsets(struct cgroup_subsys *ss) |
4510 | { | 4451 | { |
4511 | INIT_LIST_HEAD(&ss->cftsets); | 4452 | INIT_LIST_HEAD(&ss->cftsets); |
4512 | 4453 | ||
@@ -4559,186 +4500,9 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss) | |||
4559 | BUG_ON(online_css(css)); | 4500 | BUG_ON(online_css(css)); |
4560 | 4501 | ||
4561 | mutex_unlock(&cgroup_mutex); | 4502 | mutex_unlock(&cgroup_mutex); |
4562 | |||
4563 | /* this function shouldn't be used with modular subsystems, since they | ||
4564 | * need to register a subsys_id, among other things */ | ||
4565 | BUG_ON(ss->module); | ||
4566 | } | 4503 | } |
4567 | 4504 | ||
4568 | /** | 4505 | /** |
4569 | * cgroup_load_subsys: load and register a modular subsystem at runtime | ||
4570 | * @ss: the subsystem to load | ||
4571 | * | ||
4572 | * This function should be called in a modular subsystem's initcall. If the | ||
4573 | * subsystem is built as a module, it will be assigned a new subsys_id and set | ||
4574 | * up for use. If the subsystem is built-in anyway, work is delegated to the | ||
4575 | * simpler cgroup_init_subsys. | ||
4576 | */ | ||
4577 | int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss) | ||
4578 | { | ||
4579 | struct cgroup_subsys_state *css; | ||
4580 | int i, ret; | ||
4581 | struct hlist_node *tmp; | ||
4582 | struct css_set *cset; | ||
4583 | unsigned long key; | ||
4584 | |||
4585 | /* check name and function validity */ | ||
4586 | if (ss->name == NULL || strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN || | ||
4587 | ss->css_alloc == NULL || ss->css_free == NULL) | ||
4588 | return -EINVAL; | ||
4589 | |||
4590 | /* | ||
4591 | * we don't support callbacks in modular subsystems. this check is | ||
4592 | * before the ss->module check for consistency; a subsystem that could | ||
4593 | * be a module should still have no callbacks even if the user isn't | ||
4594 | * compiling it as one. | ||
4595 | */ | ||
4596 | if (ss->fork || ss->exit) | ||
4597 | return -EINVAL; | ||
4598 | |||
4599 | /* | ||
4600 | * an optionally modular subsystem is built-in: we want to do nothing, | ||
4601 | * since cgroup_init_subsys will have already taken care of it. | ||
4602 | */ | ||
4603 | if (ss->module == NULL) { | ||
4604 | /* a sanity check */ | ||
4605 | BUG_ON(cgroup_subsys[ss->subsys_id] != ss); | ||
4606 | return 0; | ||
4607 | } | ||
4608 | |||
4609 | /* init base cftset */ | ||
4610 | cgroup_init_cftsets(ss); | ||
4611 | |||
4612 | mutex_lock(&cgroup_mutex); | ||
4613 | mutex_lock(&cgroup_root_mutex); | ||
4614 | cgroup_subsys[ss->subsys_id] = ss; | ||
4615 | |||
4616 | /* | ||
4617 | * no ss->css_alloc seems to need anything important in the ss | ||
4618 | * struct, so this can happen first (i.e. before the dummy root | ||
4619 | * attachment). | ||
4620 | */ | ||
4621 | css = ss->css_alloc(cgroup_css(cgroup_dummy_top, ss)); | ||
4622 | if (IS_ERR(css)) { | ||
4623 | /* failure case - need to deassign the cgroup_subsys[] slot. */ | ||
4624 | cgroup_subsys[ss->subsys_id] = NULL; | ||
4625 | mutex_unlock(&cgroup_root_mutex); | ||
4626 | mutex_unlock(&cgroup_mutex); | ||
4627 | return PTR_ERR(css); | ||
4628 | } | ||
4629 | |||
4630 | ss->root = &cgroup_dummy_root; | ||
4631 | |||
4632 | /* our new subsystem will be attached to the dummy hierarchy. */ | ||
4633 | init_css(css, ss, cgroup_dummy_top); | ||
4634 | |||
4635 | /* | ||
4636 | * Now we need to entangle the css into the existing css_sets. unlike | ||
4637 | * in cgroup_init_subsys, there are now multiple css_sets, so each one | ||
4638 | * will need a new pointer to it; done by iterating the css_set_table. | ||
4639 | * furthermore, modifying the existing css_sets will corrupt the hash | ||
4640 | * table state, so each changed css_set will need its hash recomputed. | ||
4641 | * this is all done under the css_set_lock. | ||
4642 | */ | ||
4643 | write_lock(&css_set_lock); | ||
4644 | hash_for_each_safe(css_set_table, i, tmp, cset, hlist) { | ||
4645 | /* skip entries that we already rehashed */ | ||
4646 | if (cset->subsys[ss->subsys_id]) | ||
4647 | continue; | ||
4648 | /* remove existing entry */ | ||
4649 | hash_del(&cset->hlist); | ||
4650 | /* set new value */ | ||
4651 | cset->subsys[ss->subsys_id] = css; | ||
4652 | /* recompute hash and restore entry */ | ||
4653 | key = css_set_hash(cset->subsys); | ||
4654 | hash_add(css_set_table, &cset->hlist, key); | ||
4655 | } | ||
4656 | write_unlock(&css_set_lock); | ||
4657 | |||
4658 | ret = online_css(css); | ||
4659 | if (ret) { | ||
4660 | ss->css_free(css); | ||
4661 | goto err_unload; | ||
4662 | } | ||
4663 | |||
4664 | /* success! */ | ||
4665 | mutex_unlock(&cgroup_root_mutex); | ||
4666 | mutex_unlock(&cgroup_mutex); | ||
4667 | return 0; | ||
4668 | |||
4669 | err_unload: | ||
4670 | mutex_unlock(&cgroup_root_mutex); | ||
4671 | mutex_unlock(&cgroup_mutex); | ||
4672 | /* @ss can't be mounted here as try_module_get() would fail */ | ||
4673 | cgroup_unload_subsys(ss); | ||
4674 | return ret; | ||
4675 | } | ||
4676 | EXPORT_SYMBOL_GPL(cgroup_load_subsys); | ||
4677 | |||
4678 | /** | ||
4679 | * cgroup_unload_subsys: unload a modular subsystem | ||
4680 | * @ss: the subsystem to unload | ||
4681 | * | ||
4682 | * This function should be called in a modular subsystem's exitcall. When this | ||
4683 | * function is invoked, the refcount on the subsystem's module will be 0, so | ||
4684 | * the subsystem will not be attached to any hierarchy. | ||
4685 | */ | ||
4686 | void cgroup_unload_subsys(struct cgroup_subsys *ss) | ||
4687 | { | ||
4688 | struct cgrp_cset_link *link; | ||
4689 | struct cgroup_subsys_state *css; | ||
4690 | |||
4691 | BUG_ON(ss->module == NULL); | ||
4692 | |||
4693 | /* | ||
4694 | * we shouldn't be called if the subsystem is in use, and the use of | ||
4695 | * try_module_get() in rebind_subsystems() should ensure that it | ||
4696 | * doesn't start being used while we're killing it off. | ||
4697 | */ | ||
4698 | BUG_ON(ss->root != &cgroup_dummy_root); | ||
4699 | |||
4700 | mutex_lock(&cgroup_mutex); | ||
4701 | mutex_lock(&cgroup_root_mutex); | ||
4702 | |||
4703 | css = cgroup_css(cgroup_dummy_top, ss); | ||
4704 | if (css) | ||
4705 | offline_css(css); | ||
4706 | |||
4707 | /* deassign the subsys_id */ | ||
4708 | cgroup_subsys[ss->subsys_id] = NULL; | ||
4709 | |||
4710 | /* | ||
4711 | * disentangle the css from all css_sets attached to the dummy | ||
4712 | * top. as in loading, we need to pay our respects to the hashtable | ||
4713 | * gods. | ||
4714 | */ | ||
4715 | write_lock(&css_set_lock); | ||
4716 | list_for_each_entry(link, &cgroup_dummy_top->cset_links, cset_link) { | ||
4717 | struct css_set *cset = link->cset; | ||
4718 | unsigned long key; | ||
4719 | |||
4720 | hash_del(&cset->hlist); | ||
4721 | cset->subsys[ss->subsys_id] = NULL; | ||
4722 | key = css_set_hash(cset->subsys); | ||
4723 | hash_add(css_set_table, &cset->hlist, key); | ||
4724 | } | ||
4725 | write_unlock(&css_set_lock); | ||
4726 | |||
4727 | /* | ||
4728 | * remove subsystem's css from the cgroup_dummy_top and free it - | ||
4729 | * need to free before marking as null because ss->css_free needs | ||
4730 | * the cgrp->subsys pointer to find their state. | ||
4731 | */ | ||
4732 | if (css) | ||
4733 | ss->css_free(css); | ||
4734 | RCU_INIT_POINTER(cgroup_dummy_top->subsys[ss->subsys_id], NULL); | ||
4735 | |||
4736 | mutex_unlock(&cgroup_root_mutex); | ||
4737 | mutex_unlock(&cgroup_mutex); | ||
4738 | } | ||
4739 | EXPORT_SYMBOL_GPL(cgroup_unload_subsys); | ||
4740 | |||
4741 | /** | ||
4742 | * cgroup_init_early - cgroup initialization at system boot | 4506 | * cgroup_init_early - cgroup initialization at system boot |
4743 | * | 4507 | * |
4744 | * Initialize cgroups at system boot, and initialize any | 4508 | * Initialize cgroups at system boot, and initialize any |
@@ -4763,8 +4527,7 @@ int __init cgroup_init_early(void) | |||
4763 | list_add(&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links); | 4527 | list_add(&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links); |
4764 | list_add(&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links); | 4528 | list_add(&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links); |
4765 | 4529 | ||
4766 | /* at bootup time, we don't worry about modular subsystems */ | 4530 | for_each_subsys(ss, i) { |
4767 | for_each_builtin_subsys(ss, i) { | ||
4768 | BUG_ON(!ss->name); | 4531 | BUG_ON(!ss->name); |
4769 | BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN); | 4532 | BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN); |
4770 | BUG_ON(!ss->css_alloc); | 4533 | BUG_ON(!ss->css_alloc); |
@@ -4797,7 +4560,7 @@ int __init cgroup_init(void) | |||
4797 | if (err) | 4560 | if (err) |
4798 | return err; | 4561 | return err; |
4799 | 4562 | ||
4800 | for_each_builtin_subsys(ss, i) { | 4563 | for_each_subsys(ss, i) { |
4801 | if (!ss->early_init) | 4564 | if (!ss->early_init) |
4802 | cgroup_init_subsys(ss); | 4565 | cgroup_init_subsys(ss); |
4803 | } | 4566 | } |
@@ -5032,15 +4795,7 @@ void cgroup_post_fork(struct task_struct *child) | |||
5032 | * and addition to css_set. | 4795 | * and addition to css_set. |
5033 | */ | 4796 | */ |
5034 | if (need_forkexit_callback) { | 4797 | if (need_forkexit_callback) { |
5035 | /* | 4798 | for_each_subsys(ss, i) |
5036 | * fork/exit callbacks are supported only for builtin | ||
5037 | * subsystems, and the builtin section of the subsys | ||
5038 | * array is immutable, so we don't need to lock the | ||
5039 | * subsys array here. On the other hand, modular section | ||
5040 | * of the array can be freed at module unload, so we | ||
5041 | * can't touch that. | ||
5042 | */ | ||
5043 | for_each_builtin_subsys(ss, i) | ||
5044 | if (ss->fork) | 4799 | if (ss->fork) |
5045 | ss->fork(child); | 4800 | ss->fork(child); |
5046 | } | 4801 | } |
@@ -5105,11 +4860,8 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks) | |||
5105 | RCU_INIT_POINTER(tsk->cgroups, &init_css_set); | 4860 | RCU_INIT_POINTER(tsk->cgroups, &init_css_set); |
5106 | 4861 | ||
5107 | if (run_callbacks && need_forkexit_callback) { | 4862 | if (run_callbacks && need_forkexit_callback) { |
5108 | /* | 4863 | /* see cgroup_post_fork() for details */ |
5109 | * fork/exit callbacks are supported only for builtin | 4864 | for_each_subsys(ss, i) { |
5110 | * subsystems, see cgroup_post_fork() for details. | ||
5111 | */ | ||
5112 | for_each_builtin_subsys(ss, i) { | ||
5113 | if (ss->exit) { | 4865 | if (ss->exit) { |
5114 | struct cgroup_subsys_state *old_css = cset->subsys[i]; | 4866 | struct cgroup_subsys_state *old_css = cset->subsys[i]; |
5115 | struct cgroup_subsys_state *css = task_css(tsk, i); | 4867 | struct cgroup_subsys_state *css = task_css(tsk, i); |
@@ -5228,11 +4980,7 @@ static int __init cgroup_disable(char *str) | |||
5228 | if (!*token) | 4980 | if (!*token) |
5229 | continue; | 4981 | continue; |
5230 | 4982 | ||
5231 | /* | 4983 | for_each_subsys(ss, i) { |
5232 | * cgroup_disable, being at boot time, can't know about | ||
5233 | * module subsystems, so we don't worry about them. | ||
5234 | */ | ||
5235 | for_each_builtin_subsys(ss, i) { | ||
5236 | if (!strcmp(token, ss->name)) { | 4984 | if (!strcmp(token, ss->name)) { |
5237 | ss->disabled = 1; | 4985 | ss->disabled = 1; |
5238 | printk(KERN_INFO "Disabling %s control group" | 4986 | printk(KERN_INFO "Disabling %s control group" |