From: Jens Axboe Date: Mon, 23 Apr 2007 06:33:33 +0000 (+0200) Subject: cfq-iosched: improve sync vs async workloads X-Git-Tag: v2.6.22-rc1~1108^2^2~4 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3ed9a2965c47636bc0ebafab31a39f1c105492ca;p=linux-2.6 cfq-iosched: improve sync vs async workloads Signed-off-by: Jens Axboe --- diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index df82755ac4..a8237be97a 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -96,6 +96,7 @@ struct cfq_data { struct hlist_head *cfq_hash; int rq_in_driver; + int sync_flight; int hw_tag; /* @@ -911,11 +912,15 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) */ static void cfq_dispatch_insert(request_queue_t *q, struct request *rq) { + struct cfq_data *cfqd = q->elevator->elevator_data; struct cfq_queue *cfqq = RQ_CFQQ(rq); cfq_remove_request(rq); cfqq->dispatched++; elv_dispatch_sort(q, rq); + + if (cfq_cfqq_sync(cfqq)) + cfqd->sync_flight++; } /* @@ -1100,27 +1105,24 @@ static int cfq_dispatch_requests(request_queue_t *q, int force) while ((cfqq = cfq_select_queue(cfqd)) != NULL) { int max_dispatch; - if (cfqd->busy_queues > 1) { - /* - * So we have dispatched before in this round, if the - * next queue has idling enabled (must be sync), don't - * allow it service until the previous have completed. - */ - if (cfqd->rq_in_driver && cfq_cfqq_idle_window(cfqq) && - dispatched) + max_dispatch = cfqd->cfq_quantum; + if (cfq_class_idle(cfqq)) + max_dispatch = 1; + + if (cfqq->dispatched >= max_dispatch) { + if (cfqd->busy_queues > 1) break; - if (cfqq->dispatched >= cfqd->cfq_quantum) + if (cfqq->dispatched >= 4 * max_dispatch) break; } + if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq)) + break; + cfq_clear_cfqq_must_dispatch(cfqq); cfq_clear_cfqq_wait_request(cfqq); del_timer(&cfqd->idle_slice_timer); - max_dispatch = cfqd->cfq_quantum; - if (cfq_class_idle(cfqq)) - max_dispatch = 1; - dispatched += __cfq_dispatch_requests(cfqd, cfqq, max_dispatch); } @@ -1767,6 +1769,9 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq) cfqd->rq_in_driver--; cfqq->dispatched--; + if (cfq_cfqq_sync(cfqq)) + cfqd->sync_flight--; + if (!cfq_class_idle(cfqq)) cfqd->last_end_request = now;