diff options
author | Corrado Zoccolo <czoccolo@gmail.com> | 2009-11-26 04:02:58 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-11-26 04:39:31 -0500 |
commit | e4a229196a7c676514c78f6783f8994f64bf681c (patch) | |
tree | b2a9e72f863cfaadaad697158969214cd8bb5681 /block/cfq-iosched.c | |
parent | e459dd08f45d2aa68abb0c02f8ab045cf8a598b8 (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/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, | |||
2392 | if (cfq_class_idle(cfqq)) | 2392 | if (cfq_class_idle(cfqq)) |
2393 | return true; | 2393 | return true; |
2394 | 2394 | ||
2395 | if (cfqd->serving_type == SYNC_NOIDLE_WORKLOAD | 2395 | if (cfqd->serving_type == SYNC_NOIDLE_WORKLOAD && |
2396 | && new_cfqq->service_tree == cfqq->service_tree) | 2396 | cfqq_type(new_cfqq) == SYNC_NOIDLE_WORKLOAD && |
2397 | new_cfqq->service_tree->count == 1) | ||
2397 | return true; | 2398 | return true; |
2398 | 2399 | ||
2399 | /* | 2400 | /* |