aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorShaohua Li <shaohua.li@intel.com>2010-11-08 09:01:03 -0500
committerJens Axboe <jaxboe@fusionio.com>2010-11-08 09:01:03 -0500
commitd2d59e18a1ea8ecdd1c0a52af320e9a7f5391cc4 (patch)
treeb39812dc8fd9ae552c361a84a10dcd61d2caaab5 /block
parentc1e44756fdb7b363fd22cb5514dced40752e36c5 (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.c23
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/*