Commit d2d59e18a1ea8ecdd1c0a52af320e9a7f5391cc4
Committed by
Jens Axboe
1 parent
c1e44756fd
Exists in
master
and in
4 other branches
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>
Showing 1 changed file with 22 additions and 1 deletions Side-by-side Diff
block/cfq-iosched.c
... | ... | @@ -3255,6 +3255,10 @@ |
3255 | 3255 | if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) |
3256 | 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 | 3262 | if (!cfqd->active_cic || !cfq_cfqq_wait_request(cfqq)) |
3259 | 3263 | return false; |
3260 | 3264 | |
3261 | 3265 | |
... | ... | @@ -3508,8 +3512,25 @@ |
3508 | 3512 | } |
3509 | 3513 | } |
3510 | 3514 | |
3511 | - if (!cfqd->rq_in_driver) | |
3515 | + if (!cfqd->rq_in_driver) { | |
3512 | 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); | |
3532 | + cfq_schedule_dispatch(cfqd); | |
3533 | + } | |
3513 | 3534 | } |
3514 | 3535 | |
3515 | 3536 | /* |