diff options
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r-- | block/cfq-iosched.c | 54 |
1 files changed, 14 insertions, 40 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 10eb286f1f4..3fd8afc2174 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -46,8 +46,8 @@ static const int cfq_hist_divisor = 4; | |||
46 | #define CFQ_HW_QUEUE_MIN (5) | 46 | #define CFQ_HW_QUEUE_MIN (5) |
47 | #define CFQ_SERVICE_SHIFT 12 | 47 | #define CFQ_SERVICE_SHIFT 12 |
48 | 48 | ||
49 | #define CFQQ_SEEK_THR 8 * 1024 | 49 | #define CFQQ_SEEK_THR (sector_t)(8 * 100) |
50 | #define CFQQ_SEEKY(cfqq) ((cfqq)->seek_mean > CFQQ_SEEK_THR) | 50 | #define CFQQ_SEEKY(cfqq) (hweight32(cfqq->seek_history) > 32/8) |
51 | 51 | ||
52 | #define RQ_CIC(rq) \ | 52 | #define RQ_CIC(rq) \ |
53 | ((struct cfq_io_context *) (rq)->elevator_private) | 53 | ((struct cfq_io_context *) (rq)->elevator_private) |
@@ -132,9 +132,7 @@ struct cfq_queue { | |||
132 | 132 | ||
133 | pid_t pid; | 133 | pid_t pid; |
134 | 134 | ||
135 | unsigned int seek_samples; | 135 | u32 seek_history; |
136 | u64 seek_total; | ||
137 | sector_t seek_mean; | ||
138 | sector_t last_request_pos; | 136 | sector_t last_request_pos; |
139 | 137 | ||
140 | struct cfq_rb_root *service_tree; | 138 | struct cfq_rb_root *service_tree; |
@@ -1668,16 +1666,7 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd, | |||
1668 | static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq, | 1666 | static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq, |
1669 | struct request *rq, bool for_preempt) | 1667 | struct request *rq, bool for_preempt) |
1670 | { | 1668 | { |
1671 | sector_t sdist = cfqq->seek_mean; | 1669 | return cfq_dist_from_last(cfqd, rq) <= CFQQ_SEEK_THR; |
1672 | |||
1673 | if (!sample_valid(cfqq->seek_samples)) | ||
1674 | sdist = CFQQ_SEEK_THR; | ||
1675 | |||
1676 | /* if seek_mean is big, using it as close criteria is meaningless */ | ||
1677 | if (sdist > CFQQ_SEEK_THR && !for_preempt) | ||
1678 | sdist = CFQQ_SEEK_THR; | ||
1679 | |||
1680 | return cfq_dist_from_last(cfqd, rq) <= sdist; | ||
1681 | } | 1670 | } |
1682 | 1671 | ||
1683 | static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, | 1672 | static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, |
@@ -2975,30 +2964,16 @@ static void | |||
2975 | cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_queue *cfqq, | 2964 | cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_queue *cfqq, |
2976 | struct request *rq) | 2965 | struct request *rq) |
2977 | { | 2966 | { |
2978 | sector_t sdist; | 2967 | sector_t sdist = 0; |
2979 | u64 total; | 2968 | if (cfqq->last_request_pos) { |
2980 | 2969 | if (cfqq->last_request_pos < blk_rq_pos(rq)) | |
2981 | if (!cfqq->last_request_pos) | 2970 | sdist = blk_rq_pos(rq) - cfqq->last_request_pos; |
2982 | sdist = 0; | 2971 | else |
2983 | else if (cfqq->last_request_pos < blk_rq_pos(rq)) | 2972 | sdist = cfqq->last_request_pos - blk_rq_pos(rq); |
2984 | sdist = blk_rq_pos(rq) - cfqq->last_request_pos; | 2973 | } |
2985 | else | ||
2986 | sdist = cfqq->last_request_pos - blk_rq_pos(rq); | ||
2987 | |||
2988 | /* | ||
2989 | * Don't allow the seek distance to get too large from the | ||
2990 | * odd fragment, pagein, etc | ||
2991 | */ | ||
2992 | if (cfqq->seek_samples <= 60) /* second&third seek */ | ||
2993 | sdist = min(sdist, (cfqq->seek_mean * 4) + 2*1024*1024); | ||
2994 | else | ||
2995 | sdist = min(sdist, (cfqq->seek_mean * 4) + 2*1024*64); | ||
2996 | 2974 | ||
2997 | cfqq->seek_samples = (7*cfqq->seek_samples + 256) / 8; | 2975 | cfqq->seek_history <<= 1; |
2998 | cfqq->seek_total = (7*cfqq->seek_total + (u64)256*sdist) / 8; | 2976 | cfqq->seek_history |= (sdist > CFQQ_SEEK_THR); |
2999 | total = cfqq->seek_total + (cfqq->seek_samples/2); | ||
3000 | do_div(total, cfqq->seek_samples); | ||
3001 | cfqq->seek_mean = (sector_t)total; | ||
3002 | } | 2977 | } |
3003 | 2978 | ||
3004 | /* | 2979 | /* |
@@ -3023,8 +2998,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
3023 | cfq_mark_cfqq_deep(cfqq); | 2998 | cfq_mark_cfqq_deep(cfqq); |
3024 | 2999 | ||
3025 | if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || | 3000 | if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || |
3026 | (!cfq_cfqq_deep(cfqq) && sample_valid(cfqq->seek_samples) | 3001 | (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq))) |
3027 | && CFQQ_SEEKY(cfqq))) | ||
3028 | enable_idle = 0; | 3002 | enable_idle = 0; |
3029 | else if (sample_valid(cic->ttime_samples)) { | 3003 | else if (sample_valid(cic->ttime_samples)) { |
3030 | if (cic->ttime_mean > cfqd->cfq_slice_idle) | 3004 | if (cic->ttime_mean > cfqd->cfq_slice_idle) |