diff options
-rw-r--r-- | block/blk-cgroup.c | 1 | ||||
-rw-r--r-- | include/linux/cgroup.h | 29 | ||||
-rw-r--r-- | include/linux/cgroup_subsys.h | 24 | ||||
-rw-r--r-- | kernel/cgroup.c | 284 | ||||
-rw-r--r-- | net/core/netclassid_cgroup.c | 1 | ||||
-rw-r--r-- | net/core/netprio_cgroup.c | 1 |
6 files changed, 32 insertions, 308 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 4e491d9b5292..660d419918a7 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -914,7 +914,6 @@ struct cgroup_subsys blkio_subsys = { | |||
914 | .can_attach = blkcg_can_attach, | 914 | .can_attach = blkcg_can_attach, |
915 | .subsys_id = blkio_subsys_id, | 915 | .subsys_id = blkio_subsys_id, |
916 | .base_cftypes = blkcg_files, | 916 | .base_cftypes = blkcg_files, |
917 | .module = THIS_MODULE, | ||
918 | }; | 917 | }; |
919 | EXPORT_SYMBOL_GPL(blkio_subsys); | 918 | EXPORT_SYMBOL_GPL(blkio_subsys); |
920 | 919 | ||
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 5c097596104b..d842a737d448 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -37,28 +37,13 @@ extern void cgroup_post_fork(struct task_struct *p); | |||
37 | extern void cgroup_exit(struct task_struct *p, int run_callbacks); | 37 | extern void cgroup_exit(struct task_struct *p, int run_callbacks); |
38 | extern int cgroupstats_build(struct cgroupstats *stats, | 38 | extern int cgroupstats_build(struct cgroupstats *stats, |
39 | struct dentry *dentry); | 39 | struct dentry *dentry); |
40 | extern int cgroup_load_subsys(struct cgroup_subsys *ss); | ||
41 | extern void cgroup_unload_subsys(struct cgroup_subsys *ss); | ||
42 | 40 | ||
43 | extern int proc_cgroup_show(struct seq_file *, void *); | 41 | extern int proc_cgroup_show(struct seq_file *, void *); |
44 | 42 | ||
45 | /* | 43 | /* define the enumeration of all cgroup subsystems */ |
46 | * Define the enumeration of all cgroup subsystems. | ||
47 | * | ||
48 | * We define ids for builtin subsystems and then modular ones. | ||
49 | */ | ||
50 | #define SUBSYS(_x) _x ## _subsys_id, | 44 | #define SUBSYS(_x) _x ## _subsys_id, |
51 | enum cgroup_subsys_id { | 45 | enum cgroup_subsys_id { |
52 | #define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option) | ||
53 | #include <linux/cgroup_subsys.h> | 46 | #include <linux/cgroup_subsys.h> |
54 | #undef IS_SUBSYS_ENABLED | ||
55 | CGROUP_BUILTIN_SUBSYS_COUNT, | ||
56 | |||
57 | __CGROUP_SUBSYS_TEMP_PLACEHOLDER = CGROUP_BUILTIN_SUBSYS_COUNT - 1, | ||
58 | |||
59 | #define IS_SUBSYS_ENABLED(option) IS_MODULE(option) | ||
60 | #include <linux/cgroup_subsys.h> | ||
61 | #undef IS_SUBSYS_ENABLED | ||
62 | CGROUP_SUBSYS_COUNT, | 47 | CGROUP_SUBSYS_COUNT, |
63 | }; | 48 | }; |
64 | #undef SUBSYS | 49 | #undef SUBSYS |
@@ -370,10 +355,9 @@ struct css_set { | |||
370 | struct list_head cgrp_links; | 355 | struct list_head cgrp_links; |
371 | 356 | ||
372 | /* | 357 | /* |
373 | * Set of subsystem states, one for each subsystem. This array | 358 | * Set of subsystem states, one for each subsystem. This array is |
374 | * is immutable after creation apart from the init_css_set | 359 | * immutable after creation apart from the init_css_set during |
375 | * during subsystem registration (at boot time) and modular subsystem | 360 | * subsystem registration (at boot time). |
376 | * loading/unloading. | ||
377 | */ | 361 | */ |
378 | struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; | 362 | struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; |
379 | 363 | ||
@@ -620,15 +604,10 @@ struct cgroup_subsys { | |||
620 | /* base cftypes, automatically [de]registered with subsys itself */ | 604 | /* base cftypes, automatically [de]registered with subsys itself */ |
621 | struct cftype *base_cftypes; | 605 | struct cftype *base_cftypes; |
622 | struct cftype_set base_cftset; | 606 | struct cftype_set base_cftset; |
623 | |||
624 | /* should be defined only by modular subsystems */ | ||
625 | struct module *module; | ||
626 | }; | 607 | }; |
627 | 608 | ||
628 | #define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys; | 609 | #define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys; |
629 | #define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option) | ||
630 | #include <linux/cgroup_subsys.h> | 610 | #include <linux/cgroup_subsys.h> |
631 | #undef IS_SUBSYS_ENABLED | ||
632 | #undef SUBSYS | 611 | #undef SUBSYS |
633 | 612 | ||
634 | /** | 613 | /** |
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index 7b99d717411d..11c42f6a25a8 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h | |||
@@ -3,51 +3,51 @@ | |||
3 | * | 3 | * |
4 | * DO NOT ADD ANY SUBSYSTEM WITHOUT EXPLICIT ACKS FROM CGROUP MAINTAINERS. | 4 | * DO NOT ADD ANY SUBSYSTEM WITHOUT EXPLICIT ACKS FROM CGROUP MAINTAINERS. |
5 | */ | 5 | */ |
6 | #if IS_SUBSYS_ENABLED(CONFIG_CPUSETS) | 6 | #if IS_ENABLED(CONFIG_CPUSETS) |
7 | SUBSYS(cpuset) | 7 | SUBSYS(cpuset) |
8 | #endif | 8 | #endif |
9 | 9 | ||
10 | #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_DEBUG) | 10 | #if IS_ENABLED(CONFIG_CGROUP_DEBUG) |
11 | SUBSYS(debug) | 11 | SUBSYS(debug) |
12 | #endif | 12 | #endif |
13 | 13 | ||
14 | #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_SCHED) | 14 | #if IS_ENABLED(CONFIG_CGROUP_SCHED) |
15 | SUBSYS(cpu_cgroup) | 15 | SUBSYS(cpu_cgroup) |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_CPUACCT) | 18 | #if IS_ENABLED(CONFIG_CGROUP_CPUACCT) |
19 | SUBSYS(cpuacct) | 19 | SUBSYS(cpuacct) |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #if IS_SUBSYS_ENABLED(CONFIG_MEMCG) | 22 | #if IS_ENABLED(CONFIG_MEMCG) |
23 | SUBSYS(mem_cgroup) | 23 | SUBSYS(mem_cgroup) |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_DEVICE) | 26 | #if IS_ENABLED(CONFIG_CGROUP_DEVICE) |
27 | SUBSYS(devices) | 27 | SUBSYS(devices) |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_FREEZER) | 30 | #if IS_ENABLED(CONFIG_CGROUP_FREEZER) |
31 | SUBSYS(freezer) | 31 | SUBSYS(freezer) |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_NET_CLASSID) | 34 | #if IS_ENABLED(CONFIG_CGROUP_NET_CLASSID) |
35 | SUBSYS(net_cls) | 35 | SUBSYS(net_cls) |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #if IS_SUBSYS_ENABLED(CONFIG_BLK_CGROUP) | 38 | #if IS_ENABLED(CONFIG_BLK_CGROUP) |
39 | SUBSYS(blkio) | 39 | SUBSYS(blkio) |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_PERF) | 42 | #if IS_ENABLED(CONFIG_CGROUP_PERF) |
43 | SUBSYS(perf) | 43 | SUBSYS(perf) |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_NET_PRIO) | 46 | #if IS_ENABLED(CONFIG_CGROUP_NET_PRIO) |
47 | SUBSYS(net_prio) | 47 | SUBSYS(net_prio) |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_HUGETLB) | 50 | #if IS_ENABLED(CONFIG_CGROUP_HUGETLB) |
51 | SUBSYS(hugetlb) | 51 | SUBSYS(hugetlb) |
52 | #endif | 52 | #endif |
53 | /* | 53 | /* |
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" |
diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c index 9fc7f90d034c..9e5ad5d74e60 100644 --- a/net/core/netclassid_cgroup.c +++ b/net/core/netclassid_cgroup.c | |||
@@ -110,5 +110,4 @@ struct cgroup_subsys net_cls_subsys = { | |||
110 | .attach = cgrp_attach, | 110 | .attach = cgrp_attach, |
111 | .subsys_id = net_cls_subsys_id, | 111 | .subsys_id = net_cls_subsys_id, |
112 | .base_cftypes = ss_files, | 112 | .base_cftypes = ss_files, |
113 | .module = THIS_MODULE, | ||
114 | }; | 113 | }; |
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index cc3a31e7dc08..857e1603f9b7 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
@@ -252,7 +252,6 @@ struct cgroup_subsys net_prio_subsys = { | |||
252 | .attach = net_prio_attach, | 252 | .attach = net_prio_attach, |
253 | .subsys_id = net_prio_subsys_id, | 253 | .subsys_id = net_prio_subsys_id, |
254 | .base_cftypes = ss_files, | 254 | .base_cftypes = ss_files, |
255 | .module = THIS_MODULE, | ||
256 | }; | 255 | }; |
257 | 256 | ||
258 | static int netprio_device_event(struct notifier_block *unused, | 257 | static int netprio_device_event(struct notifier_block *unused, |