diff options
author | Tejun Heo <tj@kernel.org> | 2012-04-13 16:11:28 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-04-20 04:06:06 -0400 |
commit | 8bd435b30ecacb69bbb8b2d3e251f770b807c5b2 (patch) | |
tree | a1a50e95517a54a578af3967fb4016a5a1a42a68 /block | |
parent | ec399347d39fb2337ebace928cf4a2855bd0ec37 (diff) |
blkcg: remove static policy ID enums
Remove BLKIO_POLICY_* enums and let blkio_policy_register() allocate
@pol->plid dynamically on registration. The maximum number of blkcg
policies which can be registered at the same time is defined by
BLKCG_MAX_POLS constant added to include/linux/blkdev.h.
Note that blkio_policy_register() now may fail. Policy init functions
updated accordingly and unnecessary ifdefs removed from cfq_init().
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-cgroup.c | 59 | ||||
-rw-r--r-- | block/blk-cgroup.h | 15 | ||||
-rw-r--r-- | block/blk-throttle.c | 4 | ||||
-rw-r--r-- | block/cfq-iosched.c | 25 |
4 files changed, 63 insertions, 40 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index b1231524a097..2d4d7d6d9ae9 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -31,7 +31,7 @@ static LIST_HEAD(all_q_list); | |||
31 | struct blkio_cgroup blkio_root_cgroup = { .cfq_weight = 2 * CFQ_WEIGHT_DEFAULT }; | 31 | struct blkio_cgroup blkio_root_cgroup = { .cfq_weight = 2 * CFQ_WEIGHT_DEFAULT }; |
32 | EXPORT_SYMBOL_GPL(blkio_root_cgroup); | 32 | EXPORT_SYMBOL_GPL(blkio_root_cgroup); |
33 | 33 | ||
34 | static struct blkio_policy_type *blkio_policy[BLKIO_NR_POLICIES]; | 34 | static struct blkio_policy_type *blkio_policy[BLKCG_MAX_POLS]; |
35 | 35 | ||
36 | struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) | 36 | struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) |
37 | { | 37 | { |
@@ -67,7 +67,7 @@ static void blkg_free(struct blkio_group *blkg) | |||
67 | if (!blkg) | 67 | if (!blkg) |
68 | return; | 68 | return; |
69 | 69 | ||
70 | for (i = 0; i < BLKIO_NR_POLICIES; i++) { | 70 | for (i = 0; i < BLKCG_MAX_POLS; i++) { |
71 | struct blkio_policy_type *pol = blkio_policy[i]; | 71 | struct blkio_policy_type *pol = blkio_policy[i]; |
72 | struct blkg_policy_data *pd = blkg->pd[i]; | 72 | struct blkg_policy_data *pd = blkg->pd[i]; |
73 | 73 | ||
@@ -107,7 +107,7 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg, | |||
107 | blkg->refcnt = 1; | 107 | blkg->refcnt = 1; |
108 | cgroup_path(blkcg->css.cgroup, blkg->path, sizeof(blkg->path)); | 108 | cgroup_path(blkcg->css.cgroup, blkg->path, sizeof(blkg->path)); |
109 | 109 | ||
110 | for (i = 0; i < BLKIO_NR_POLICIES; i++) { | 110 | for (i = 0; i < BLKCG_MAX_POLS; i++) { |
111 | struct blkio_policy_type *pol = blkio_policy[i]; | 111 | struct blkio_policy_type *pol = blkio_policy[i]; |
112 | struct blkg_policy_data *pd; | 112 | struct blkg_policy_data *pd; |
113 | 113 | ||
@@ -127,7 +127,7 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg, | |||
127 | } | 127 | } |
128 | 128 | ||
129 | /* invoke per-policy init */ | 129 | /* invoke per-policy init */ |
130 | for (i = 0; i < BLKIO_NR_POLICIES; i++) { | 130 | for (i = 0; i < BLKCG_MAX_POLS; i++) { |
131 | struct blkio_policy_type *pol = blkio_policy[i]; | 131 | struct blkio_policy_type *pol = blkio_policy[i]; |
132 | 132 | ||
133 | if (pol) | 133 | if (pol) |
@@ -320,7 +320,7 @@ blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val) | |||
320 | * anyway. If you get hit by a race, retry. | 320 | * anyway. If you get hit by a race, retry. |
321 | */ | 321 | */ |
322 | hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) { | 322 | hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) { |
323 | for (i = 0; i < BLKIO_NR_POLICIES; i++) { | 323 | for (i = 0; i < BLKCG_MAX_POLS; i++) { |
324 | struct blkio_policy_type *pol = blkio_policy[i]; | 324 | struct blkio_policy_type *pol = blkio_policy[i]; |
325 | 325 | ||
326 | if (pol && pol->ops.blkio_reset_group_stats_fn) | 326 | if (pol && pol->ops.blkio_reset_group_stats_fn) |
@@ -729,46 +729,75 @@ struct cgroup_subsys blkio_subsys = { | |||
729 | }; | 729 | }; |
730 | EXPORT_SYMBOL_GPL(blkio_subsys); | 730 | EXPORT_SYMBOL_GPL(blkio_subsys); |
731 | 731 | ||
732 | void blkio_policy_register(struct blkio_policy_type *blkiop) | 732 | /** |
733 | * blkio_policy_register - register a blkcg policy | ||
734 | * @blkiop: blkcg policy to register | ||
735 | * | ||
736 | * Register @blkiop with blkcg core. Might sleep and @blkiop may be | ||
737 | * modified on successful registration. Returns 0 on success and -errno on | ||
738 | * failure. | ||
739 | */ | ||
740 | int blkio_policy_register(struct blkio_policy_type *blkiop) | ||
733 | { | 741 | { |
734 | struct request_queue *q; | 742 | struct request_queue *q; |
743 | int i, ret; | ||
735 | 744 | ||
736 | mutex_lock(&blkcg_pol_mutex); | 745 | mutex_lock(&blkcg_pol_mutex); |
737 | 746 | ||
738 | blkcg_bypass_start(); | 747 | /* find an empty slot */ |
748 | ret = -ENOSPC; | ||
749 | for (i = 0; i < BLKCG_MAX_POLS; i++) | ||
750 | if (!blkio_policy[i]) | ||
751 | break; | ||
752 | if (i >= BLKCG_MAX_POLS) | ||
753 | goto out_unlock; | ||
739 | 754 | ||
740 | BUG_ON(blkio_policy[blkiop->plid]); | 755 | /* register and update blkgs */ |
741 | blkio_policy[blkiop->plid] = blkiop; | 756 | blkiop->plid = i; |
757 | blkio_policy[i] = blkiop; | ||
758 | |||
759 | blkcg_bypass_start(); | ||
742 | list_for_each_entry(q, &all_q_list, all_q_node) | 760 | list_for_each_entry(q, &all_q_list, all_q_node) |
743 | update_root_blkg_pd(q, blkiop); | 761 | update_root_blkg_pd(q, blkiop); |
744 | |||
745 | blkcg_bypass_end(); | 762 | blkcg_bypass_end(); |
746 | 763 | ||
764 | /* everything is in place, add intf files for the new policy */ | ||
747 | if (blkiop->cftypes) | 765 | if (blkiop->cftypes) |
748 | WARN_ON(cgroup_add_cftypes(&blkio_subsys, blkiop->cftypes)); | 766 | WARN_ON(cgroup_add_cftypes(&blkio_subsys, blkiop->cftypes)); |
749 | 767 | ret = 0; | |
768 | out_unlock: | ||
750 | mutex_unlock(&blkcg_pol_mutex); | 769 | mutex_unlock(&blkcg_pol_mutex); |
770 | return ret; | ||
751 | } | 771 | } |
752 | EXPORT_SYMBOL_GPL(blkio_policy_register); | 772 | EXPORT_SYMBOL_GPL(blkio_policy_register); |
753 | 773 | ||
774 | /** | ||
775 | * blkiop_policy_unregister - unregister a blkcg policy | ||
776 | * @blkiop: blkcg policy to unregister | ||
777 | * | ||
778 | * Undo blkio_policy_register(@blkiop). Might sleep. | ||
779 | */ | ||
754 | void blkio_policy_unregister(struct blkio_policy_type *blkiop) | 780 | void blkio_policy_unregister(struct blkio_policy_type *blkiop) |
755 | { | 781 | { |
756 | struct request_queue *q; | 782 | struct request_queue *q; |
757 | 783 | ||
758 | mutex_lock(&blkcg_pol_mutex); | 784 | mutex_lock(&blkcg_pol_mutex); |
759 | 785 | ||
786 | if (WARN_ON(blkio_policy[blkiop->plid] != blkiop)) | ||
787 | goto out_unlock; | ||
788 | |||
789 | /* kill the intf files first */ | ||
760 | if (blkiop->cftypes) | 790 | if (blkiop->cftypes) |
761 | cgroup_rm_cftypes(&blkio_subsys, blkiop->cftypes); | 791 | cgroup_rm_cftypes(&blkio_subsys, blkiop->cftypes); |
762 | 792 | ||
763 | blkcg_bypass_start(); | 793 | /* unregister and update blkgs */ |
764 | |||
765 | BUG_ON(blkio_policy[blkiop->plid] != blkiop); | ||
766 | blkio_policy[blkiop->plid] = NULL; | 794 | blkio_policy[blkiop->plid] = NULL; |
767 | 795 | ||
796 | blkcg_bypass_start(); | ||
768 | list_for_each_entry(q, &all_q_list, all_q_node) | 797 | list_for_each_entry(q, &all_q_list, all_q_node) |
769 | update_root_blkg_pd(q, blkiop); | 798 | update_root_blkg_pd(q, blkiop); |
770 | blkcg_bypass_end(); | 799 | blkcg_bypass_end(); |
771 | 800 | out_unlock: | |
772 | mutex_unlock(&blkcg_pol_mutex); | 801 | mutex_unlock(&blkcg_pol_mutex); |
773 | } | 802 | } |
774 | EXPORT_SYMBOL_GPL(blkio_policy_unregister); | 803 | EXPORT_SYMBOL_GPL(blkio_policy_unregister); |
diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h index 26949731108f..be80d6eb6531 100644 --- a/block/blk-cgroup.h +++ b/block/blk-cgroup.h | |||
@@ -17,13 +17,6 @@ | |||
17 | #include <linux/u64_stats_sync.h> | 17 | #include <linux/u64_stats_sync.h> |
18 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
19 | 19 | ||
20 | enum blkio_policy_id { | ||
21 | BLKIO_POLICY_PROP = 0, /* Proportional Bandwidth division */ | ||
22 | BLKIO_POLICY_THROTL, /* Throttling */ | ||
23 | |||
24 | BLKIO_NR_POLICIES, | ||
25 | }; | ||
26 | |||
27 | /* Max limits for throttle policy */ | 20 | /* Max limits for throttle policy */ |
28 | #define THROTL_IOPS_MAX UINT_MAX | 21 | #define THROTL_IOPS_MAX UINT_MAX |
29 | 22 | ||
@@ -86,7 +79,7 @@ struct blkio_group { | |||
86 | /* reference count */ | 79 | /* reference count */ |
87 | int refcnt; | 80 | int refcnt; |
88 | 81 | ||
89 | struct blkg_policy_data *pd[BLKIO_NR_POLICIES]; | 82 | struct blkg_policy_data *pd[BLKCG_MAX_POLS]; |
90 | 83 | ||
91 | struct rcu_head rcu_head; | 84 | struct rcu_head rcu_head; |
92 | }; | 85 | }; |
@@ -103,7 +96,7 @@ struct blkio_policy_ops { | |||
103 | 96 | ||
104 | struct blkio_policy_type { | 97 | struct blkio_policy_type { |
105 | struct blkio_policy_ops ops; | 98 | struct blkio_policy_ops ops; |
106 | enum blkio_policy_id plid; | 99 | int plid; |
107 | size_t pdata_size; /* policy specific private data size */ | 100 | size_t pdata_size; /* policy specific private data size */ |
108 | struct cftype *cftypes; /* cgroup files for the policy */ | 101 | struct cftype *cftypes; /* cgroup files for the policy */ |
109 | }; | 102 | }; |
@@ -113,7 +106,7 @@ extern void blkcg_drain_queue(struct request_queue *q); | |||
113 | extern void blkcg_exit_queue(struct request_queue *q); | 106 | extern void blkcg_exit_queue(struct request_queue *q); |
114 | 107 | ||
115 | /* Blkio controller policy registration */ | 108 | /* Blkio controller policy registration */ |
116 | extern void blkio_policy_register(struct blkio_policy_type *); | 109 | extern int blkio_policy_register(struct blkio_policy_type *); |
117 | extern void blkio_policy_unregister(struct blkio_policy_type *); | 110 | extern void blkio_policy_unregister(struct blkio_policy_type *); |
118 | extern void blkg_destroy_all(struct request_queue *q, bool destroy_root); | 111 | extern void blkg_destroy_all(struct request_queue *q, bool destroy_root); |
119 | extern void update_root_blkg_pd(struct request_queue *q, | 112 | extern void update_root_blkg_pd(struct request_queue *q, |
@@ -329,7 +322,7 @@ struct blkio_policy_type { | |||
329 | static inline int blkcg_init_queue(struct request_queue *q) { return 0; } | 322 | static inline int blkcg_init_queue(struct request_queue *q) { return 0; } |
330 | static inline void blkcg_drain_queue(struct request_queue *q) { } | 323 | static inline void blkcg_drain_queue(struct request_queue *q) { } |
331 | static inline void blkcg_exit_queue(struct request_queue *q) { } | 324 | static inline void blkcg_exit_queue(struct request_queue *q) { } |
332 | static inline void blkio_policy_register(struct blkio_policy_type *blkiop) { } | 325 | static inline int blkio_policy_register(struct blkio_policy_type *blkiop) { return 0; } |
333 | static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { } | 326 | static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { } |
334 | static inline void blkg_destroy_all(struct request_queue *q, | 327 | static inline void blkg_destroy_all(struct request_queue *q, |
335 | bool destory_root) { } | 328 | bool destory_root) { } |
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 07c17c27a628..0dc4645aa7fe 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c | |||
@@ -1089,7 +1089,6 @@ static struct blkio_policy_type blkio_policy_throtl = { | |||
1089 | .blkio_exit_group_fn = throtl_exit_blkio_group, | 1089 | .blkio_exit_group_fn = throtl_exit_blkio_group, |
1090 | .blkio_reset_group_stats_fn = throtl_reset_group_stats, | 1090 | .blkio_reset_group_stats_fn = throtl_reset_group_stats, |
1091 | }, | 1091 | }, |
1092 | .plid = BLKIO_POLICY_THROTL, | ||
1093 | .pdata_size = sizeof(struct throtl_grp), | 1092 | .pdata_size = sizeof(struct throtl_grp), |
1094 | .cftypes = throtl_files, | 1093 | .cftypes = throtl_files, |
1095 | }; | 1094 | }; |
@@ -1271,8 +1270,7 @@ static int __init throtl_init(void) | |||
1271 | if (!kthrotld_workqueue) | 1270 | if (!kthrotld_workqueue) |
1272 | panic("Failed to create kthrotld\n"); | 1271 | panic("Failed to create kthrotld\n"); |
1273 | 1272 | ||
1274 | blkio_policy_register(&blkio_policy_throtl); | 1273 | return blkio_policy_register(&blkio_policy_throtl); |
1275 | return 0; | ||
1276 | } | 1274 | } |
1277 | 1275 | ||
1278 | module_init(throtl_init); | 1276 | module_init(throtl_init); |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index d02f0ae9637f..08db2fc70c29 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -4157,7 +4157,6 @@ static struct blkio_policy_type blkio_policy_cfq = { | |||
4157 | .blkio_init_group_fn = cfq_init_blkio_group, | 4157 | .blkio_init_group_fn = cfq_init_blkio_group, |
4158 | .blkio_reset_group_stats_fn = cfqg_stats_reset, | 4158 | .blkio_reset_group_stats_fn = cfqg_stats_reset, |
4159 | }, | 4159 | }, |
4160 | .plid = BLKIO_POLICY_PROP, | ||
4161 | .pdata_size = sizeof(struct cfq_group), | 4160 | .pdata_size = sizeof(struct cfq_group), |
4162 | .cftypes = cfq_blkcg_files, | 4161 | .cftypes = cfq_blkcg_files, |
4163 | }; | 4162 | }; |
@@ -4181,27 +4180,31 @@ static int __init cfq_init(void) | |||
4181 | #else | 4180 | #else |
4182 | cfq_group_idle = 0; | 4181 | cfq_group_idle = 0; |
4183 | #endif | 4182 | #endif |
4183 | |||
4184 | ret = blkio_policy_register(&blkio_policy_cfq); | ||
4185 | if (ret) | ||
4186 | return ret; | ||
4187 | |||
4184 | cfq_pool = KMEM_CACHE(cfq_queue, 0); | 4188 | cfq_pool = KMEM_CACHE(cfq_queue, 0); |
4185 | if (!cfq_pool) | 4189 | if (!cfq_pool) |
4186 | return -ENOMEM; | 4190 | goto err_pol_unreg; |
4187 | 4191 | ||
4188 | ret = elv_register(&iosched_cfq); | 4192 | ret = elv_register(&iosched_cfq); |
4189 | if (ret) { | 4193 | if (ret) |
4190 | kmem_cache_destroy(cfq_pool); | 4194 | goto err_free_pool; |
4191 | return ret; | ||
4192 | } | ||
4193 | 4195 | ||
4194 | #ifdef CONFIG_CFQ_GROUP_IOSCHED | ||
4195 | blkio_policy_register(&blkio_policy_cfq); | ||
4196 | #endif | ||
4197 | return 0; | 4196 | return 0; |
4197 | |||
4198 | err_free_pool: | ||
4199 | kmem_cache_destroy(cfq_pool); | ||
4200 | err_pol_unreg: | ||
4201 | blkio_policy_unregister(&blkio_policy_cfq); | ||
4202 | return ret; | ||
4198 | } | 4203 | } |
4199 | 4204 | ||
4200 | static void __exit cfq_exit(void) | 4205 | static void __exit cfq_exit(void) |
4201 | { | 4206 | { |
4202 | #ifdef CONFIG_CFQ_GROUP_IOSCHED | ||
4203 | blkio_policy_unregister(&blkio_policy_cfq); | 4207 | blkio_policy_unregister(&blkio_policy_cfq); |
4204 | #endif | ||
4205 | elv_unregister(&iosched_cfq); | 4208 | elv_unregister(&iosched_cfq); |
4206 | kmem_cache_destroy(cfq_pool); | 4209 | kmem_cache_destroy(cfq_pool); |
4207 | } | 4210 | } |