aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-01-09 11:05:11 -0500
committerTejun Heo <tj@kernel.org>2013-01-09 11:05:11 -0500
commitd02f7aa8dce8166dbbc515ce393912aa45e6b8a6 (patch)
tree8a3e8e54bed797bb084a83008ca47065a261a9d6 /block
parent41cad6ab2cb9ccb3b11546ad56b8b285e47c6279 (diff)
cfq-iosched: enable full blkcg hierarchy support
With the previous two patches, all cfqg scheduling decisions are based on vfraction and ready for hierarchy support. The only thing which keeps the behavior flat is cfqg_flat_parent() which makes vfraction calculation consider all non-root cfqgs children of the root cfqg. Replace it with cfqg_parent() which returns the real parent. This enables full blkcg hierarchy support for cfq-iosched. For example, consider the following hierarchy. root / \ A:500 B:250 / \ AA:500 AB:1000 For simplicity, let's say all the leaf nodes have active tasks and are on service tree. For each leaf node, vfraction would be AA: (500 / 1500) * (500 / 750) =~ 0.2222 AB: (1000 / 1500) * (500 / 750) =~ 0.4444 B: (250 / 750) =~ 0.3333 and vdisktime will be distributed accordingly. For more detail, please refer to Documentation/block/cfq-iosched.txt. v2: cfq-iosched.txt updated to describe group scheduling as suggested by Vivek. v3: blkio-controller.txt updated. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Vivek Goyal <vgoyal@redhat.com>
Diffstat (limited to 'block')
-rw-r--r--block/cfq-iosched.c21
1 files changed, 6 insertions, 15 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index ee342826fd98..e8f31069b379 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -606,20 +606,11 @@ static inline struct cfq_group *blkg_to_cfqg(struct blkcg_gq *blkg)
606 return pd_to_cfqg(blkg_to_pd(blkg, &blkcg_policy_cfq)); 606 return pd_to_cfqg(blkg_to_pd(blkg, &blkcg_policy_cfq));
607} 607}
608 608
609/* 609static inline struct cfq_group *cfqg_parent(struct cfq_group *cfqg)
610 * Determine the parent cfqg for weight calculation. Currently, cfqg
611 * scheduling is flat and the root is the parent of everyone else.
612 */
613static inline struct cfq_group *cfqg_flat_parent(struct cfq_group *cfqg)
614{ 610{
615 struct blkcg_gq *blkg = cfqg_to_blkg(cfqg); 611 struct blkcg_gq *pblkg = cfqg_to_blkg(cfqg)->parent;
616 struct cfq_group *root;
617
618 while (blkg->parent)
619 blkg = blkg->parent;
620 root = blkg_to_cfqg(blkg);
621 612
622 return root != cfqg ? root : NULL; 613 return pblkg ? blkg_to_cfqg(pblkg) : NULL;
623} 614}
624 615
625static inline void cfqg_get(struct cfq_group *cfqg) 616static inline void cfqg_get(struct cfq_group *cfqg)
@@ -722,7 +713,7 @@ static void cfq_pd_reset_stats(struct blkcg_gq *blkg)
722 713
723#else /* CONFIG_CFQ_GROUP_IOSCHED */ 714#else /* CONFIG_CFQ_GROUP_IOSCHED */
724 715
725static inline struct cfq_group *cfqg_flat_parent(struct cfq_group *cfqg) { return NULL; } 716static inline struct cfq_group *cfqg_parent(struct cfq_group *cfqg) { return NULL; }
726static inline void cfqg_get(struct cfq_group *cfqg) { } 717static inline void cfqg_get(struct cfq_group *cfqg) { }
727static inline void cfqg_put(struct cfq_group *cfqg) { } 718static inline void cfqg_put(struct cfq_group *cfqg) { }
728 719
@@ -1290,7 +1281,7 @@ cfq_group_service_tree_add(struct cfq_rb_root *st, struct cfq_group *cfqg)
1290 * stops once an already activated node is met. vfraction 1281 * stops once an already activated node is met. vfraction
1291 * calculation should always continue to the root. 1282 * calculation should always continue to the root.
1292 */ 1283 */
1293 while ((parent = cfqg_flat_parent(pos))) { 1284 while ((parent = cfqg_parent(pos))) {
1294 if (propagate) { 1285 if (propagate) {
1295 propagate = !parent->nr_active++; 1286 propagate = !parent->nr_active++;
1296 parent->children_weight += pos->weight; 1287 parent->children_weight += pos->weight;
@@ -1341,7 +1332,7 @@ cfq_group_service_tree_del(struct cfq_rb_root *st, struct cfq_group *cfqg)
1341 pos->children_weight -= pos->leaf_weight; 1332 pos->children_weight -= pos->leaf_weight;
1342 1333
1343 while (propagate) { 1334 while (propagate) {
1344 struct cfq_group *parent = cfqg_flat_parent(pos); 1335 struct cfq_group *parent = cfqg_parent(pos);
1345 1336
1346 /* @pos has 0 nr_active at this point */ 1337 /* @pos has 0 nr_active at this point */
1347 WARN_ON_ONCE(pos->children_weight); 1338 WARN_ON_ONCE(pos->children_weight);