diff options
-rw-r--r-- | block/cfq-iosched.c | 40 | ||||
-rw-r--r-- | include/linux/iocontext.h | 14 |
2 files changed, 33 insertions, 21 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index d8b108737b72..56255599a022 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -2008,10 +2008,10 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) | |||
2008 | * slice, then don't idle. This avoids overrunning the allotted | 2008 | * slice, then don't idle. This avoids overrunning the allotted |
2009 | * time slice. | 2009 | * time slice. |
2010 | */ | 2010 | */ |
2011 | if (sample_valid(cic->ttime_samples) && | 2011 | if (sample_valid(cic->ttime.ttime_samples) && |
2012 | (cfqq->slice_end - jiffies < cic->ttime_mean)) { | 2012 | (cfqq->slice_end - jiffies < cic->ttime.ttime_mean)) { |
2013 | cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%lu", | 2013 | cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%lu", |
2014 | cic->ttime_mean); | 2014 | cic->ttime.ttime_mean); |
2015 | return; | 2015 | return; |
2016 | } | 2016 | } |
2017 | 2017 | ||
@@ -2819,7 +2819,7 @@ cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) | |||
2819 | cic = kmem_cache_alloc_node(cfq_ioc_pool, gfp_mask | __GFP_ZERO, | 2819 | cic = kmem_cache_alloc_node(cfq_ioc_pool, gfp_mask | __GFP_ZERO, |
2820 | cfqd->queue->node); | 2820 | cfqd->queue->node); |
2821 | if (cic) { | 2821 | if (cic) { |
2822 | cic->last_end_request = jiffies; | 2822 | cic->ttime.last_end_request = jiffies; |
2823 | INIT_LIST_HEAD(&cic->queue_list); | 2823 | INIT_LIST_HEAD(&cic->queue_list); |
2824 | INIT_HLIST_NODE(&cic->cic_list); | 2824 | INIT_HLIST_NODE(&cic->cic_list); |
2825 | cic->dtor = cfq_free_io_context; | 2825 | cic->dtor = cfq_free_io_context; |
@@ -3206,14 +3206,22 @@ err: | |||
3206 | } | 3206 | } |
3207 | 3207 | ||
3208 | static void | 3208 | static void |
3209 | cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_io_context *cic) | 3209 | __cfq_update_io_thinktime(struct cfq_ttime *ttime, unsigned long slice_idle) |
3210 | { | 3210 | { |
3211 | unsigned long elapsed = jiffies - cic->last_end_request; | 3211 | unsigned long elapsed = jiffies - ttime->last_end_request; |
3212 | unsigned long ttime = min(elapsed, 2UL * cfqd->cfq_slice_idle); | 3212 | elapsed = min(elapsed, 2UL * slice_idle); |
3213 | 3213 | ||
3214 | cic->ttime_samples = (7*cic->ttime_samples + 256) / 8; | 3214 | ttime->ttime_samples = (7*ttime->ttime_samples + 256) / 8; |
3215 | cic->ttime_total = (7*cic->ttime_total + 256*ttime) / 8; | 3215 | ttime->ttime_total = (7*ttime->ttime_total + 256*elapsed) / 8; |
3216 | cic->ttime_mean = (cic->ttime_total + 128) / cic->ttime_samples; | 3216 | ttime->ttime_mean = (ttime->ttime_total + 128) / ttime->ttime_samples; |
3217 | } | ||
3218 | |||
3219 | static void | ||
3220 | cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_queue *cfqq, | ||
3221 | struct cfq_io_context *cic) | ||
3222 | { | ||
3223 | if (cfq_cfqq_sync(cfqq)) | ||
3224 | __cfq_update_io_thinktime(&cic->ttime, cfqd->cfq_slice_idle); | ||
3217 | } | 3225 | } |
3218 | 3226 | ||
3219 | static void | 3227 | static void |
@@ -3262,8 +3270,8 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
3262 | else if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || | 3270 | else if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || |
3263 | (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq))) | 3271 | (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq))) |
3264 | enable_idle = 0; | 3272 | enable_idle = 0; |
3265 | else if (sample_valid(cic->ttime_samples)) { | 3273 | else if (sample_valid(cic->ttime.ttime_samples)) { |
3266 | if (cic->ttime_mean > cfqd->cfq_slice_idle) | 3274 | if (cic->ttime.ttime_mean > cfqd->cfq_slice_idle) |
3267 | enable_idle = 0; | 3275 | enable_idle = 0; |
3268 | else | 3276 | else |
3269 | enable_idle = 1; | 3277 | enable_idle = 1; |
@@ -3389,7 +3397,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
3389 | 3397 | ||
3390 | cfqd->rq_queued++; | 3398 | cfqd->rq_queued++; |
3391 | 3399 | ||
3392 | cfq_update_io_thinktime(cfqd, cic); | 3400 | cfq_update_io_thinktime(cfqd, cfqq, cic); |
3393 | cfq_update_io_seektime(cfqd, cfqq, rq); | 3401 | cfq_update_io_seektime(cfqd, cfqq, rq); |
3394 | cfq_update_idle_window(cfqd, cfqq, cic); | 3402 | cfq_update_idle_window(cfqd, cfqq, cic); |
3395 | 3403 | ||
@@ -3500,8 +3508,8 @@ static bool cfq_should_wait_busy(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
3500 | return true; | 3508 | return true; |
3501 | 3509 | ||
3502 | /* if slice left is less than think time, wait busy */ | 3510 | /* if slice left is less than think time, wait busy */ |
3503 | if (cic && sample_valid(cic->ttime_samples) | 3511 | if (cic && sample_valid(cic->ttime.ttime_samples) |
3504 | && (cfqq->slice_end - jiffies < cic->ttime_mean)) | 3512 | && (cfqq->slice_end - jiffies < cic->ttime.ttime_mean)) |
3505 | return true; | 3513 | return true; |
3506 | 3514 | ||
3507 | /* | 3515 | /* |
@@ -3542,7 +3550,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
3542 | cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]--; | 3550 | cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]--; |
3543 | 3551 | ||
3544 | if (sync) { | 3552 | if (sync) { |
3545 | RQ_CIC(rq)->last_end_request = now; | 3553 | RQ_CIC(rq)->ttime.last_end_request = now; |
3546 | if (!time_after(rq->start_time + cfqd->cfq_fifo_expire[1], now)) | 3554 | if (!time_after(rq->start_time + cfqd->cfq_fifo_expire[1], now)) |
3547 | cfqd->last_delayed_sync = now; | 3555 | cfqd->last_delayed_sync = now; |
3548 | } | 3556 | } |
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index b2eee896dcbc..5037a0ad2312 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h | |||
@@ -5,6 +5,14 @@ | |||
5 | #include <linux/rcupdate.h> | 5 | #include <linux/rcupdate.h> |
6 | 6 | ||
7 | struct cfq_queue; | 7 | struct cfq_queue; |
8 | struct cfq_ttime { | ||
9 | unsigned long last_end_request; | ||
10 | |||
11 | unsigned long ttime_total; | ||
12 | unsigned long ttime_samples; | ||
13 | unsigned long ttime_mean; | ||
14 | }; | ||
15 | |||
8 | struct cfq_io_context { | 16 | struct cfq_io_context { |
9 | void *key; | 17 | void *key; |
10 | 18 | ||
@@ -12,11 +20,7 @@ struct cfq_io_context { | |||
12 | 20 | ||
13 | struct io_context *ioc; | 21 | struct io_context *ioc; |
14 | 22 | ||
15 | unsigned long last_end_request; | 23 | struct cfq_ttime ttime; |
16 | |||
17 | unsigned long ttime_total; | ||
18 | unsigned long ttime_samples; | ||
19 | unsigned long ttime_mean; | ||
20 | 24 | ||
21 | struct list_head queue_list; | 25 | struct list_head queue_list; |
22 | struct hlist_node cic_list; | 26 | struct hlist_node cic_list; |