6 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/slab.h>
14 #include <linux/compiler.h>
15 #include <linux/rbtree.h>
20 static const int read_expire =
HZ / 2;
21 static const int write_expire = 5 *
HZ;
22 static const int writes_starved = 2;
23 static const int fifo_batch = 16;
66 deadline_latter_request(
struct request *
rq)
71 return rb_entry_rq(node);
87 const int data_dir = rq_data_dir(rq);
89 if (dd->
next_rq[data_dir] == rq)
102 const int data_dir = rq_data_dir(rq);
104 deadline_add_rq_rb(dd, rq);
109 rq_set_fifo_time(rq, jiffies + dd->
fifo_expire[data_dir]);
121 deadline_del_rq_rb(dd, rq);
139 BUG_ON(sector != blk_rq_pos(__rq));
142 ret = ELEVATOR_FRONT_MERGE;
148 return ELEVATOR_NO_MERGE;
162 if (type == ELEVATOR_FRONT_MERGE) {
164 deadline_add_rq_rb(dd, req);
176 if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) {
177 if (
time_before(rq_fifo_time(next), rq_fifo_time(req))) {
178 list_move(&req->queuelist, &next->queuelist);
179 rq_set_fifo_time(req, rq_fifo_time(next));
186 deadline_remove_request(q, next);
197 deadline_remove_request(q, rq);
207 const int data_dir = rq_data_dir(rq);
219 deadline_move_to_dispatch(dd, rq);
226 static inline int deadline_check_fifo(
struct deadline_data *dd,
int ddir)
261 goto dispatch_request;
272 goto dispatch_writes;
276 goto dispatch_find_request;
291 goto dispatch_find_request;
296 dispatch_find_request:
300 if (deadline_check_fifo(dd, data_dir) || !dd->
next_rq[data_dir]) {
306 rq = rq_entry_fifo(dd->
fifo_list[data_dir].next);
322 deadline_move_request(dd, rq);
327 static void deadline_exit_queue(
struct elevator_queue *
e)
358 q->elevator->elevator_data =
dd;
367 deadline_var_show(
int var,
char *
page)
369 return sprintf(page,
"%d\n", var);
373 deadline_var_store(
int *var,
const char *
page,
size_t count)
375 char *
p = (
char *) page;
381 #define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
382 static ssize_t __FUNC(struct elevator_queue *e, char *page) \
384 struct deadline_data *dd = e->elevator_data; \
385 int __data = __VAR; \
387 __data = jiffies_to_msecs(__data); \
388 return deadline_var_show(__data, (page)); \
397 #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
398 static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count) \
400 struct deadline_data *dd = e->elevator_data; \
402 int ret = deadline_var_store(&__data, (page), count); \
403 if (__data < (MIN)) \
405 else if (__data > (MAX)) \
408 *(__PTR) = msecs_to_jiffies(__data); \
418 #undef STORE_FUNCTION
420 #define DD_ATTR(name) \
421 __ATTR(name, S_IRUGO|S_IWUSR, deadline_##name##_show, \
422 deadline_##name##_store)
424 static struct elv_fs_entry deadline_attrs[] = {
433 static struct elevator_type iosched_deadline = {
435 .elevator_merge_fn = deadline_merge,
436 .elevator_merged_fn = deadline_merged_request,
437 .elevator_merge_req_fn = deadline_merged_requests,
438 .elevator_dispatch_fn = deadline_dispatch_requests,
439 .elevator_add_req_fn = deadline_add_request,
442 .elevator_init_fn = deadline_init_queue,
443 .elevator_exit_fn = deadline_exit_queue,
446 .elevator_attrs = deadline_attrs,
447 .elevator_name =
"deadline",
451 static int __init deadline_init(
void)
456 static void __exit deadline_exit(
void)