aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorShaohua Li <shaohua.li@intel.com>2011-07-12 08:24:56 -0400
committerJens Axboe <jaxboe@fusionio.com>2011-07-12 08:24:56 -0400
commit7700fc4f675fa38094e78e345b594363a2fd895b (patch)
tree000ae1fb3d825240b7e78ad8d3db66be168ffe94 /block
parentf5f2b6ceb23e02ff35c6dbc6a39aa776ace99cda (diff)
CFQ: add think time check for group
Currently when the last queue of a group has no request, we don't expire the queue to hope request from the group comes soon, so the group doesn't miss its share. But if the think time is big, the assumption isn't correct and we just waste bandwidth. In such case, we don't do idle. [global] runtime=30 direct=1 [test1] cgroup=test1 cgroup_weight=1000 rw=randread ioengine=libaio size=500m runtime=30 directory=/mnt filename=file1 thinktime=9000 [test2] cgroup=test2 cgroup_weight=1000 rw=randread ioengine=libaio size=500m runtime=30 directory=/mnt filename=file2 patched base test1 64k 39k test2 548k 540k total 604k 578k group1 gets much better throughput because it waits less time. To check if the patch changes behavior of queue without think time. I also tried to give test1 2ms think time or no think time. The test result is stable. The thoughput doesn't change with/without the patch. Signed-off-by: Shaohua Li <shaohua.li@intel.com> Acked-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'block')
-rw-r--r--block/cfq-iosched.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index baa90606f01a..1f96ad6254f1 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -211,6 +211,7 @@ struct cfq_group {
211#endif 211#endif
212 /* number of requests that are on the dispatch list or inside driver */ 212 /* number of requests that are on the dispatch list or inside driver */
213 int dispatched; 213 int dispatched;
214 struct cfq_ttime ttime;
214}; 215};
215 216
216/* 217/*
@@ -1067,6 +1068,8 @@ static struct cfq_group * cfq_alloc_cfqg(struct cfq_data *cfqd)
1067 *st = CFQ_RB_ROOT; 1068 *st = CFQ_RB_ROOT;
1068 RB_CLEAR_NODE(&cfqg->rb_node); 1069 RB_CLEAR_NODE(&cfqg->rb_node);
1069 1070
1071 cfqg->ttime.last_end_request = jiffies;
1072
1070 /* 1073 /*
1071 * Take the initial reference that will be released on destroy 1074 * Take the initial reference that will be released on destroy
1072 * This can be thought of a joint reference by cgroup and 1075 * This can be thought of a joint reference by cgroup and
@@ -2381,8 +2384,9 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
2381 * this group, wait for requests to complete. 2384 * this group, wait for requests to complete.
2382 */ 2385 */
2383check_group_idle: 2386check_group_idle:
2384 if (cfqd->cfq_group_idle && cfqq->cfqg->nr_cfqq == 1 2387 if (cfqd->cfq_group_idle && cfqq->cfqg->nr_cfqq == 1 &&
2385 && cfqq->cfqg->dispatched) { 2388 cfqq->cfqg->dispatched &&
2389 !cfq_io_thinktime_big(cfqd, &cfqq->cfqg->ttime, true)) {
2386 cfqq = NULL; 2390 cfqq = NULL;
2387 goto keep_queue; 2391 goto keep_queue;
2388 } 2392 }
@@ -3239,6 +3243,9 @@ cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_queue *cfqq,
3239 __cfq_update_io_thinktime(&cfqq->service_tree->ttime, 3243 __cfq_update_io_thinktime(&cfqq->service_tree->ttime,
3240 cfqd->cfq_slice_idle); 3244 cfqd->cfq_slice_idle);
3241 } 3245 }
3246#ifdef CONFIG_CFQ_GROUP_IOSCHED
3247 __cfq_update_io_thinktime(&cfqq->cfqg->ttime, cfqd->cfq_group_idle);
3248#endif
3242} 3249}
3243 3250
3244static void 3251static void
@@ -3521,6 +3528,10 @@ static bool cfq_should_wait_busy(struct cfq_data *cfqd, struct cfq_queue *cfqq)
3521 if (cfqq->cfqg->nr_cfqq > 1) 3528 if (cfqq->cfqg->nr_cfqq > 1)
3522 return false; 3529 return false;
3523 3530
3531 /* the only queue in the group, but think time is big */
3532 if (cfq_io_thinktime_big(cfqd, &cfqq->cfqg->ttime, true))
3533 return false;
3534
3524 if (cfq_slice_used(cfqq)) 3535 if (cfq_slice_used(cfqq))
3525 return true; 3536 return true;
3526 3537
@@ -3581,6 +3592,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
3581 cfqd->last_delayed_sync = now; 3592 cfqd->last_delayed_sync = now;
3582 } 3593 }
3583 3594
3595#ifdef CONFIG_CFQ_GROUP_IOSCHED
3596 cfqq->cfqg->ttime.last_end_request = now;
3597#endif
3598
3584 /* 3599 /*
3585 * If this is the active queue, check if it needs to be expired, 3600 * If this is the active queue, check if it needs to be expired,
3586 * or if we want to idle in case it has no pending requests. 3601 * or if we want to idle in case it has no pending requests.