cfq-iosched: improve sync vs async workloads

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
Jens Axboe 2007-04-23 08:33:33 +02:00 committed by Jens Axboe
parent 1be92f2fc7
commit 3ed9a2965c

View file

@ -96,6 +96,7 @@ struct cfq_data {
struct hlist_head *cfq_hash; struct hlist_head *cfq_hash;
int rq_in_driver; int rq_in_driver;
int sync_flight;
int hw_tag; 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) 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); struct cfq_queue *cfqq = RQ_CFQQ(rq);
cfq_remove_request(rq); cfq_remove_request(rq);
cfqq->dispatched++; cfqq->dispatched++;
elv_dispatch_sort(q, rq); 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) { while ((cfqq = cfq_select_queue(cfqd)) != NULL) {
int max_dispatch; int max_dispatch;
if (cfqd->busy_queues > 1) { max_dispatch = cfqd->cfq_quantum;
/* if (cfq_class_idle(cfqq))
* So we have dispatched before in this round, if the max_dispatch = 1;
* next queue has idling enabled (must be sync), don't
* allow it service until the previous have completed. if (cfqq->dispatched >= max_dispatch) {
*/ if (cfqd->busy_queues > 1)
if (cfqd->rq_in_driver && cfq_cfqq_idle_window(cfqq) &&
dispatched)
break; break;
if (cfqq->dispatched >= cfqd->cfq_quantum) if (cfqq->dispatched >= 4 * max_dispatch)
break; break;
} }
if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
break;
cfq_clear_cfqq_must_dispatch(cfqq); cfq_clear_cfqq_must_dispatch(cfqq);
cfq_clear_cfqq_wait_request(cfqq); cfq_clear_cfqq_wait_request(cfqq);
del_timer(&cfqd->idle_slice_timer); 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); 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--; cfqd->rq_in_driver--;
cfqq->dispatched--; cfqq->dispatched--;
if (cfq_cfqq_sync(cfqq))
cfqd->sync_flight--;
if (!cfq_class_idle(cfqq)) if (!cfq_class_idle(cfqq))
cfqd->last_end_request = now; cfqd->last_end_request = now;