diff options
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r-- | block/cfq-iosched.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index b8174bb4a6a1..986865e3fbc5 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -3255,6 +3255,10 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
3255 | if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) | 3255 | if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) |
3256 | return true; | 3256 | return true; |
3257 | 3257 | ||
3258 | /* An idle queue should not be idle now for some reason */ | ||
3259 | if (RB_EMPTY_ROOT(&cfqq->sort_list) && !cfq_should_idle(cfqd, cfqq)) | ||
3260 | return true; | ||
3261 | |||
3258 | if (!cfqd->active_cic || !cfq_cfqq_wait_request(cfqq)) | 3262 | if (!cfqd->active_cic || !cfq_cfqq_wait_request(cfqq)) |
3259 | return false; | 3263 | return false; |
3260 | 3264 | ||
@@ -3508,8 +3512,25 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
3508 | } | 3512 | } |
3509 | } | 3513 | } |
3510 | 3514 | ||
3511 | if (!cfqd->rq_in_driver) | 3515 | if (!cfqd->rq_in_driver) { |
3516 | cfq_schedule_dispatch(cfqd); | ||
3517 | return; | ||
3518 | } | ||
3519 | /* | ||
3520 | * A queue is idle at cfq_dispatch_requests(), but it gets noidle | ||
3521 | * later. We schedule a dispatch if the queue has no requests, | ||
3522 | * otherwise the disk is actually in idle till all requests | ||
3523 | * are finished even cfq_arm_slice_timer doesn't make the queue idle | ||
3524 | * */ | ||
3525 | cfqq = cfqd->active_queue; | ||
3526 | if (!cfqq) | ||
3527 | return; | ||
3528 | |||
3529 | if (RB_EMPTY_ROOT(&cfqq->sort_list) && !cfq_should_idle(cfqd, cfqq) && | ||
3530 | (!cfqd->cfq_group_idle || cfqq->cfqg->nr_cfqq > 1)) { | ||
3531 | cfq_del_timer(cfqd, cfqq); | ||
3512 | cfq_schedule_dispatch(cfqd); | 3532 | cfq_schedule_dispatch(cfqd); |
3533 | } | ||
3513 | } | 3534 | } |
3514 | 3535 | ||
3515 | /* | 3536 | /* |