diff options
Diffstat (limited to 'drivers/block/xen-blkback/common.h')
-rw-r--r-- | drivers/block/xen-blkback/common.h | 147 |
1 files changed, 145 insertions, 2 deletions
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 60103e2517ba..8d8807563d99 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h | |||
@@ -50,6 +50,19 @@ | |||
50 | __func__, __LINE__, ##args) | 50 | __func__, __LINE__, ##args) |
51 | 51 | ||
52 | 52 | ||
53 | /* | ||
54 | * This is the maximum number of segments that would be allowed in indirect | ||
55 | * requests. This value will also be passed to the frontend. | ||
56 | */ | ||
57 | #define MAX_INDIRECT_SEGMENTS 256 | ||
58 | |||
59 | #define SEGS_PER_INDIRECT_FRAME \ | ||
60 | (PAGE_SIZE/sizeof(struct blkif_request_segment_aligned)) | ||
61 | #define MAX_INDIRECT_PAGES \ | ||
62 | ((MAX_INDIRECT_SEGMENTS + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME) | ||
63 | #define INDIRECT_PAGES(_segs) \ | ||
64 | ((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME) | ||
65 | |||
53 | /* Not a real protocol. Used to generate ring structs which contain | 66 | /* Not a real protocol. Used to generate ring structs which contain |
54 | * the elements common to all protocols only. This way we get a | 67 | * the elements common to all protocols only. This way we get a |
55 | * compiler-checkable way to use common struct elements, so we can | 68 | * compiler-checkable way to use common struct elements, so we can |
@@ -83,12 +96,31 @@ struct blkif_x86_32_request_other { | |||
83 | uint64_t id; /* private guest value, echoed in resp */ | 96 | uint64_t id; /* private guest value, echoed in resp */ |
84 | } __attribute__((__packed__)); | 97 | } __attribute__((__packed__)); |
85 | 98 | ||
99 | struct blkif_x86_32_request_indirect { | ||
100 | uint8_t indirect_op; | ||
101 | uint16_t nr_segments; | ||
102 | uint64_t id; | ||
103 | blkif_sector_t sector_number; | ||
104 | blkif_vdev_t handle; | ||
105 | uint16_t _pad1; | ||
106 | grant_ref_t indirect_grefs[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST]; | ||
107 | /* | ||
108 | * The maximum number of indirect segments (and pages) that will | ||
109 | * be used is determined by MAX_INDIRECT_SEGMENTS, this value | ||
110 | * is also exported to the guest (via xenstore | ||
111 | * feature-max-indirect-segments entry), so the frontend knows how | ||
112 | * many indirect segments the backend supports. | ||
113 | */ | ||
114 | uint64_t _pad2; /* make it 64 byte aligned */ | ||
115 | } __attribute__((__packed__)); | ||
116 | |||
86 | struct blkif_x86_32_request { | 117 | struct blkif_x86_32_request { |
87 | uint8_t operation; /* BLKIF_OP_??? */ | 118 | uint8_t operation; /* BLKIF_OP_??? */ |
88 | union { | 119 | union { |
89 | struct blkif_x86_32_request_rw rw; | 120 | struct blkif_x86_32_request_rw rw; |
90 | struct blkif_x86_32_request_discard discard; | 121 | struct blkif_x86_32_request_discard discard; |
91 | struct blkif_x86_32_request_other other; | 122 | struct blkif_x86_32_request_other other; |
123 | struct blkif_x86_32_request_indirect indirect; | ||
92 | } u; | 124 | } u; |
93 | } __attribute__((__packed__)); | 125 | } __attribute__((__packed__)); |
94 | 126 | ||
@@ -127,12 +159,32 @@ struct blkif_x86_64_request_other { | |||
127 | uint64_t id; /* private guest value, echoed in resp */ | 159 | uint64_t id; /* private guest value, echoed in resp */ |
128 | } __attribute__((__packed__)); | 160 | } __attribute__((__packed__)); |
129 | 161 | ||
162 | struct blkif_x86_64_request_indirect { | ||
163 | uint8_t indirect_op; | ||
164 | uint16_t nr_segments; | ||
165 | uint32_t _pad1; /* offsetof(blkif_..,u.indirect.id)==8 */ | ||
166 | uint64_t id; | ||
167 | blkif_sector_t sector_number; | ||
168 | blkif_vdev_t handle; | ||
169 | uint16_t _pad2; | ||
170 | grant_ref_t indirect_grefs[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST]; | ||
171 | /* | ||
172 | * The maximum number of indirect segments (and pages) that will | ||
173 | * be used is determined by MAX_INDIRECT_SEGMENTS, this value | ||
174 | * is also exported to the guest (via xenstore | ||
175 | * feature-max-indirect-segments entry), so the frontend knows how | ||
176 | * many indirect segments the backend supports. | ||
177 | */ | ||
178 | uint32_t _pad3; /* make it 64 byte aligned */ | ||
179 | } __attribute__((__packed__)); | ||
180 | |||
130 | struct blkif_x86_64_request { | 181 | struct blkif_x86_64_request { |
131 | uint8_t operation; /* BLKIF_OP_??? */ | 182 | uint8_t operation; /* BLKIF_OP_??? */ |
132 | union { | 183 | union { |
133 | struct blkif_x86_64_request_rw rw; | 184 | struct blkif_x86_64_request_rw rw; |
134 | struct blkif_x86_64_request_discard discard; | 185 | struct blkif_x86_64_request_discard discard; |
135 | struct blkif_x86_64_request_other other; | 186 | struct blkif_x86_64_request_other other; |
187 | struct blkif_x86_64_request_indirect indirect; | ||
136 | } u; | 188 | } u; |
137 | } __attribute__((__packed__)); | 189 | } __attribute__((__packed__)); |
138 | 190 | ||
@@ -182,12 +234,26 @@ struct xen_vbd { | |||
182 | 234 | ||
183 | struct backend_info; | 235 | struct backend_info; |
184 | 236 | ||
237 | /* Number of available flags */ | ||
238 | #define PERSISTENT_GNT_FLAGS_SIZE 2 | ||
239 | /* This persistent grant is currently in use */ | ||
240 | #define PERSISTENT_GNT_ACTIVE 0 | ||
241 | /* | ||
242 | * This persistent grant has been used, this flag is set when we remove the | ||
243 | * PERSISTENT_GNT_ACTIVE, to know that this grant has been used recently. | ||
244 | */ | ||
245 | #define PERSISTENT_GNT_WAS_ACTIVE 1 | ||
246 | |||
247 | /* Number of requests that we can fit in a ring */ | ||
248 | #define XEN_BLKIF_REQS 32 | ||
185 | 249 | ||
186 | struct persistent_gnt { | 250 | struct persistent_gnt { |
187 | struct page *page; | 251 | struct page *page; |
188 | grant_ref_t gnt; | 252 | grant_ref_t gnt; |
189 | grant_handle_t handle; | 253 | grant_handle_t handle; |
254 | DECLARE_BITMAP(flags, PERSISTENT_GNT_FLAGS_SIZE); | ||
190 | struct rb_node node; | 255 | struct rb_node node; |
256 | struct list_head remove_node; | ||
191 | }; | 257 | }; |
192 | 258 | ||
193 | struct xen_blkif { | 259 | struct xen_blkif { |
@@ -219,6 +285,23 @@ struct xen_blkif { | |||
219 | /* tree to store persistent grants */ | 285 | /* tree to store persistent grants */ |
220 | struct rb_root persistent_gnts; | 286 | struct rb_root persistent_gnts; |
221 | unsigned int persistent_gnt_c; | 287 | unsigned int persistent_gnt_c; |
288 | atomic_t persistent_gnt_in_use; | ||
289 | unsigned long next_lru; | ||
290 | |||
291 | /* used by the kworker that offload work from the persistent purge */ | ||
292 | struct list_head persistent_purge_list; | ||
293 | struct work_struct persistent_purge_work; | ||
294 | |||
295 | /* buffer of free pages to map grant refs */ | ||
296 | spinlock_t free_pages_lock; | ||
297 | int free_pages_num; | ||
298 | struct list_head free_pages; | ||
299 | |||
300 | /* List of all 'pending_req' available */ | ||
301 | struct list_head pending_free; | ||
302 | /* And its spinlock. */ | ||
303 | spinlock_t pending_free_lock; | ||
304 | wait_queue_head_t pending_free_wq; | ||
222 | 305 | ||
223 | /* statistics */ | 306 | /* statistics */ |
224 | unsigned long st_print; | 307 | unsigned long st_print; |
@@ -231,6 +314,41 @@ struct xen_blkif { | |||
231 | unsigned long long st_wr_sect; | 314 | unsigned long long st_wr_sect; |
232 | 315 | ||
233 | wait_queue_head_t waiting_to_free; | 316 | wait_queue_head_t waiting_to_free; |
317 | /* Thread shutdown wait queue. */ | ||
318 | wait_queue_head_t shutdown_wq; | ||
319 | }; | ||
320 | |||
321 | struct seg_buf { | ||
322 | unsigned long offset; | ||
323 | unsigned int nsec; | ||
324 | }; | ||
325 | |||
326 | struct grant_page { | ||
327 | struct page *page; | ||
328 | struct persistent_gnt *persistent_gnt; | ||
329 | grant_handle_t handle; | ||
330 | grant_ref_t gref; | ||
331 | }; | ||
332 | |||
333 | /* | ||
334 | * Each outstanding request that we've passed to the lower device layers has a | ||
335 | * 'pending_req' allocated to it. Each buffer_head that completes decrements | ||
336 | * the pendcnt towards zero. When it hits zero, the specified domain has a | ||
337 | * response queued for it, with the saved 'id' passed back. | ||
338 | */ | ||
339 | struct pending_req { | ||
340 | struct xen_blkif *blkif; | ||
341 | u64 id; | ||
342 | int nr_pages; | ||
343 | atomic_t pendcnt; | ||
344 | unsigned short operation; | ||
345 | int status; | ||
346 | struct list_head free_list; | ||
347 | struct grant_page *segments[MAX_INDIRECT_SEGMENTS]; | ||
348 | /* Indirect descriptors */ | ||
349 | struct grant_page *indirect_pages[MAX_INDIRECT_PAGES]; | ||
350 | struct seg_buf seg[MAX_INDIRECT_SEGMENTS]; | ||
351 | struct bio *biolist[MAX_INDIRECT_SEGMENTS]; | ||
234 | }; | 352 | }; |
235 | 353 | ||
236 | 354 | ||
@@ -257,6 +375,7 @@ int xen_blkif_xenbus_init(void); | |||
257 | 375 | ||
258 | irqreturn_t xen_blkif_be_int(int irq, void *dev_id); | 376 | irqreturn_t xen_blkif_be_int(int irq, void *dev_id); |
259 | int xen_blkif_schedule(void *arg); | 377 | int xen_blkif_schedule(void *arg); |
378 | int xen_blkif_purge_persistent(void *arg); | ||
260 | 379 | ||
261 | int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, | 380 | int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, |
262 | struct backend_info *be, int state); | 381 | struct backend_info *be, int state); |
@@ -268,7 +387,7 @@ struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be); | |||
268 | static inline void blkif_get_x86_32_req(struct blkif_request *dst, | 387 | static inline void blkif_get_x86_32_req(struct blkif_request *dst, |
269 | struct blkif_x86_32_request *src) | 388 | struct blkif_x86_32_request *src) |
270 | { | 389 | { |
271 | int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; | 390 | int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j; |
272 | dst->operation = src->operation; | 391 | dst->operation = src->operation; |
273 | switch (src->operation) { | 392 | switch (src->operation) { |
274 | case BLKIF_OP_READ: | 393 | case BLKIF_OP_READ: |
@@ -291,6 +410,18 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, | |||
291 | dst->u.discard.sector_number = src->u.discard.sector_number; | 410 | dst->u.discard.sector_number = src->u.discard.sector_number; |
292 | dst->u.discard.nr_sectors = src->u.discard.nr_sectors; | 411 | dst->u.discard.nr_sectors = src->u.discard.nr_sectors; |
293 | break; | 412 | break; |
413 | case BLKIF_OP_INDIRECT: | ||
414 | dst->u.indirect.indirect_op = src->u.indirect.indirect_op; | ||
415 | dst->u.indirect.nr_segments = src->u.indirect.nr_segments; | ||
416 | dst->u.indirect.handle = src->u.indirect.handle; | ||
417 | dst->u.indirect.id = src->u.indirect.id; | ||
418 | dst->u.indirect.sector_number = src->u.indirect.sector_number; | ||
419 | barrier(); | ||
420 | j = min(MAX_INDIRECT_PAGES, INDIRECT_PAGES(dst->u.indirect.nr_segments)); | ||
421 | for (i = 0; i < j; i++) | ||
422 | dst->u.indirect.indirect_grefs[i] = | ||
423 | src->u.indirect.indirect_grefs[i]; | ||
424 | break; | ||
294 | default: | 425 | default: |
295 | /* | 426 | /* |
296 | * Don't know how to translate this op. Only get the | 427 | * Don't know how to translate this op. Only get the |
@@ -304,7 +435,7 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, | |||
304 | static inline void blkif_get_x86_64_req(struct blkif_request *dst, | 435 | static inline void blkif_get_x86_64_req(struct blkif_request *dst, |
305 | struct blkif_x86_64_request *src) | 436 | struct blkif_x86_64_request *src) |
306 | { | 437 | { |
307 | int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; | 438 | int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j; |
308 | dst->operation = src->operation; | 439 | dst->operation = src->operation; |
309 | switch (src->operation) { | 440 | switch (src->operation) { |
310 | case BLKIF_OP_READ: | 441 | case BLKIF_OP_READ: |
@@ -327,6 +458,18 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, | |||
327 | dst->u.discard.sector_number = src->u.discard.sector_number; | 458 | dst->u.discard.sector_number = src->u.discard.sector_number; |
328 | dst->u.discard.nr_sectors = src->u.discard.nr_sectors; | 459 | dst->u.discard.nr_sectors = src->u.discard.nr_sectors; |
329 | break; | 460 | break; |
461 | case BLKIF_OP_INDIRECT: | ||
462 | dst->u.indirect.indirect_op = src->u.indirect.indirect_op; | ||
463 | dst->u.indirect.nr_segments = src->u.indirect.nr_segments; | ||
464 | dst->u.indirect.handle = src->u.indirect.handle; | ||
465 | dst->u.indirect.id = src->u.indirect.id; | ||
466 | dst->u.indirect.sector_number = src->u.indirect.sector_number; | ||
467 | barrier(); | ||
468 | j = min(MAX_INDIRECT_PAGES, INDIRECT_PAGES(dst->u.indirect.nr_segments)); | ||
469 | for (i = 0; i < j; i++) | ||
470 | dst->u.indirect.indirect_grefs[i] = | ||
471 | src->u.indirect.indirect_grefs[i]; | ||
472 | break; | ||
330 | default: | 473 | default: |
331 | /* | 474 | /* |
332 | * Don't know how to translate this op. Only get the | 475 | * Don't know how to translate this op. Only get the |