path: root/block
diff options
authorCorrado Zoccolo <czoccolo@gmail.com>2009-11-26 10:02:58 +0100
committerJens Axboe <jens.axboe@oracle.com>2009-11-26 10:39:31 +0100
commite4a229196a7c676514c78f6783f8994f64bf681c (patch)
treeb2a9e72f863cfaadaad697158969214cd8bb5681 /block
parente459dd08f45d2aa68abb0c02f8ab045cf8a598b8 (diff)
cfq-iosched: fix no-idle preemption logic
An incoming no-idle queue should preempt the active no-idle queue only if the active queue is idling due to service tree empty. Previous code was buggy in two ways: * it relied on service_tree field to be set on the active queue, while it is not set when the code is idling for a new request * it didn't check for the service tree empty condition, so could lead to LIFO behaviour if multiple queues with depth > 1 were preempting each other on an non-NCQ device. Reported-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Corrado Zoccolo <czoccolo@gmail.com> Acked-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block')
1 files changed, 3 insertions, 2 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 47abd24617be..2c1086acddfa 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -2392,8 +2392,9 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
if (cfq_class_idle(cfqq))
return true;
- if (cfqd->serving_type == SYNC_NOIDLE_WORKLOAD
- && new_cfqq->service_tree == cfqq->service_tree)
+ if (cfqd->serving_type == SYNC_NOIDLE_WORKLOAD &&
+ cfqq_type(new_cfqq) == SYNC_NOIDLE_WORKLOAD &&
+ new_cfqq->service_tree->count == 1)
return true;