cfq-iosched: fix sequential write regression
We have a 10-15% performance regression for sequential writes on TCQ/NCQ enabled drives in 2.6.21-rcX after the CFQ update went in. It has been reported by Valerie Clement <valerie.clement@bull.net> and the Intel testing folks. The regression is because of CFQ's now more aggressive queue control, limiting the depth available to the device. This patches fixes that regression by allowing a greater depth when only one queue is busy. It has been tested to not impact sync-vs-async workloads too much - we still do a lot better than 2.6.20. Signed-off-by: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
46fcc86dd7
commit
a993800655
@@ -986,9 +986,9 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
|
|||||||
* expire an async queue immediately if it has used up its slice. idle
|
* expire an async queue immediately if it has used up its slice. idle
|
||||||
* queue always expire after 1 dispatch round.
|
* queue always expire after 1 dispatch round.
|
||||||
*/
|
*/
|
||||||
if ((!cfq_cfqq_sync(cfqq) &&
|
if (cfqd->busy_queues > 1 && ((!cfq_cfqq_sync(cfqq) &&
|
||||||
cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
|
cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
|
||||||
cfq_class_idle(cfqq)) {
|
cfq_class_idle(cfqq))) {
|
||||||
cfqq->slice_end = jiffies + 1;
|
cfqq->slice_end = jiffies + 1;
|
||||||
cfq_slice_expired(cfqd, 0, 0);
|
cfq_slice_expired(cfqd, 0, 0);
|
||||||
}
|
}
|
||||||
@@ -1051,6 +1051,7 @@ 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) {
|
||||||
/*
|
/*
|
||||||
* Don't repeat dispatch from the previous queue.
|
* Don't repeat dispatch from the previous queue.
|
||||||
*/
|
*/
|
||||||
@@ -1064,6 +1065,7 @@ cfq_dispatch_requests(request_queue_t *q, int force)
|
|||||||
*/
|
*/
|
||||||
if (cfqd->rq_in_driver && cfq_cfqq_idle_window(cfqq))
|
if (cfqd->rq_in_driver && cfq_cfqq_idle_window(cfqq))
|
||||||
break;
|
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);
|
||||||
@@ -1370,7 +1372,9 @@ retry:
|
|||||||
atomic_set(&cfqq->ref, 0);
|
atomic_set(&cfqq->ref, 0);
|
||||||
cfqq->cfqd = cfqd;
|
cfqq->cfqd = cfqd;
|
||||||
|
|
||||||
|
if (key != CFQ_KEY_ASYNC)
|
||||||
cfq_mark_cfqq_idle_window(cfqq);
|
cfq_mark_cfqq_idle_window(cfqq);
|
||||||
|
|
||||||
cfq_mark_cfqq_prio_changed(cfqq);
|
cfq_mark_cfqq_prio_changed(cfqq);
|
||||||
cfq_mark_cfqq_queue_new(cfqq);
|
cfq_mark_cfqq_queue_new(cfqq);
|
||||||
cfq_init_prio_data(cfqq);
|
cfq_init_prio_data(cfqq);
|
||||||
|
Reference in New Issue
Block a user