aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/cfq-iosched.c40
-rw-r--r--include/linux/iocontext.h14
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
3208static void 3208static void
3209cfq_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
3219static void
3220cfq_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
3219static void 3227static 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
7struct cfq_queue; 7struct cfq_queue;
8struct 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
8struct cfq_io_context { 16struct 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;