diff options
author | Corrado Zoccolo <czoccolo@gmail.com> | 2009-11-26 10:02:58 +0100 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-11-26 10:39:31 +0100 |
commit | e4a229196a7c676514c78f6783f8994f64bf681c (patch) | |
tree | b2a9e72f863cfaadaad697158969214cd8bb5681 /block/cfq-iosched.c | |
parent | e459dd08f45d2aa68abb0c02f8ab045cf8a598b8 (diff) | |
download | linux-next-e4a229196a7c676514c78f6783f8994f64bf681c.tar.gz |
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/cfq-iosched.c')
-rw-r--r-- | block/cfq-iosched.c | 5 |
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; /* |