aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r--block/cfq-iosched.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 56255599a022..baa90606f01a 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -87,9 +87,10 @@ struct cfq_rb_root {
87 unsigned count; 87 unsigned count;
88 unsigned total_weight; 88 unsigned total_weight;
89 u64 min_vdisktime; 89 u64 min_vdisktime;
90 struct cfq_ttime ttime;
90}; 91};
91#define CFQ_RB_ROOT (struct cfq_rb_root) { .rb = RB_ROOT, .left = NULL, \ 92#define CFQ_RB_ROOT (struct cfq_rb_root) { .rb = RB_ROOT, \
92 .count = 0, .min_vdisktime = 0, } 93 .ttime = {.last_end_request = jiffies,},}
93 94
94/* 95/*
95 * Per process-grouping structure 96 * Per process-grouping structure
@@ -391,6 +392,18 @@ CFQ_CFQQ_FNS(wait_busy);
391 j++, st = i < IDLE_WORKLOAD ? \ 392 j++, st = i < IDLE_WORKLOAD ? \
392 &cfqg->service_trees[i][j]: NULL) \ 393 &cfqg->service_trees[i][j]: NULL) \
393 394
395static inline bool cfq_io_thinktime_big(struct cfq_data *cfqd,
396 struct cfq_ttime *ttime, bool group_idle)
397{
398 unsigned long slice;
399 if (!sample_valid(ttime->ttime_samples))
400 return false;
401 if (group_idle)
402 slice = cfqd->cfq_group_idle;
403 else
404 slice = cfqd->cfq_slice_idle;
405 return ttime->ttime_mean > slice;
406}
394 407
395static inline bool iops_mode(struct cfq_data *cfqd) 408static inline bool iops_mode(struct cfq_data *cfqd)
396{ 409{
@@ -1955,7 +1968,8 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1955 * Otherwise, we do only if they are the last ones 1968 * Otherwise, we do only if they are the last ones
1956 * in their service tree. 1969 * in their service tree.
1957 */ 1970 */
1958 if (service_tree->count == 1 && cfq_cfqq_sync(cfqq)) 1971 if (service_tree->count == 1 && cfq_cfqq_sync(cfqq) &&
1972 !cfq_io_thinktime_big(cfqd, &service_tree->ttime, false))
1959 return true; 1973 return true;
1960 cfq_log_cfqq(cfqd, cfqq, "Not idling. st->count:%d", 1974 cfq_log_cfqq(cfqd, cfqq, "Not idling. st->count:%d",
1961 service_tree->count); 1975 service_tree->count);
@@ -3220,8 +3234,11 @@ static void
3220cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_queue *cfqq, 3234cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_queue *cfqq,
3221 struct cfq_io_context *cic) 3235 struct cfq_io_context *cic)
3222{ 3236{
3223 if (cfq_cfqq_sync(cfqq)) 3237 if (cfq_cfqq_sync(cfqq)) {
3224 __cfq_update_io_thinktime(&cic->ttime, cfqd->cfq_slice_idle); 3238 __cfq_update_io_thinktime(&cic->ttime, cfqd->cfq_slice_idle);
3239 __cfq_update_io_thinktime(&cfqq->service_tree->ttime,
3240 cfqd->cfq_slice_idle);
3241 }
3225} 3242}
3226 3243
3227static void 3244static void
@@ -3550,7 +3567,16 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
3550 cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]--; 3567 cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]--;
3551 3568
3552 if (sync) { 3569 if (sync) {
3570 struct cfq_rb_root *service_tree;
3571
3553 RQ_CIC(rq)->ttime.last_end_request = now; 3572 RQ_CIC(rq)->ttime.last_end_request = now;
3573
3574 if (cfq_cfqq_on_rr(cfqq))
3575 service_tree = cfqq->service_tree;
3576 else
3577 service_tree = service_tree_for(cfqq->cfqg,
3578 cfqq_prio(cfqq), cfqq_type(cfqq));
3579 service_tree->ttime.last_end_request = now;
3554 if (!time_after(rq->start_time + cfqd->cfq_fifo_expire[1], now)) 3580 if (!time_after(rq->start_time + cfqd->cfq_fifo_expire[1], now))
3555 cfqd->last_delayed_sync = now; 3581 cfqd->last_delayed_sync = now;
3556 } 3582 }