diff options
Diffstat (limited to 'block/deadline-iosched.c')
-rw-r--r-- | block/deadline-iosched.c | 40 |
1 files changed, 16 insertions, 24 deletions
diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c index 342448c3d2dd..fd311179f44c 100644 --- a/block/deadline-iosched.c +++ b/block/deadline-iosched.c | |||
@@ -33,7 +33,7 @@ struct deadline_data { | |||
33 | */ | 33 | */ |
34 | struct rb_root sort_list[2]; | 34 | struct rb_root sort_list[2]; |
35 | struct list_head fifo_list[2]; | 35 | struct list_head fifo_list[2]; |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * next in sort order. read, write or both are NULL | 38 | * next in sort order. read, write or both are NULL |
39 | */ | 39 | */ |
@@ -53,7 +53,11 @@ struct deadline_data { | |||
53 | 53 | ||
54 | static void deadline_move_request(struct deadline_data *, struct request *); | 54 | static void deadline_move_request(struct deadline_data *, struct request *); |
55 | 55 | ||
56 | #define RQ_RB_ROOT(dd, rq) (&(dd)->sort_list[rq_data_dir((rq))]) | 56 | static inline struct rb_root * |
57 | deadline_rb_root(struct deadline_data *dd, struct request *rq) | ||
58 | { | ||
59 | return &dd->sort_list[rq_data_dir(rq)]; | ||
60 | } | ||
57 | 61 | ||
58 | /* | 62 | /* |
59 | * get the request after `rq' in sector-sorted order | 63 | * get the request after `rq' in sector-sorted order |
@@ -72,15 +76,11 @@ deadline_latter_request(struct request *rq) | |||
72 | static void | 76 | static void |
73 | deadline_add_rq_rb(struct deadline_data *dd, struct request *rq) | 77 | deadline_add_rq_rb(struct deadline_data *dd, struct request *rq) |
74 | { | 78 | { |
75 | struct rb_root *root = RQ_RB_ROOT(dd, rq); | 79 | struct rb_root *root = deadline_rb_root(dd, rq); |
76 | struct request *__alias; | 80 | struct request *__alias; |
77 | 81 | ||
78 | retry: | 82 | while (unlikely(__alias = elv_rb_add(root, rq))) |
79 | __alias = elv_rb_add(root, rq); | ||
80 | if (unlikely(__alias)) { | ||
81 | deadline_move_request(dd, __alias); | 83 | deadline_move_request(dd, __alias); |
82 | goto retry; | ||
83 | } | ||
84 | } | 84 | } |
85 | 85 | ||
86 | static inline void | 86 | static inline void |
@@ -91,7 +91,7 @@ deadline_del_rq_rb(struct deadline_data *dd, struct request *rq) | |||
91 | if (dd->next_rq[data_dir] == rq) | 91 | if (dd->next_rq[data_dir] == rq) |
92 | dd->next_rq[data_dir] = deadline_latter_request(rq); | 92 | dd->next_rq[data_dir] = deadline_latter_request(rq); |
93 | 93 | ||
94 | elv_rb_del(RQ_RB_ROOT(dd, rq), rq); | 94 | elv_rb_del(deadline_rb_root(dd, rq), rq); |
95 | } | 95 | } |
96 | 96 | ||
97 | /* | 97 | /* |
@@ -106,7 +106,7 @@ deadline_add_request(struct request_queue *q, struct request *rq) | |||
106 | deadline_add_rq_rb(dd, rq); | 106 | deadline_add_rq_rb(dd, rq); |
107 | 107 | ||
108 | /* | 108 | /* |
109 | * set expire time (only used for reads) and add to fifo list | 109 | * set expire time and add to fifo list |
110 | */ | 110 | */ |
111 | rq_set_fifo_time(rq, jiffies + dd->fifo_expire[data_dir]); | 111 | rq_set_fifo_time(rq, jiffies + dd->fifo_expire[data_dir]); |
112 | list_add_tail(&rq->queuelist, &dd->fifo_list[data_dir]); | 112 | list_add_tail(&rq->queuelist, &dd->fifo_list[data_dir]); |
@@ -162,7 +162,7 @@ static void deadline_merged_request(struct request_queue *q, | |||
162 | * if the merge was a front merge, we need to reposition request | 162 | * if the merge was a front merge, we need to reposition request |
163 | */ | 163 | */ |
164 | if (type == ELEVATOR_FRONT_MERGE) { | 164 | if (type == ELEVATOR_FRONT_MERGE) { |
165 | elv_rb_del(RQ_RB_ROOT(dd, req), req); | 165 | elv_rb_del(deadline_rb_root(dd, req), req); |
166 | deadline_add_rq_rb(dd, req); | 166 | deadline_add_rq_rb(dd, req); |
167 | } | 167 | } |
168 | } | 168 | } |
@@ -212,7 +212,7 @@ deadline_move_request(struct deadline_data *dd, struct request *rq) | |||
212 | dd->next_rq[WRITE] = NULL; | 212 | dd->next_rq[WRITE] = NULL; |
213 | dd->next_rq[data_dir] = deadline_latter_request(rq); | 213 | dd->next_rq[data_dir] = deadline_latter_request(rq); |
214 | 214 | ||
215 | dd->last_sector = rq->sector + rq->nr_sectors; | 215 | dd->last_sector = rq_end_sector(rq); |
216 | 216 | ||
217 | /* | 217 | /* |
218 | * take it off the sort and fifo list, move | 218 | * take it off the sort and fifo list, move |
@@ -222,7 +222,7 @@ deadline_move_request(struct deadline_data *dd, struct request *rq) | |||
222 | } | 222 | } |
223 | 223 | ||
224 | /* | 224 | /* |
225 | * deadline_check_fifo returns 0 if there are no expired reads on the fifo, | 225 | * deadline_check_fifo returns 0 if there are no expired requests on the fifo, |
226 | * 1 otherwise. Requires !list_empty(&dd->fifo_list[data_dir]) | 226 | * 1 otherwise. Requires !list_empty(&dd->fifo_list[data_dir]) |
227 | */ | 227 | */ |
228 | static inline int deadline_check_fifo(struct deadline_data *dd, int ddir) | 228 | static inline int deadline_check_fifo(struct deadline_data *dd, int ddir) |
@@ -258,17 +258,9 @@ static int deadline_dispatch_requests(struct request_queue *q, int force) | |||
258 | else | 258 | else |
259 | rq = dd->next_rq[READ]; | 259 | rq = dd->next_rq[READ]; |
260 | 260 | ||
261 | if (rq) { | 261 | if (rq && dd->batching < dd->fifo_batch) |
262 | /* we have a "next request" */ | 262 | /* we have a next request are still entitled to batch */ |
263 | 263 | goto dispatch_request; | |
264 | if (dd->last_sector != rq->sector) | ||
265 | /* end the batch on a non sequential request */ | ||
266 | dd->batching += dd->fifo_batch; | ||
267 | |||
268 | if (dd->batching < dd->fifo_batch) | ||
269 | /* we are still entitled to batch */ | ||
270 | goto dispatch_request; | ||
271 | } | ||
272 | 264 | ||
273 | /* | 265 | /* |
274 | * at this point we are not running a batch. select the appropriate | 266 | * at this point we are not running a batch. select the appropriate |