diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-cgroup.c | 36 | ||||
-rw-r--r-- | block/blk-cgroup.h | 24 | ||||
-rw-r--r-- | block/cfq-iosched.c | 14 | ||||
-rw-r--r-- | block/cfq-iosched.h | 7 |
4 files changed, 69 insertions, 12 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 4d4a277b2905..3ad497f4eed6 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -15,7 +15,9 @@ | |||
15 | #include <linux/kdev_t.h> | 15 | #include <linux/kdev_t.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include "blk-cgroup.h" | 17 | #include "blk-cgroup.h" |
18 | #include "cfq-iosched.h" | 18 | |
19 | static DEFINE_SPINLOCK(blkio_list_lock); | ||
20 | static LIST_HEAD(blkio_list); | ||
19 | 21 | ||
20 | struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT }; | 22 | struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT }; |
21 | EXPORT_SYMBOL_GPL(blkio_root_cgroup); | 23 | EXPORT_SYMBOL_GPL(blkio_root_cgroup); |
@@ -138,6 +140,7 @@ blkiocg_weight_write(struct cgroup *cgroup, struct cftype *cftype, u64 val) | |||
138 | struct blkio_cgroup *blkcg; | 140 | struct blkio_cgroup *blkcg; |
139 | struct blkio_group *blkg; | 141 | struct blkio_group *blkg; |
140 | struct hlist_node *n; | 142 | struct hlist_node *n; |
143 | struct blkio_policy_type *blkiop; | ||
141 | 144 | ||
142 | if (val < BLKIO_WEIGHT_MIN || val > BLKIO_WEIGHT_MAX) | 145 | if (val < BLKIO_WEIGHT_MIN || val > BLKIO_WEIGHT_MAX) |
143 | return -EINVAL; | 146 | return -EINVAL; |
@@ -145,8 +148,13 @@ blkiocg_weight_write(struct cgroup *cgroup, struct cftype *cftype, u64 val) | |||
145 | blkcg = cgroup_to_blkio_cgroup(cgroup); | 148 | blkcg = cgroup_to_blkio_cgroup(cgroup); |
146 | spin_lock_irq(&blkcg->lock); | 149 | spin_lock_irq(&blkcg->lock); |
147 | blkcg->weight = (unsigned int)val; | 150 | blkcg->weight = (unsigned int)val; |
148 | hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) | 151 | hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) { |
149 | cfq_update_blkio_group_weight(blkg, blkcg->weight); | 152 | spin_lock(&blkio_list_lock); |
153 | list_for_each_entry(blkiop, &blkio_list, list) | ||
154 | blkiop->ops.blkio_update_group_weight_fn(blkg, | ||
155 | blkcg->weight); | ||
156 | spin_unlock(&blkio_list_lock); | ||
157 | } | ||
150 | spin_unlock_irq(&blkcg->lock); | 158 | spin_unlock_irq(&blkcg->lock); |
151 | return 0; | 159 | return 0; |
152 | } | 160 | } |
@@ -224,6 +232,7 @@ static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup) | |||
224 | unsigned long flags; | 232 | unsigned long flags; |
225 | struct blkio_group *blkg; | 233 | struct blkio_group *blkg; |
226 | void *key; | 234 | void *key; |
235 | struct blkio_policy_type *blkiop; | ||
227 | 236 | ||
228 | rcu_read_lock(); | 237 | rcu_read_lock(); |
229 | remove_entry: | 238 | remove_entry: |
@@ -249,7 +258,10 @@ remove_entry: | |||
249 | * we have more policies in place, we need some dynamic registration | 258 | * we have more policies in place, we need some dynamic registration |
250 | * of callback function. | 259 | * of callback function. |
251 | */ | 260 | */ |
252 | cfq_unlink_blkio_group(key, blkg); | 261 | spin_lock(&blkio_list_lock); |
262 | list_for_each_entry(blkiop, &blkio_list, list) | ||
263 | blkiop->ops.blkio_unlink_group_fn(key, blkg); | ||
264 | spin_unlock(&blkio_list_lock); | ||
253 | goto remove_entry; | 265 | goto remove_entry; |
254 | done: | 266 | done: |
255 | free_css_id(&blkio_subsys, &blkcg->css); | 267 | free_css_id(&blkio_subsys, &blkcg->css); |
@@ -330,3 +342,19 @@ struct cgroup_subsys blkio_subsys = { | |||
330 | .subsys_id = blkio_subsys_id, | 342 | .subsys_id = blkio_subsys_id, |
331 | .use_id = 1, | 343 | .use_id = 1, |
332 | }; | 344 | }; |
345 | |||
346 | void blkio_policy_register(struct blkio_policy_type *blkiop) | ||
347 | { | ||
348 | spin_lock(&blkio_list_lock); | ||
349 | list_add_tail(&blkiop->list, &blkio_list); | ||
350 | spin_unlock(&blkio_list_lock); | ||
351 | } | ||
352 | EXPORT_SYMBOL_GPL(blkio_policy_register); | ||
353 | |||
354 | void blkio_policy_unregister(struct blkio_policy_type *blkiop) | ||
355 | { | ||
356 | spin_lock(&blkio_list_lock); | ||
357 | list_del_init(&blkiop->list); | ||
358 | spin_unlock(&blkio_list_lock); | ||
359 | } | ||
360 | EXPORT_SYMBOL_GPL(blkio_policy_unregister); | ||
diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h index 4f89b967467f..4d316df863b4 100644 --- a/block/blk-cgroup.h +++ b/block/blk-cgroup.h | |||
@@ -46,11 +46,35 @@ struct blkio_group { | |||
46 | extern bool blkiocg_css_tryget(struct blkio_cgroup *blkcg); | 46 | extern bool blkiocg_css_tryget(struct blkio_cgroup *blkcg); |
47 | extern void blkiocg_css_put(struct blkio_cgroup *blkcg); | 47 | extern void blkiocg_css_put(struct blkio_cgroup *blkcg); |
48 | 48 | ||
49 | typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg); | ||
50 | typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg, | ||
51 | unsigned int weight); | ||
52 | |||
53 | struct blkio_policy_ops { | ||
54 | blkio_unlink_group_fn *blkio_unlink_group_fn; | ||
55 | blkio_update_group_weight_fn *blkio_update_group_weight_fn; | ||
56 | }; | ||
57 | |||
58 | struct blkio_policy_type { | ||
59 | struct list_head list; | ||
60 | struct blkio_policy_ops ops; | ||
61 | }; | ||
62 | |||
63 | /* Blkio controller policy registration */ | ||
64 | extern void blkio_policy_register(struct blkio_policy_type *); | ||
65 | extern void blkio_policy_unregister(struct blkio_policy_type *); | ||
66 | |||
49 | #else | 67 | #else |
50 | 68 | ||
51 | struct blkio_group { | 69 | struct blkio_group { |
52 | }; | 70 | }; |
53 | 71 | ||
72 | struct blkio_policy_type { | ||
73 | }; | ||
74 | |||
75 | static inline void blkio_policy_register(struct blkio_policy_type *blkiop) { } | ||
76 | static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { } | ||
77 | |||
54 | #endif | 78 | #endif |
55 | 79 | ||
56 | #define BLKIO_WEIGHT_MIN 100 | 80 | #define BLKIO_WEIGHT_MIN 100 |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 7f3f343b0c65..78f4829895bd 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/ioprio.h> | 14 | #include <linux/ioprio.h> |
15 | #include <linux/blktrace_api.h> | 15 | #include <linux/blktrace_api.h> |
16 | #include "blk-cgroup.h" | 16 | #include "blk-cgroup.h" |
17 | #include "cfq-iosched.h" | ||
18 | 17 | ||
19 | /* | 18 | /* |
20 | * tunables | 19 | * tunables |
@@ -3855,6 +3854,17 @@ static struct elevator_type iosched_cfq = { | |||
3855 | .elevator_owner = THIS_MODULE, | 3854 | .elevator_owner = THIS_MODULE, |
3856 | }; | 3855 | }; |
3857 | 3856 | ||
3857 | #ifdef CONFIG_CFQ_GROUP_IOSCHED | ||
3858 | static struct blkio_policy_type blkio_policy_cfq = { | ||
3859 | .ops = { | ||
3860 | .blkio_unlink_group_fn = cfq_unlink_blkio_group, | ||
3861 | .blkio_update_group_weight_fn = cfq_update_blkio_group_weight, | ||
3862 | }, | ||
3863 | }; | ||
3864 | #else | ||
3865 | static struct blkio_policy_type blkio_policy_cfq; | ||
3866 | #endif | ||
3867 | |||
3858 | static int __init cfq_init(void) | 3868 | static int __init cfq_init(void) |
3859 | { | 3869 | { |
3860 | /* | 3870 | /* |
@@ -3869,6 +3879,7 @@ static int __init cfq_init(void) | |||
3869 | return -ENOMEM; | 3879 | return -ENOMEM; |
3870 | 3880 | ||
3871 | elv_register(&iosched_cfq); | 3881 | elv_register(&iosched_cfq); |
3882 | blkio_policy_register(&blkio_policy_cfq); | ||
3872 | 3883 | ||
3873 | return 0; | 3884 | return 0; |
3874 | } | 3885 | } |
@@ -3876,6 +3887,7 @@ static int __init cfq_init(void) | |||
3876 | static void __exit cfq_exit(void) | 3887 | static void __exit cfq_exit(void) |
3877 | { | 3888 | { |
3878 | DECLARE_COMPLETION_ONSTACK(all_gone); | 3889 | DECLARE_COMPLETION_ONSTACK(all_gone); |
3890 | blkio_policy_unregister(&blkio_policy_cfq); | ||
3879 | elv_unregister(&iosched_cfq); | 3891 | elv_unregister(&iosched_cfq); |
3880 | ioc_gone = &all_gone; | 3892 | ioc_gone = &all_gone; |
3881 | /* ioc_gone's update must be visible before reading ioc_count */ | 3893 | /* ioc_gone's update must be visible before reading ioc_count */ |
diff --git a/block/cfq-iosched.h b/block/cfq-iosched.h deleted file mode 100644 index ef7b4798a349..000000000000 --- a/block/cfq-iosched.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef CFQ_IOSCHED_H | ||
2 | #define CFQ_IOSCHED_H | ||
3 | |||
4 | void cfq_unlink_blkio_group(void *, struct blkio_group *); | ||
5 | void cfq_update_blkio_group_weight(struct blkio_group *, unsigned int); | ||
6 | |||
7 | #endif | ||