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 | |
| 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')
| -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 | /* |
