diff options
author | Shaohua Li <shaohua.li@intel.com> | 2010-11-08 09:01:03 -0500 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-11-08 09:01:03 -0500 |
commit | d2d59e18a1ea8ecdd1c0a52af320e9a7f5391cc4 (patch) | |
tree | b39812dc8fd9ae552c361a84a10dcd61d2caaab5 /block/cfq-iosched.c | |
parent | c1e44756fdb7b363fd22cb5514dced40752e36c5 (diff) |
cfq-iosched: schedule dispatch for noidle queue
A queue is idle at cfq_dispatch_requests(), but it gets noidle later. Unless
other task explictly does unplug or all requests are drained, we will not
deliever requests to the disk even cfq_arm_slice_timer doesn't make the
queue idle. For example, cfq_should_idle() returns true because of
service_tree->count == 1, and then other queues are added. Note, I didn't
see obvious performance impacts so far with the patch, but just thought
this could be a problem.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
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 | /* |