]>
Commit | Line | Data |
---|---|---|
1 | #ifndef _LINUX_ELEVATOR_H | |
2 | #define _LINUX_ELEVATOR_H | |
3 | ||
4 | #include <linux/percpu.h> | |
5 | #include <linux/hashtable.h> | |
6 | ||
7 | #ifdef CONFIG_BLOCK | |
8 | ||
9 | struct io_cq; | |
10 | struct elevator_type; | |
11 | ||
12 | typedef int (elevator_merge_fn) (struct request_queue *, struct request **, | |
13 | struct bio *); | |
14 | ||
15 | typedef void (elevator_merge_req_fn) (struct request_queue *, struct request *, struct request *); | |
16 | ||
17 | typedef void (elevator_merged_fn) (struct request_queue *, struct request *, int); | |
18 | ||
19 | typedef int (elevator_allow_bio_merge_fn) (struct request_queue *, | |
20 | struct request *, struct bio *); | |
21 | ||
22 | typedef int (elevator_allow_rq_merge_fn) (struct request_queue *, | |
23 | struct request *, struct request *); | |
24 | ||
25 | typedef void (elevator_bio_merged_fn) (struct request_queue *, | |
26 | struct request *, struct bio *); | |
27 | ||
28 | typedef int (elevator_dispatch_fn) (struct request_queue *, int); | |
29 | ||
30 | typedef void (elevator_add_req_fn) (struct request_queue *, struct request *); | |
31 | typedef struct request *(elevator_request_list_fn) (struct request_queue *, struct request *); | |
32 | typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *); | |
33 | typedef int (elevator_may_queue_fn) (struct request_queue *, unsigned int); | |
34 | ||
35 | typedef void (elevator_init_icq_fn) (struct io_cq *); | |
36 | typedef void (elevator_exit_icq_fn) (struct io_cq *); | |
37 | typedef int (elevator_set_req_fn) (struct request_queue *, struct request *, | |
38 | struct bio *, gfp_t); | |
39 | typedef void (elevator_put_req_fn) (struct request *); | |
40 | typedef void (elevator_activate_req_fn) (struct request_queue *, struct request *); | |
41 | typedef void (elevator_deactivate_req_fn) (struct request_queue *, struct request *); | |
42 | ||
43 | typedef int (elevator_init_fn) (struct request_queue *, | |
44 | struct elevator_type *e); | |
45 | typedef void (elevator_exit_fn) (struct elevator_queue *); | |
46 | typedef void (elevator_registered_fn) (struct request_queue *); | |
47 | ||
48 | struct elevator_ops | |
49 | { | |
50 | elevator_merge_fn *elevator_merge_fn; | |
51 | elevator_merged_fn *elevator_merged_fn; | |
52 | elevator_merge_req_fn *elevator_merge_req_fn; | |
53 | elevator_allow_bio_merge_fn *elevator_allow_bio_merge_fn; | |
54 | elevator_allow_rq_merge_fn *elevator_allow_rq_merge_fn; | |
55 | elevator_bio_merged_fn *elevator_bio_merged_fn; | |
56 | ||
57 | elevator_dispatch_fn *elevator_dispatch_fn; | |
58 | elevator_add_req_fn *elevator_add_req_fn; | |
59 | elevator_activate_req_fn *elevator_activate_req_fn; | |
60 | elevator_deactivate_req_fn *elevator_deactivate_req_fn; | |
61 | ||
62 | elevator_completed_req_fn *elevator_completed_req_fn; | |
63 | ||
64 | elevator_request_list_fn *elevator_former_req_fn; | |
65 | elevator_request_list_fn *elevator_latter_req_fn; | |
66 | ||
67 | elevator_init_icq_fn *elevator_init_icq_fn; /* see iocontext.h */ | |
68 | elevator_exit_icq_fn *elevator_exit_icq_fn; /* ditto */ | |
69 | ||
70 | elevator_set_req_fn *elevator_set_req_fn; | |
71 | elevator_put_req_fn *elevator_put_req_fn; | |
72 | ||
73 | elevator_may_queue_fn *elevator_may_queue_fn; | |
74 | ||
75 | elevator_init_fn *elevator_init_fn; | |
76 | elevator_exit_fn *elevator_exit_fn; | |
77 | elevator_registered_fn *elevator_registered_fn; | |
78 | }; | |
79 | ||
80 | #define ELV_NAME_MAX (16) | |
81 | ||
82 | struct elv_fs_entry { | |
83 | struct attribute attr; | |
84 | ssize_t (*show)(struct elevator_queue *, char *); | |
85 | ssize_t (*store)(struct elevator_queue *, const char *, size_t); | |
86 | }; | |
87 | ||
88 | /* | |
89 | * identifies an elevator type, such as AS or deadline | |
90 | */ | |
91 | struct elevator_type | |
92 | { | |
93 | /* managed by elevator core */ | |
94 | struct kmem_cache *icq_cache; | |
95 | ||
96 | /* fields provided by elevator implementation */ | |
97 | struct elevator_ops ops; | |
98 | size_t icq_size; /* see iocontext.h */ | |
99 | size_t icq_align; /* ditto */ | |
100 | struct elv_fs_entry *elevator_attrs; | |
101 | char elevator_name[ELV_NAME_MAX]; | |
102 | struct module *elevator_owner; | |
103 | ||
104 | /* managed by elevator core */ | |
105 | char icq_cache_name[ELV_NAME_MAX + 5]; /* elvname + "_io_cq" */ | |
106 | struct list_head list; | |
107 | }; | |
108 | ||
109 | #define ELV_HASH_BITS 6 | |
110 | ||
111 | void elv_rqhash_del(struct request_queue *q, struct request *rq); | |
112 | void elv_rqhash_add(struct request_queue *q, struct request *rq); | |
113 | void elv_rqhash_reposition(struct request_queue *q, struct request *rq); | |
114 | struct request *elv_rqhash_find(struct request_queue *q, sector_t offset); | |
115 | ||
116 | /* | |
117 | * each queue has an elevator_queue associated with it | |
118 | */ | |
119 | struct elevator_queue | |
120 | { | |
121 | struct elevator_type *type; | |
122 | void *elevator_data; | |
123 | struct kobject kobj; | |
124 | struct mutex sysfs_lock; | |
125 | unsigned int registered:1; | |
126 | DECLARE_HASHTABLE(hash, ELV_HASH_BITS); | |
127 | }; | |
128 | ||
129 | /* | |
130 | * block elevator interface | |
131 | */ | |
132 | extern void elv_dispatch_sort(struct request_queue *, struct request *); | |
133 | extern void elv_dispatch_add_tail(struct request_queue *, struct request *); | |
134 | extern void elv_add_request(struct request_queue *, struct request *, int); | |
135 | extern void __elv_add_request(struct request_queue *, struct request *, int); | |
136 | extern int elv_merge(struct request_queue *, struct request **, struct bio *); | |
137 | extern void elv_merge_requests(struct request_queue *, struct request *, | |
138 | struct request *); | |
139 | extern void elv_merged_request(struct request_queue *, struct request *, int); | |
140 | extern void elv_bio_merged(struct request_queue *q, struct request *, | |
141 | struct bio *); | |
142 | extern void elv_requeue_request(struct request_queue *, struct request *); | |
143 | extern struct request *elv_former_request(struct request_queue *, struct request *); | |
144 | extern struct request *elv_latter_request(struct request_queue *, struct request *); | |
145 | extern int elv_register_queue(struct request_queue *q); | |
146 | extern void elv_unregister_queue(struct request_queue *q); | |
147 | extern int elv_may_queue(struct request_queue *, unsigned int); | |
148 | extern void elv_completed_request(struct request_queue *, struct request *); | |
149 | extern int elv_set_request(struct request_queue *q, struct request *rq, | |
150 | struct bio *bio, gfp_t gfp_mask); | |
151 | extern void elv_put_request(struct request_queue *, struct request *); | |
152 | extern void elv_drain_elevator(struct request_queue *); | |
153 | ||
154 | /* | |
155 | * io scheduler registration | |
156 | */ | |
157 | extern void __init load_default_elevator_module(void); | |
158 | extern int elv_register(struct elevator_type *); | |
159 | extern void elv_unregister(struct elevator_type *); | |
160 | ||
161 | /* | |
162 | * io scheduler sysfs switching | |
163 | */ | |
164 | extern ssize_t elv_iosched_show(struct request_queue *, char *); | |
165 | extern ssize_t elv_iosched_store(struct request_queue *, const char *, size_t); | |
166 | ||
167 | extern int elevator_init(struct request_queue *, char *); | |
168 | extern void elevator_exit(struct elevator_queue *); | |
169 | extern int elevator_change(struct request_queue *, const char *); | |
170 | extern bool elv_bio_merge_ok(struct request *, struct bio *); | |
171 | extern struct elevator_queue *elevator_alloc(struct request_queue *, | |
172 | struct elevator_type *); | |
173 | ||
174 | /* | |
175 | * Helper functions. | |
176 | */ | |
177 | extern struct request *elv_rb_former_request(struct request_queue *, struct request *); | |
178 | extern struct request *elv_rb_latter_request(struct request_queue *, struct request *); | |
179 | ||
180 | /* | |
181 | * rb support functions. | |
182 | */ | |
183 | extern void elv_rb_add(struct rb_root *, struct request *); | |
184 | extern void elv_rb_del(struct rb_root *, struct request *); | |
185 | extern struct request *elv_rb_find(struct rb_root *, sector_t); | |
186 | ||
187 | /* | |
188 | * Return values from elevator merger | |
189 | */ | |
190 | #define ELEVATOR_NO_MERGE 0 | |
191 | #define ELEVATOR_FRONT_MERGE 1 | |
192 | #define ELEVATOR_BACK_MERGE 2 | |
193 | ||
194 | /* | |
195 | * Insertion selection | |
196 | */ | |
197 | #define ELEVATOR_INSERT_FRONT 1 | |
198 | #define ELEVATOR_INSERT_BACK 2 | |
199 | #define ELEVATOR_INSERT_SORT 3 | |
200 | #define ELEVATOR_INSERT_REQUEUE 4 | |
201 | #define ELEVATOR_INSERT_FLUSH 5 | |
202 | #define ELEVATOR_INSERT_SORT_MERGE 6 | |
203 | ||
204 | /* | |
205 | * return values from elevator_may_queue_fn | |
206 | */ | |
207 | enum { | |
208 | ELV_MQUEUE_MAY, | |
209 | ELV_MQUEUE_NO, | |
210 | ELV_MQUEUE_MUST, | |
211 | }; | |
212 | ||
213 | #define rq_end_sector(rq) (blk_rq_pos(rq) + blk_rq_sectors(rq)) | |
214 | #define rb_entry_rq(node) rb_entry((node), struct request, rb_node) | |
215 | ||
216 | #define rq_entry_fifo(ptr) list_entry((ptr), struct request, queuelist) | |
217 | #define rq_fifo_clear(rq) list_del_init(&(rq)->queuelist) | |
218 | ||
219 | #else /* CONFIG_BLOCK */ | |
220 | ||
221 | static inline void load_default_elevator_module(void) { } | |
222 | ||
223 | #endif /* CONFIG_BLOCK */ | |
224 | #endif |