Commit 8bd435b30ecacb69bbb8b2d3e251f770b807c5b2
Committed by
Jens Axboe
1 parent
ec399347d3
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 5 changed files with 69 additions and 41 deletions Side-by-side Diff
block/blk-cgroup.c
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | struct blkio_cgroup blkio_root_cgroup = { .cfq_weight = 2 * CFQ_WEIGHT_DEFAULT }; |
32 | 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 | 36 | struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) |
37 | 37 | { |
... | ... | @@ -67,7 +67,7 @@ |
67 | 67 | if (!blkg) |
68 | 68 | return; |
69 | 69 | |
70 | - for (i = 0; i < BLKIO_NR_POLICIES; i++) { | |
70 | + for (i = 0; i < BLKCG_MAX_POLS; i++) { | |
71 | 71 | struct blkio_policy_type *pol = blkio_policy[i]; |
72 | 72 | struct blkg_policy_data *pd = blkg->pd[i]; |
73 | 73 | |
... | ... | @@ -107,7 +107,7 @@ |
107 | 107 | blkg->refcnt = 1; |
108 | 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 | 111 | struct blkio_policy_type *pol = blkio_policy[i]; |
112 | 112 | struct blkg_policy_data *pd; |
113 | 113 | |
... | ... | @@ -127,7 +127,7 @@ |
127 | 127 | } |
128 | 128 | |
129 | 129 | /* invoke per-policy init */ |
130 | - for (i = 0; i < BLKIO_NR_POLICIES; i++) { | |
130 | + for (i = 0; i < BLKCG_MAX_POLS; i++) { | |
131 | 131 | struct blkio_policy_type *pol = blkio_policy[i]; |
132 | 132 | |
133 | 133 | if (pol) |
... | ... | @@ -320,7 +320,7 @@ |
320 | 320 | * anyway. If you get hit by a race, retry. |
321 | 321 | */ |
322 | 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 | 324 | struct blkio_policy_type *pol = blkio_policy[i]; |
325 | 325 | |
326 | 326 | if (pol && pol->ops.blkio_reset_group_stats_fn) |
327 | 327 | |
328 | 328 | |
329 | 329 | |
330 | 330 | |
331 | 331 | |
332 | 332 | |
333 | 333 | |
334 | 334 | |
335 | 335 | |
336 | 336 | |
337 | 337 | |
338 | 338 | |
... | ... | @@ -729,46 +729,75 @@ |
729 | 729 | }; |
730 | 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 | 742 | struct request_queue *q; |
743 | + int i, ret; | |
735 | 744 | |
736 | 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]); | |
741 | - blkio_policy[blkiop->plid] = blkiop; | |
755 | + /* register and update blkgs */ | |
756 | + blkiop->plid = i; | |
757 | + blkio_policy[i] = blkiop; | |
758 | + | |
759 | + blkcg_bypass_start(); | |
742 | 760 | list_for_each_entry(q, &all_q_list, all_q_node) |
743 | 761 | update_root_blkg_pd(q, blkiop); |
744 | - | |
745 | 762 | blkcg_bypass_end(); |
746 | 763 | |
764 | + /* everything is in place, add intf files for the new policy */ | |
747 | 765 | if (blkiop->cftypes) |
748 | 766 | WARN_ON(cgroup_add_cftypes(&blkio_subsys, blkiop->cftypes)); |
749 | - | |
767 | + ret = 0; | |
768 | +out_unlock: | |
750 | 769 | mutex_unlock(&blkcg_pol_mutex); |
770 | + return ret; | |
751 | 771 | } |
752 | 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 | 780 | void blkio_policy_unregister(struct blkio_policy_type *blkiop) |
755 | 781 | { |
756 | 782 | struct request_queue *q; |
757 | 783 | |
758 | 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 | 790 | if (blkiop->cftypes) |
761 | 791 | cgroup_rm_cftypes(&blkio_subsys, blkiop->cftypes); |
762 | 792 | |
763 | - blkcg_bypass_start(); | |
764 | - | |
765 | - BUG_ON(blkio_policy[blkiop->plid] != blkiop); | |
793 | + /* unregister and update blkgs */ | |
766 | 794 | blkio_policy[blkiop->plid] = NULL; |
767 | 795 | |
796 | + blkcg_bypass_start(); | |
768 | 797 | list_for_each_entry(q, &all_q_list, all_q_node) |
769 | 798 | update_root_blkg_pd(q, blkiop); |
770 | 799 | blkcg_bypass_end(); |
771 | - | |
800 | +out_unlock: | |
772 | 801 | mutex_unlock(&blkcg_pol_mutex); |
773 | 802 | } |
774 | 803 | EXPORT_SYMBOL_GPL(blkio_policy_unregister); |
block/blk-cgroup.h
... | ... | @@ -17,13 +17,6 @@ |
17 | 17 | #include <linux/u64_stats_sync.h> |
18 | 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 | 20 | /* Max limits for throttle policy */ |
28 | 21 | #define THROTL_IOPS_MAX UINT_MAX |
29 | 22 | |
... | ... | @@ -86,7 +79,7 @@ |
86 | 79 | /* reference count */ |
87 | 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 | 84 | struct rcu_head rcu_head; |
92 | 85 | }; |
... | ... | @@ -103,7 +96,7 @@ |
103 | 96 | |
104 | 97 | struct blkio_policy_type { |
105 | 98 | struct blkio_policy_ops ops; |
106 | - enum blkio_policy_id plid; | |
99 | + int plid; | |
107 | 100 | size_t pdata_size; /* policy specific private data size */ |
108 | 101 | struct cftype *cftypes; /* cgroup files for the policy */ |
109 | 102 | }; |
... | ... | @@ -113,7 +106,7 @@ |
113 | 106 | extern void blkcg_exit_queue(struct request_queue *q); |
114 | 107 | |
115 | 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 | 110 | extern void blkio_policy_unregister(struct blkio_policy_type *); |
118 | 111 | extern void blkg_destroy_all(struct request_queue *q, bool destroy_root); |
119 | 112 | extern void update_root_blkg_pd(struct request_queue *q, |
... | ... | @@ -329,7 +322,7 @@ |
329 | 322 | static inline int blkcg_init_queue(struct request_queue *q) { return 0; } |
330 | 323 | static inline void blkcg_drain_queue(struct request_queue *q) { } |
331 | 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 | 326 | static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { } |
334 | 327 | static inline void blkg_destroy_all(struct request_queue *q, |
335 | 328 | bool destory_root) { } |
block/blk-throttle.c
... | ... | @@ -1089,7 +1089,6 @@ |
1089 | 1089 | .blkio_exit_group_fn = throtl_exit_blkio_group, |
1090 | 1090 | .blkio_reset_group_stats_fn = throtl_reset_group_stats, |
1091 | 1091 | }, |
1092 | - .plid = BLKIO_POLICY_THROTL, | |
1093 | 1092 | .pdata_size = sizeof(struct throtl_grp), |
1094 | 1093 | .cftypes = throtl_files, |
1095 | 1094 | }; |
... | ... | @@ -1271,8 +1270,7 @@ |
1271 | 1270 | if (!kthrotld_workqueue) |
1272 | 1271 | panic("Failed to create kthrotld\n"); |
1273 | 1272 | |
1274 | - blkio_policy_register(&blkio_policy_throtl); | |
1275 | - return 0; | |
1273 | + return blkio_policy_register(&blkio_policy_throtl); | |
1276 | 1274 | } |
1277 | 1275 | |
1278 | 1276 | module_init(throtl_init); |
block/cfq-iosched.c
... | ... | @@ -4157,7 +4157,6 @@ |
4157 | 4157 | .blkio_init_group_fn = cfq_init_blkio_group, |
4158 | 4158 | .blkio_reset_group_stats_fn = cfqg_stats_reset, |
4159 | 4159 | }, |
4160 | - .plid = BLKIO_POLICY_PROP, | |
4161 | 4160 | .pdata_size = sizeof(struct cfq_group), |
4162 | 4161 | .cftypes = cfq_blkcg_files, |
4163 | 4162 | }; |
4164 | 4163 | |
4165 | 4164 | |
4166 | 4165 | |
4167 | 4166 | |
4168 | 4167 | |
4169 | 4168 | |
... | ... | @@ -4181,27 +4180,31 @@ |
4181 | 4180 | #else |
4182 | 4181 | cfq_group_idle = 0; |
4183 | 4182 | #endif |
4183 | + | |
4184 | + ret = blkio_policy_register(&blkio_policy_cfq); | |
4185 | + if (ret) | |
4186 | + return ret; | |
4187 | + | |
4184 | 4188 | cfq_pool = KMEM_CACHE(cfq_queue, 0); |
4185 | 4189 | if (!cfq_pool) |
4186 | - return -ENOMEM; | |
4190 | + goto err_pol_unreg; | |
4187 | 4191 | |
4188 | 4192 | ret = elv_register(&iosched_cfq); |
4189 | - if (ret) { | |
4190 | - kmem_cache_destroy(cfq_pool); | |
4191 | - return ret; | |
4192 | - } | |
4193 | + if (ret) | |
4194 | + goto err_free_pool; | |
4193 | 4195 | |
4194 | -#ifdef CONFIG_CFQ_GROUP_IOSCHED | |
4195 | - blkio_policy_register(&blkio_policy_cfq); | |
4196 | -#endif | |
4197 | 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 | 4205 | static void __exit cfq_exit(void) |
4201 | 4206 | { |
4202 | -#ifdef CONFIG_CFQ_GROUP_IOSCHED | |
4203 | 4207 | blkio_policy_unregister(&blkio_policy_cfq); |
4204 | -#endif | |
4205 | 4208 | elv_unregister(&iosched_cfq); |
4206 | 4209 | kmem_cache_destroy(cfq_pool); |
4207 | 4210 | } |
include/linux/blkdev.h
... | ... | @@ -35,6 +35,12 @@ |
35 | 35 | #define BLKDEV_MIN_RQ 4 |
36 | 36 | #define BLKDEV_MAX_RQ 128 /* Default maximum */ |
37 | 37 | |
38 | +/* | |
39 | + * Maximum number of blkcg policies allowed to be registered concurrently. | |
40 | + * Defined here to simplify include dependency. | |
41 | + */ | |
42 | +#define BLKCG_MAX_POLS 2 | |
43 | + | |
38 | 44 | struct request; |
39 | 45 | typedef void (rq_end_io_fn)(struct request *, int); |
40 | 46 | |
... | ... | @@ -363,7 +369,6 @@ |
363 | 369 | |
364 | 370 | struct list_head icq_list; |
365 | 371 | #ifdef CONFIG_BLK_CGROUP |
366 | - /* XXX: array size hardcoded to avoid include dependency (temporary) */ | |
367 | 372 | struct list_head blkg_list; |
368 | 373 | #endif |
369 | 374 |