]>
Commit | Line | Data |
---|---|---|
d362f46d | 1 | diff -u -ur linux-2.4.20/drivers/block/elevator.c linux-iosched-2/drivers/block/elevator.c |
2 | --- linux-2.4.20/drivers/block/elevator.c 2003-04-14 14:47:22.000000000 -0400 | |
3 | +++ linux-iosched-2/drivers/block/elevator.c 2003-05-30 17:28:57.000000000 -0400 | |
4 | @@ -74,6 +74,81 @@ | |
5 | return 0; | |
6 | } | |
7 | ||
8 | +int elevator_neil_merge(request_queue_t *q, struct request **req, | |
9 | + struct list_head * head, | |
10 | + struct buffer_head *bh, int rw, | |
11 | + int max_sectors) | |
12 | +{ | |
13 | + struct list_head *entry = &q->queue_head; | |
14 | + struct request *__rq; | |
15 | + unsigned int count = bh->b_size >> 9, ret = ELEVATOR_NO_MERGE; | |
16 | + unsigned int reads = 0, writes = 0; | |
17 | + /* XXX make tunable? */ | |
18 | + unsigned int expire_time = jiffies - 1*HZ; | |
19 | + | |
20 | + if (list_empty(&q->queue_head)) | |
21 | + goto out; | |
22 | + | |
23 | + /* try to merge requests, fall back to ordering them by sector */ | |
24 | + while ((entry = entry->prev) != head) { | |
25 | + __rq = blkdev_entry_to_request(entry); | |
26 | + | |
27 | + if (__rq->elevator_sequence <= 0) | |
28 | + break; | |
29 | + if (__rq->cmd == READ) | |
30 | + ++reads; | |
31 | + else | |
32 | + ++writes; | |
33 | + if (__rq->rq_dev != bh->b_rdev) | |
34 | + continue; | |
35 | + if (__rq->waiting) | |
36 | + continue; | |
37 | + if (__rq->cmd != rw) | |
38 | + continue; | |
39 | + if (time_before(__rq->start_time, expire_time)) | |
40 | + break; | |
41 | + if (bh->b_rsector > __rq->sector) | |
42 | + *req = __rq; | |
43 | + if (__rq->nr_sectors + count > max_sectors) | |
44 | + continue; | |
45 | + if (__rq->sector + __rq->nr_sectors == bh->b_rsector) { | |
46 | + ret = ELEVATOR_BACK_MERGE; | |
47 | + *req = __rq; | |
48 | + goto out; | |
49 | + } else if (__rq->sector - count == bh->b_rsector) { | |
50 | + ret = ELEVATOR_FRONT_MERGE; | |
51 | + *req = __rq; | |
52 | + goto out; | |
53 | + } | |
54 | + } | |
55 | + if (!*req && rw == READ) { | |
56 | + int extra_writes = writes - reads; | |
57 | + /* | |
58 | + * If there are more writes than reads in the queue then put | |
59 | + * read requests ahead of the extra writes. This prevents | |
60 | + * writes from starving reads. | |
61 | + */ | |
62 | + entry = q->queue_head.prev; | |
63 | + while (extra_writes > 0 && entry != head) { | |
64 | + __rq = blkdev_entry_to_request(entry); | |
65 | + if (__rq->cmd == WRITE) | |
66 | + --extra_writes; | |
67 | + else if (time_before(__rq->start_time, expire_time)) | |
68 | + break; | |
69 | + entry = entry->prev; | |
70 | + } | |
71 | + *req = blkdev_entry_to_request(entry); | |
72 | + } | |
73 | +out: | |
74 | + return ret; | |
75 | +} | |
76 | + | |
77 | +void elevator_neil_merge_req(struct request *req, struct request *next) | |
78 | +{ | |
79 | + if (time_before(next->start_time, req->start_time)) | |
80 | + req->start_time = next->start_time; | |
81 | +} | |
82 | + | |
83 | ||
84 | int elevator_linus_merge(request_queue_t *q, struct request **req, | |
85 | struct list_head * head, | |
86 | diff -u -ur linux-2.4.20/drivers/block/ll_rw_blk.c linux-iosched-2/drivers/block/ll_rw_blk.c | |
87 | --- linux-2.4.20/drivers/block/ll_rw_blk.c 2003-04-14 14:47:22.000000000 -0400 | |
88 | +++ linux-iosched-2/drivers/block/ll_rw_blk.c 2003-05-30 17:27:16.000000000 -0400 | |
89 | @@ -480,7 +480,7 @@ | |
90 | void blk_init_queue(request_queue_t * q, request_fn_proc * rfn) | |
91 | { | |
92 | INIT_LIST_HEAD(&q->queue_head); | |
93 | - elevator_init(&q->elevator, ELEVATOR_LINUS); | |
94 | + elevator_init(&q->elevator, ELEVATOR_NEIL); | |
95 | blk_init_free_list(q); | |
96 | q->request_fn = rfn; | |
97 | q->back_merge_fn = ll_back_merge_fn; | |
98 | @@ -922,7 +922,8 @@ | |
99 | rw = READ; /* drop into READ */ | |
100 | case READ: | |
101 | case WRITE: | |
102 | - latency = elevator_request_latency(elevator, rw); | |
103 | + /* latency = elevator_request_latency(elevator, rw); */ | |
104 | + latency = 1; | |
105 | break; | |
106 | default: | |
107 | BUG(); | |
108 | diff -u -ur linux-2.4.20/include/linux/elevator.h linux-iosched-2/include/linux/elevator.h | |
109 | --- linux-2.4.20/include/linux/elevator.h 2003-04-14 14:47:24.000000000 -0400 | |
110 | +++ linux-iosched-2/include/linux/elevator.h 2003-05-30 17:27:16.000000000 -0400 | |
111 | @@ -31,6 +31,9 @@ | |
112 | void elevator_linus_merge_cleanup(request_queue_t *, struct request *, int); | |
113 | void elevator_linus_merge_req(struct request *, struct request *); | |
114 | ||
115 | +int elevator_neil_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int); | |
116 | +void elevator_neil_merge_req(struct request *, struct request *); | |
117 | + | |
118 | typedef struct blkelv_ioctl_arg_s { | |
119 | int queue_ID; | |
120 | int read_latency; | |
121 | @@ -101,3 +104,12 @@ | |
122 | }) | |
123 | ||
124 | #endif | |
125 | + | |
126 | +#define ELEVATOR_NEIL \ | |
127 | +((elevator_t) { \ | |
128 | + 0, /* read_latency */ \ | |
129 | + 0, /* write_latency */ \ | |
130 | + \ | |
131 | + elevator_neil_merge, /* elevator_merge_fn */ \ | |
132 | + elevator_neil_merge_req, /* elevator_merge_req_fn */ \ | |
133 | + }) | |
134 |