aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2009-12-04 10:36:42 -0500
committerJens Axboe <jens.axboe@oracle.com>2009-12-04 10:38:14 -0500
commit3e2520668970aab5a764044a298e987aafc1f63d (patch)
tree088ebf7c4576d597774c8c332bab590dc3a472d6 /block
parent9d6a986c0b276085f7944cd8ad65f4f82aff7536 (diff)
blkio: Implement dynamic io controlling policy registration
o One of the goals of block IO controller is that it should be able to support mulitple io control policies, some of which be operational at higher level in storage hierarchy. o To begin with, we had one io controlling policy implemented by CFQ, and I hard coded the CFQ functions called by blkio. This created issues when CFQ is compiled as module. o This patch implements a basic dynamic io controlling policy registration functionality in blkio. This is similar to elevator functionality where ioschedulers register the functions dynamically. o Now in future, when more IO controlling policies are implemented, these can dynakically register with block IO controller. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block')
-rw-r--r--block/blk-cgroup.c36
-rw-r--r--block/blk-cgroup.h24
-rw-r--r--block/cfq-iosched.c14
-rw-r--r--block/cfq-iosched.h7
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
19static DEFINE_SPINLOCK(blkio_list_lock);
20static LIST_HEAD(blkio_list);
19 21
20struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT }; 22struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
21EXPORT_SYMBOL_GPL(blkio_root_cgroup); 23EXPORT_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();
229remove_entry: 238remove_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;
254done: 266done:
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
346void 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}
352EXPORT_SYMBOL_GPL(blkio_policy_register);
353
354void 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}
360EXPORT_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 {
46extern bool blkiocg_css_tryget(struct blkio_cgroup *blkcg); 46extern bool blkiocg_css_tryget(struct blkio_cgroup *blkcg);
47extern void blkiocg_css_put(struct blkio_cgroup *blkcg); 47extern void blkiocg_css_put(struct blkio_cgroup *blkcg);
48 48
49typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg);
50typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg,
51 unsigned int weight);
52
53struct 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
58struct blkio_policy_type {
59 struct list_head list;
60 struct blkio_policy_ops ops;
61};
62
63/* Blkio controller policy registration */
64extern void blkio_policy_register(struct blkio_policy_type *);
65extern void blkio_policy_unregister(struct blkio_policy_type *);
66
49#else 67#else
50 68
51struct blkio_group { 69struct blkio_group {
52}; 70};
53 71
72struct blkio_policy_type {
73};
74
75static inline void blkio_policy_register(struct blkio_policy_type *blkiop) { }
76static 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
3858static 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
3865static struct blkio_policy_type blkio_policy_cfq;
3866#endif
3867
3858static int __init cfq_init(void) 3868static 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)
3876static void __exit cfq_exit(void) 3887static 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
4void cfq_unlink_blkio_group(void *, struct blkio_group *);
5void cfq_update_blkio_group_weight(struct blkio_group *, unsigned int);
6
7#endif