diff options
-rw-r--r-- | Documentation/ABI/stable/sysfs-bus-xen-backend | 8 | ||||
-rw-r--r-- | drivers/block/xen-blkback/blkback.c | 286 | ||||
-rw-r--r-- | drivers/block/xen-blkback/common.h | 5 | ||||
-rw-r--r-- | drivers/block/xen-blkback/xenbus.c | 3 |
4 files changed, 181 insertions, 121 deletions
diff --git a/Documentation/ABI/stable/sysfs-bus-xen-backend b/Documentation/ABI/stable/sysfs-bus-xen-backend index 3d5951c8bf5f..e04afe0cca99 100644 --- a/Documentation/ABI/stable/sysfs-bus-xen-backend +++ b/Documentation/ABI/stable/sysfs-bus-xen-backend | |||
@@ -73,3 +73,11 @@ KernelVersion: 3.0 | |||
73 | Contact: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 73 | Contact: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> |
74 | Description: | 74 | Description: |
75 | Number of sectors written by the frontend. | 75 | Number of sectors written by the frontend. |
76 | |||
77 | What: /sys/module/xen_blkback/parameters/max_buffer_pages | ||
78 | Date: March 2013 | ||
79 | KernelVersion: 3.10 | ||
80 | Contact: Roger Pau Monné <roger.pau@citrix.com> | ||
81 | Description: | ||
82 | Maximum number of free pages to keep in each block | ||
83 | backend buffer. | ||
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index f7526dbb204d..8245c6bb9539 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
@@ -63,6 +63,21 @@ static int xen_blkif_reqs = 64; | |||
63 | module_param_named(reqs, xen_blkif_reqs, int, 0); | 63 | module_param_named(reqs, xen_blkif_reqs, int, 0); |
64 | MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate"); | 64 | MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate"); |
65 | 65 | ||
66 | /* | ||
67 | * Maximum number of unused free pages to keep in the internal buffer. | ||
68 | * Setting this to a value too low will reduce memory used in each backend, | ||
69 | * but can have a performance penalty. | ||
70 | * | ||
71 | * A sane value is xen_blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST, but can | ||
72 | * be set to a lower value that might degrade performance on some intensive | ||
73 | * IO workloads. | ||
74 | */ | ||
75 | |||
76 | static int xen_blkif_max_buffer_pages = 704; | ||
77 | module_param_named(max_buffer_pages, xen_blkif_max_buffer_pages, int, 0644); | ||
78 | MODULE_PARM_DESC(max_buffer_pages, | ||
79 | "Maximum number of free pages to keep in each block backend buffer"); | ||
80 | |||
66 | /* Run-time switchable: /sys/module/blkback/parameters/ */ | 81 | /* Run-time switchable: /sys/module/blkback/parameters/ */ |
67 | static unsigned int log_stats; | 82 | static unsigned int log_stats; |
68 | module_param(log_stats, int, 0644); | 83 | module_param(log_stats, int, 0644); |
@@ -82,10 +97,14 @@ struct pending_req { | |||
82 | int status; | 97 | int status; |
83 | struct list_head free_list; | 98 | struct list_head free_list; |
84 | DECLARE_BITMAP(unmap_seg, BLKIF_MAX_SEGMENTS_PER_REQUEST); | 99 | DECLARE_BITMAP(unmap_seg, BLKIF_MAX_SEGMENTS_PER_REQUEST); |
100 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | ||
85 | }; | 101 | }; |
86 | 102 | ||
87 | #define BLKBACK_INVALID_HANDLE (~0) | 103 | #define BLKBACK_INVALID_HANDLE (~0) |
88 | 104 | ||
105 | /* Number of free pages to remove on each call to free_xenballooned_pages */ | ||
106 | #define NUM_BATCH_FREE_PAGES 10 | ||
107 | |||
89 | struct xen_blkbk { | 108 | struct xen_blkbk { |
90 | struct pending_req *pending_reqs; | 109 | struct pending_req *pending_reqs; |
91 | /* List of all 'pending_req' available */ | 110 | /* List of all 'pending_req' available */ |
@@ -93,8 +112,6 @@ struct xen_blkbk { | |||
93 | /* And its spinlock. */ | 112 | /* And its spinlock. */ |
94 | spinlock_t pending_free_lock; | 113 | spinlock_t pending_free_lock; |
95 | wait_queue_head_t pending_free_wq; | 114 | wait_queue_head_t pending_free_wq; |
96 | /* The list of all pages that are available. */ | ||
97 | struct page **pending_pages; | ||
98 | /* And the grant handles that are available. */ | 115 | /* And the grant handles that are available. */ |
99 | grant_handle_t *pending_grant_handles; | 116 | grant_handle_t *pending_grant_handles; |
100 | }; | 117 | }; |
@@ -143,14 +160,66 @@ static inline int vaddr_pagenr(struct pending_req *req, int seg) | |||
143 | BLKIF_MAX_SEGMENTS_PER_REQUEST + seg; | 160 | BLKIF_MAX_SEGMENTS_PER_REQUEST + seg; |
144 | } | 161 | } |
145 | 162 | ||
146 | #define pending_page(req, seg) pending_pages[vaddr_pagenr(req, seg)] | 163 | static inline int get_free_page(struct xen_blkif *blkif, struct page **page) |
164 | { | ||
165 | unsigned long flags; | ||
166 | |||
167 | spin_lock_irqsave(&blkif->free_pages_lock, flags); | ||
168 | if (list_empty(&blkif->free_pages)) { | ||
169 | BUG_ON(blkif->free_pages_num != 0); | ||
170 | spin_unlock_irqrestore(&blkif->free_pages_lock, flags); | ||
171 | return alloc_xenballooned_pages(1, page, false); | ||
172 | } | ||
173 | BUG_ON(blkif->free_pages_num == 0); | ||
174 | page[0] = list_first_entry(&blkif->free_pages, struct page, lru); | ||
175 | list_del(&page[0]->lru); | ||
176 | blkif->free_pages_num--; | ||
177 | spin_unlock_irqrestore(&blkif->free_pages_lock, flags); | ||
147 | 178 | ||
148 | static inline unsigned long vaddr(struct pending_req *req, int seg) | 179 | return 0; |
180 | } | ||
181 | |||
182 | static inline void put_free_pages(struct xen_blkif *blkif, struct page **page, | ||
183 | int num) | ||
149 | { | 184 | { |
150 | unsigned long pfn = page_to_pfn(blkbk->pending_page(req, seg)); | 185 | unsigned long flags; |
151 | return (unsigned long)pfn_to_kaddr(pfn); | 186 | int i; |
187 | |||
188 | spin_lock_irqsave(&blkif->free_pages_lock, flags); | ||
189 | for (i = 0; i < num; i++) | ||
190 | list_add(&page[i]->lru, &blkif->free_pages); | ||
191 | blkif->free_pages_num += num; | ||
192 | spin_unlock_irqrestore(&blkif->free_pages_lock, flags); | ||
193 | } | ||
194 | |||
195 | static inline void shrink_free_pagepool(struct xen_blkif *blkif, int num) | ||
196 | { | ||
197 | /* Remove requested pages in batches of NUM_BATCH_FREE_PAGES */ | ||
198 | struct page *page[NUM_BATCH_FREE_PAGES]; | ||
199 | unsigned int num_pages = 0; | ||
200 | unsigned long flags; | ||
201 | |||
202 | spin_lock_irqsave(&blkif->free_pages_lock, flags); | ||
203 | while (blkif->free_pages_num > num) { | ||
204 | BUG_ON(list_empty(&blkif->free_pages)); | ||
205 | page[num_pages] = list_first_entry(&blkif->free_pages, | ||
206 | struct page, lru); | ||
207 | list_del(&page[num_pages]->lru); | ||
208 | blkif->free_pages_num--; | ||
209 | if (++num_pages == NUM_BATCH_FREE_PAGES) { | ||
210 | spin_unlock_irqrestore(&blkif->free_pages_lock, flags); | ||
211 | free_xenballooned_pages(num_pages, page); | ||
212 | spin_lock_irqsave(&blkif->free_pages_lock, flags); | ||
213 | num_pages = 0; | ||
214 | } | ||
215 | } | ||
216 | spin_unlock_irqrestore(&blkif->free_pages_lock, flags); | ||
217 | if (num_pages != 0) | ||
218 | free_xenballooned_pages(num_pages, page); | ||
152 | } | 219 | } |
153 | 220 | ||
221 | #define vaddr(page) ((unsigned long)pfn_to_kaddr(page_to_pfn(page))) | ||
222 | |||
154 | #define pending_handle(_req, _seg) \ | 223 | #define pending_handle(_req, _seg) \ |
155 | (blkbk->pending_grant_handles[vaddr_pagenr(_req, _seg)]) | 224 | (blkbk->pending_grant_handles[vaddr_pagenr(_req, _seg)]) |
156 | 225 | ||
@@ -170,7 +239,7 @@ static void make_response(struct xen_blkif *blkif, u64 id, | |||
170 | (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL) | 239 | (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL) |
171 | 240 | ||
172 | 241 | ||
173 | static void add_persistent_gnt(struct rb_root *root, | 242 | static int add_persistent_gnt(struct rb_root *root, |
174 | struct persistent_gnt *persistent_gnt) | 243 | struct persistent_gnt *persistent_gnt) |
175 | { | 244 | { |
176 | struct rb_node **new = &(root->rb_node), *parent = NULL; | 245 | struct rb_node **new = &(root->rb_node), *parent = NULL; |
@@ -186,14 +255,15 @@ static void add_persistent_gnt(struct rb_root *root, | |||
186 | else if (persistent_gnt->gnt > this->gnt) | 255 | else if (persistent_gnt->gnt > this->gnt) |
187 | new = &((*new)->rb_right); | 256 | new = &((*new)->rb_right); |
188 | else { | 257 | else { |
189 | pr_alert(DRV_PFX " trying to add a gref that's already in the tree\n"); | 258 | pr_alert_ratelimited(DRV_PFX " trying to add a gref that's already in the tree\n"); |
190 | BUG(); | 259 | return -EINVAL; |
191 | } | 260 | } |
192 | } | 261 | } |
193 | 262 | ||
194 | /* Add new node and rebalance tree. */ | 263 | /* Add new node and rebalance tree. */ |
195 | rb_link_node(&(persistent_gnt->node), parent, new); | 264 | rb_link_node(&(persistent_gnt->node), parent, new); |
196 | rb_insert_color(&(persistent_gnt->node), root); | 265 | rb_insert_color(&(persistent_gnt->node), root); |
266 | return 0; | ||
197 | } | 267 | } |
198 | 268 | ||
199 | static struct persistent_gnt *get_persistent_gnt(struct rb_root *root, | 269 | static struct persistent_gnt *get_persistent_gnt(struct rb_root *root, |
@@ -215,7 +285,8 @@ static struct persistent_gnt *get_persistent_gnt(struct rb_root *root, | |||
215 | return NULL; | 285 | return NULL; |
216 | } | 286 | } |
217 | 287 | ||
218 | static void free_persistent_gnts(struct rb_root *root, unsigned int num) | 288 | static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, |
289 | unsigned int num) | ||
219 | { | 290 | { |
220 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 291 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
221 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 292 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
@@ -240,7 +311,7 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num) | |||
240 | ret = gnttab_unmap_refs(unmap, NULL, pages, | 311 | ret = gnttab_unmap_refs(unmap, NULL, pages, |
241 | segs_to_unmap); | 312 | segs_to_unmap); |
242 | BUG_ON(ret); | 313 | BUG_ON(ret); |
243 | free_xenballooned_pages(segs_to_unmap, pages); | 314 | put_free_pages(blkif, pages, segs_to_unmap); |
244 | segs_to_unmap = 0; | 315 | segs_to_unmap = 0; |
245 | } | 316 | } |
246 | 317 | ||
@@ -422,13 +493,19 @@ int xen_blkif_schedule(void *arg) | |||
422 | if (do_block_io_op(blkif)) | 493 | if (do_block_io_op(blkif)) |
423 | blkif->waiting_reqs = 1; | 494 | blkif->waiting_reqs = 1; |
424 | 495 | ||
496 | /* Shrink if we have more than xen_blkif_max_buffer_pages */ | ||
497 | shrink_free_pagepool(blkif, xen_blkif_max_buffer_pages); | ||
498 | |||
425 | if (log_stats && time_after(jiffies, blkif->st_print)) | 499 | if (log_stats && time_after(jiffies, blkif->st_print)) |
426 | print_stats(blkif); | 500 | print_stats(blkif); |
427 | } | 501 | } |
428 | 502 | ||
503 | /* Since we are shutting down remove all pages from the buffer */ | ||
504 | shrink_free_pagepool(blkif, 0 /* All */); | ||
505 | |||
429 | /* Free all persistent grant pages */ | 506 | /* Free all persistent grant pages */ |
430 | if (!RB_EMPTY_ROOT(&blkif->persistent_gnts)) | 507 | if (!RB_EMPTY_ROOT(&blkif->persistent_gnts)) |
431 | free_persistent_gnts(&blkif->persistent_gnts, | 508 | free_persistent_gnts(blkif, &blkif->persistent_gnts, |
432 | blkif->persistent_gnt_c); | 509 | blkif->persistent_gnt_c); |
433 | 510 | ||
434 | BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); | 511 | BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); |
@@ -457,23 +534,25 @@ static void xen_blkbk_unmap(struct pending_req *req) | |||
457 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 534 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
458 | unsigned int i, invcount = 0; | 535 | unsigned int i, invcount = 0; |
459 | grant_handle_t handle; | 536 | grant_handle_t handle; |
537 | struct xen_blkif *blkif = req->blkif; | ||
460 | int ret; | 538 | int ret; |
461 | 539 | ||
462 | for (i = 0; i < req->nr_pages; i++) { | 540 | for (i = 0; i < req->nr_pages; i++) { |
463 | if (!test_bit(i, req->unmap_seg)) | 541 | if (!test_bit(i, req->unmap_seg)) |
464 | continue; | 542 | continue; |
465 | handle = pending_handle(req, i); | 543 | handle = pending_handle(req, i); |
544 | pages[invcount] = req->pages[i]; | ||
466 | if (handle == BLKBACK_INVALID_HANDLE) | 545 | if (handle == BLKBACK_INVALID_HANDLE) |
467 | continue; | 546 | continue; |
468 | gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i), | 547 | gnttab_set_unmap_op(&unmap[invcount], vaddr(pages[invcount]), |
469 | GNTMAP_host_map, handle); | 548 | GNTMAP_host_map, handle); |
470 | pending_handle(req, i) = BLKBACK_INVALID_HANDLE; | 549 | pending_handle(req, i) = BLKBACK_INVALID_HANDLE; |
471 | pages[invcount] = virt_to_page(vaddr(req, i)); | ||
472 | invcount++; | 550 | invcount++; |
473 | } | 551 | } |
474 | 552 | ||
475 | ret = gnttab_unmap_refs(unmap, NULL, pages, invcount); | 553 | ret = gnttab_unmap_refs(unmap, NULL, pages, invcount); |
476 | BUG_ON(ret); | 554 | BUG_ON(ret); |
555 | put_free_pages(blkif, pages, invcount); | ||
477 | } | 556 | } |
478 | 557 | ||
479 | static int xen_blkbk_map(struct blkif_request *req, | 558 | static int xen_blkbk_map(struct blkif_request *req, |
@@ -487,8 +566,7 @@ static int xen_blkbk_map(struct blkif_request *req, | |||
487 | struct persistent_gnt *persistent_gnt = NULL; | 566 | struct persistent_gnt *persistent_gnt = NULL; |
488 | struct xen_blkif *blkif = pending_req->blkif; | 567 | struct xen_blkif *blkif = pending_req->blkif; |
489 | phys_addr_t addr = 0; | 568 | phys_addr_t addr = 0; |
490 | int i, j; | 569 | int i, seg_idx, new_map_idx; |
491 | bool new_map; | ||
492 | int nseg = req->u.rw.nr_segments; | 570 | int nseg = req->u.rw.nr_segments; |
493 | int segs_to_map = 0; | 571 | int segs_to_map = 0; |
494 | int ret = 0; | 572 | int ret = 0; |
@@ -517,68 +595,16 @@ static int xen_blkbk_map(struct blkif_request *req, | |||
517 | * We are using persistent grants and | 595 | * We are using persistent grants and |
518 | * the grant is already mapped | 596 | * the grant is already mapped |
519 | */ | 597 | */ |
520 | new_map = false; | ||
521 | } else if (use_persistent_gnts && | ||
522 | blkif->persistent_gnt_c < | ||
523 | max_mapped_grant_pages(blkif->blk_protocol)) { | ||
524 | /* | ||
525 | * We are using persistent grants, the grant is | ||
526 | * not mapped but we have room for it | ||
527 | */ | ||
528 | new_map = true; | ||
529 | persistent_gnt = kmalloc( | ||
530 | sizeof(struct persistent_gnt), | ||
531 | GFP_KERNEL); | ||
532 | if (!persistent_gnt) | ||
533 | return -ENOMEM; | ||
534 | if (alloc_xenballooned_pages(1, &persistent_gnt->page, | ||
535 | false)) { | ||
536 | kfree(persistent_gnt); | ||
537 | return -ENOMEM; | ||
538 | } | ||
539 | persistent_gnt->gnt = req->u.rw.seg[i].gref; | ||
540 | persistent_gnt->handle = BLKBACK_INVALID_HANDLE; | ||
541 | |||
542 | pages_to_gnt[segs_to_map] = | ||
543 | persistent_gnt->page; | ||
544 | addr = (unsigned long) pfn_to_kaddr( | ||
545 | page_to_pfn(persistent_gnt->page)); | ||
546 | |||
547 | add_persistent_gnt(&blkif->persistent_gnts, | ||
548 | persistent_gnt); | ||
549 | blkif->persistent_gnt_c++; | ||
550 | pr_debug(DRV_PFX " grant %u added to the tree of persistent grants, using %u/%u\n", | ||
551 | persistent_gnt->gnt, blkif->persistent_gnt_c, | ||
552 | max_mapped_grant_pages(blkif->blk_protocol)); | ||
553 | } else { | ||
554 | /* | ||
555 | * We are either using persistent grants and | ||
556 | * hit the maximum limit of grants mapped, | ||
557 | * or we are not using persistent grants. | ||
558 | */ | ||
559 | if (use_persistent_gnts && | ||
560 | !blkif->vbd.overflow_max_grants) { | ||
561 | blkif->vbd.overflow_max_grants = 1; | ||
562 | pr_alert(DRV_PFX " domain %u, device %#x is using maximum number of persistent grants\n", | ||
563 | blkif->domid, blkif->vbd.handle); | ||
564 | } | ||
565 | new_map = true; | ||
566 | pages[i] = blkbk->pending_page(pending_req, i); | ||
567 | addr = vaddr(pending_req, i); | ||
568 | pages_to_gnt[segs_to_map] = | ||
569 | blkbk->pending_page(pending_req, i); | ||
570 | } | ||
571 | |||
572 | if (persistent_gnt) { | ||
573 | pages[i] = persistent_gnt->page; | 598 | pages[i] = persistent_gnt->page; |
574 | persistent_gnts[i] = persistent_gnt; | 599 | persistent_gnts[i] = persistent_gnt; |
575 | } else { | 600 | } else { |
601 | if (get_free_page(blkif, &pages[i])) | ||
602 | goto out_of_memory; | ||
603 | addr = vaddr(pages[i]); | ||
604 | pages_to_gnt[segs_to_map] = pages[i]; | ||
576 | persistent_gnts[i] = NULL; | 605 | persistent_gnts[i] = NULL; |
577 | } | ||
578 | |||
579 | if (new_map) { | ||
580 | flags = GNTMAP_host_map; | 606 | flags = GNTMAP_host_map; |
581 | if (!persistent_gnt && | 607 | if (!use_persistent_gnts && |
582 | (pending_req->operation != BLKIF_OP_READ)) | 608 | (pending_req->operation != BLKIF_OP_READ)) |
583 | flags |= GNTMAP_readonly; | 609 | flags |= GNTMAP_readonly; |
584 | gnttab_set_map_op(&map[segs_to_map++], addr, | 610 | gnttab_set_map_op(&map[segs_to_map++], addr, |
@@ -598,48 +624,81 @@ static int xen_blkbk_map(struct blkif_request *req, | |||
598 | * the page from the other domain. | 624 | * the page from the other domain. |
599 | */ | 625 | */ |
600 | bitmap_zero(pending_req->unmap_seg, BLKIF_MAX_SEGMENTS_PER_REQUEST); | 626 | bitmap_zero(pending_req->unmap_seg, BLKIF_MAX_SEGMENTS_PER_REQUEST); |
601 | for (i = 0, j = 0; i < nseg; i++) { | 627 | for (seg_idx = 0, new_map_idx = 0; seg_idx < nseg; seg_idx++) { |
602 | if (!persistent_gnts[i] || | 628 | if (!persistent_gnts[seg_idx]) { |
603 | persistent_gnts[i]->handle == BLKBACK_INVALID_HANDLE) { | ||
604 | /* This is a newly mapped grant */ | 629 | /* This is a newly mapped grant */ |
605 | BUG_ON(j >= segs_to_map); | 630 | BUG_ON(new_map_idx >= segs_to_map); |
606 | if (unlikely(map[j].status != 0)) { | 631 | if (unlikely(map[new_map_idx].status != 0)) { |
607 | pr_debug(DRV_PFX "invalid buffer -- could not remap it\n"); | 632 | pr_debug(DRV_PFX "invalid buffer -- could not remap it\n"); |
608 | map[j].handle = BLKBACK_INVALID_HANDLE; | 633 | pending_handle(pending_req, seg_idx) = BLKBACK_INVALID_HANDLE; |
609 | ret |= 1; | 634 | ret |= 1; |
610 | if (persistent_gnts[i]) { | 635 | new_map_idx++; |
611 | rb_erase(&persistent_gnts[i]->node, | 636 | /* |
612 | &blkif->persistent_gnts); | 637 | * No need to set unmap_seg bit, since |
613 | blkif->persistent_gnt_c--; | 638 | * we can not unmap this grant because |
614 | kfree(persistent_gnts[i]); | 639 | * the handle is invalid. |
615 | persistent_gnts[i] = NULL; | 640 | */ |
616 | } | 641 | continue; |
617 | } | 642 | } |
643 | pending_handle(pending_req, seg_idx) = map[new_map_idx].handle; | ||
644 | } else { | ||
645 | /* This grant is persistent and already mapped */ | ||
646 | goto next; | ||
618 | } | 647 | } |
619 | if (persistent_gnts[i]) { | 648 | if (use_persistent_gnts && |
620 | if (persistent_gnts[i]->handle == | 649 | blkif->persistent_gnt_c < |
621 | BLKBACK_INVALID_HANDLE) { | 650 | max_mapped_grant_pages(blkif->blk_protocol)) { |
651 | /* | ||
652 | * We are using persistent grants, the grant is | ||
653 | * not mapped but we have room for it | ||
654 | */ | ||
655 | persistent_gnt = kmalloc(sizeof(struct persistent_gnt), | ||
656 | GFP_KERNEL); | ||
657 | if (!persistent_gnt) { | ||
622 | /* | 658 | /* |
623 | * If this is a new persistent grant | 659 | * If we don't have enough memory to |
624 | * save the handler | 660 | * allocate the persistent_gnt struct |
661 | * map this grant non-persistenly | ||
625 | */ | 662 | */ |
626 | persistent_gnts[i]->handle = map[j++].handle; | 663 | goto next_unmap; |
627 | } | 664 | } |
628 | pending_handle(pending_req, i) = | 665 | persistent_gnt->gnt = map[new_map_idx].ref; |
629 | persistent_gnts[i]->handle; | 666 | persistent_gnt->handle = map[new_map_idx].handle; |
630 | 667 | persistent_gnt->page = pages[seg_idx]; | |
631 | if (ret) | 668 | if (add_persistent_gnt(&blkif->persistent_gnts, |
632 | continue; | 669 | persistent_gnt)) { |
633 | } else { | 670 | kfree(persistent_gnt); |
634 | pending_handle(pending_req, i) = map[j++].handle; | 671 | persistent_gnt = NULL; |
635 | bitmap_set(pending_req->unmap_seg, i, 1); | 672 | goto next_unmap; |
636 | 673 | } | |
637 | if (ret) | 674 | blkif->persistent_gnt_c++; |
638 | continue; | 675 | pr_debug(DRV_PFX " grant %u added to the tree of persistent grants, using %u/%u\n", |
676 | persistent_gnt->gnt, blkif->persistent_gnt_c, | ||
677 | max_mapped_grant_pages(blkif->blk_protocol)); | ||
678 | new_map_idx++; | ||
679 | goto next; | ||
680 | } | ||
681 | if (use_persistent_gnts && !blkif->vbd.overflow_max_grants) { | ||
682 | blkif->vbd.overflow_max_grants = 1; | ||
683 | pr_debug(DRV_PFX " domain %u, device %#x is using maximum number of persistent grants\n", | ||
684 | blkif->domid, blkif->vbd.handle); | ||
639 | } | 685 | } |
640 | seg[i].offset = (req->u.rw.seg[i].first_sect << 9); | 686 | next_unmap: |
687 | /* | ||
688 | * We could not map this grant persistently, so use it as | ||
689 | * a non-persistent grant. | ||
690 | */ | ||
691 | bitmap_set(pending_req->unmap_seg, seg_idx, 1); | ||
692 | new_map_idx++; | ||
693 | next: | ||
694 | seg[seg_idx].offset = (req->u.rw.seg[seg_idx].first_sect << 9); | ||
641 | } | 695 | } |
642 | return ret; | 696 | return ret; |
697 | |||
698 | out_of_memory: | ||
699 | pr_alert(DRV_PFX "%s: out of memory\n", __func__); | ||
700 | put_free_pages(blkif, pages_to_gnt, segs_to_map); | ||
701 | return -ENOMEM; | ||
643 | } | 702 | } |
644 | 703 | ||
645 | static int dispatch_discard_io(struct xen_blkif *blkif, | 704 | static int dispatch_discard_io(struct xen_blkif *blkif, |
@@ -863,7 +922,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, | |||
863 | int operation; | 922 | int operation; |
864 | struct blk_plug plug; | 923 | struct blk_plug plug; |
865 | bool drain = false; | 924 | bool drain = false; |
866 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 925 | struct page **pages = pending_req->pages; |
867 | 926 | ||
868 | switch (req->operation) { | 927 | switch (req->operation) { |
869 | case BLKIF_OP_READ: | 928 | case BLKIF_OP_READ: |
@@ -1090,22 +1149,14 @@ static int __init xen_blkif_init(void) | |||
1090 | xen_blkif_reqs, GFP_KERNEL); | 1149 | xen_blkif_reqs, GFP_KERNEL); |
1091 | blkbk->pending_grant_handles = kmalloc(sizeof(blkbk->pending_grant_handles[0]) * | 1150 | blkbk->pending_grant_handles = kmalloc(sizeof(blkbk->pending_grant_handles[0]) * |
1092 | mmap_pages, GFP_KERNEL); | 1151 | mmap_pages, GFP_KERNEL); |
1093 | blkbk->pending_pages = kzalloc(sizeof(blkbk->pending_pages[0]) * | ||
1094 | mmap_pages, GFP_KERNEL); | ||
1095 | 1152 | ||
1096 | if (!blkbk->pending_reqs || !blkbk->pending_grant_handles || | 1153 | if (!blkbk->pending_reqs || !blkbk->pending_grant_handles) { |
1097 | !blkbk->pending_pages) { | ||
1098 | rc = -ENOMEM; | 1154 | rc = -ENOMEM; |
1099 | goto out_of_memory; | 1155 | goto out_of_memory; |
1100 | } | 1156 | } |
1101 | 1157 | ||
1102 | for (i = 0; i < mmap_pages; i++) { | 1158 | for (i = 0; i < mmap_pages; i++) { |
1103 | blkbk->pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; | 1159 | blkbk->pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; |
1104 | blkbk->pending_pages[i] = alloc_page(GFP_KERNEL); | ||
1105 | if (blkbk->pending_pages[i] == NULL) { | ||
1106 | rc = -ENOMEM; | ||
1107 | goto out_of_memory; | ||
1108 | } | ||
1109 | } | 1160 | } |
1110 | rc = xen_blkif_interface_init(); | 1161 | rc = xen_blkif_interface_init(); |
1111 | if (rc) | 1162 | if (rc) |
@@ -1130,13 +1181,6 @@ static int __init xen_blkif_init(void) | |||
1130 | failed_init: | 1181 | failed_init: |
1131 | kfree(blkbk->pending_reqs); | 1182 | kfree(blkbk->pending_reqs); |
1132 | kfree(blkbk->pending_grant_handles); | 1183 | kfree(blkbk->pending_grant_handles); |
1133 | if (blkbk->pending_pages) { | ||
1134 | for (i = 0; i < mmap_pages; i++) { | ||
1135 | if (blkbk->pending_pages[i]) | ||
1136 | __free_page(blkbk->pending_pages[i]); | ||
1137 | } | ||
1138 | kfree(blkbk->pending_pages); | ||
1139 | } | ||
1140 | kfree(blkbk); | 1184 | kfree(blkbk); |
1141 | blkbk = NULL; | 1185 | blkbk = NULL; |
1142 | return rc; | 1186 | return rc; |
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 60103e2517ba..6c73c3855e65 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h | |||
@@ -220,6 +220,11 @@ struct xen_blkif { | |||
220 | struct rb_root persistent_gnts; | 220 | struct rb_root persistent_gnts; |
221 | unsigned int persistent_gnt_c; | 221 | unsigned int persistent_gnt_c; |
222 | 222 | ||
223 | /* buffer of free pages to map grant refs */ | ||
224 | spinlock_t free_pages_lock; | ||
225 | int free_pages_num; | ||
226 | struct list_head free_pages; | ||
227 | |||
223 | /* statistics */ | 228 | /* statistics */ |
224 | unsigned long st_print; | 229 | unsigned long st_print; |
225 | unsigned long long st_rd_req; | 230 | unsigned long long st_rd_req; |
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 8bfd1bcf95ec..24f7f6d87717 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c | |||
@@ -118,6 +118,9 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) | |||
118 | blkif->st_print = jiffies; | 118 | blkif->st_print = jiffies; |
119 | init_waitqueue_head(&blkif->waiting_to_free); | 119 | init_waitqueue_head(&blkif->waiting_to_free); |
120 | blkif->persistent_gnts.rb_node = NULL; | 120 | blkif->persistent_gnts.rb_node = NULL; |
121 | spin_lock_init(&blkif->free_pages_lock); | ||
122 | INIT_LIST_HEAD(&blkif->free_pages); | ||
123 | blkif->free_pages_num = 0; | ||
121 | 124 | ||
122 | return blkif; | 125 | return blkif; |
123 | } | 126 | } |