diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/block/xen-blkback/blkback.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index bd2b3bbbb22c..48e98f2712b5 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
| @@ -329,8 +329,18 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work) | |||
| 329 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 329 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
| 330 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 330 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
| 331 | struct persistent_gnt *persistent_gnt; | 331 | struct persistent_gnt *persistent_gnt; |
| 332 | int ret, segs_to_unmap = 0; | 332 | int segs_to_unmap = 0; |
| 333 | struct xen_blkif *blkif = container_of(work, typeof(*blkif), persistent_purge_work); | 333 | struct xen_blkif *blkif = container_of(work, typeof(*blkif), persistent_purge_work); |
| 334 | struct gntab_unmap_queue_data unmap_data; | ||
| 335 | struct completion unmap_completion; | ||
| 336 | |||
| 337 | init_completion(&unmap_completion); | ||
| 338 | |||
| 339 | unmap_data.data = &unmap_completion; | ||
| 340 | unmap_data.done = &free_persistent_gnts_unmap_callback; | ||
| 341 | unmap_data.pages = pages; | ||
| 342 | unmap_data.unmap_ops = unmap; | ||
| 343 | unmap_data.kunmap_ops = NULL; | ||
| 334 | 344 | ||
| 335 | while(!list_empty(&blkif->persistent_purge_list)) { | 345 | while(!list_empty(&blkif->persistent_purge_list)) { |
| 336 | persistent_gnt = list_first_entry(&blkif->persistent_purge_list, | 346 | persistent_gnt = list_first_entry(&blkif->persistent_purge_list, |
| @@ -346,17 +356,19 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work) | |||
| 346 | pages[segs_to_unmap] = persistent_gnt->page; | 356 | pages[segs_to_unmap] = persistent_gnt->page; |
| 347 | 357 | ||
| 348 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { | 358 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { |
| 349 | ret = gnttab_unmap_refs(unmap, NULL, pages, | 359 | unmap_data.count = segs_to_unmap; |
| 350 | segs_to_unmap); | 360 | gnttab_unmap_refs_async(&unmap_data); |
| 351 | BUG_ON(ret); | 361 | wait_for_completion(&unmap_completion); |
| 362 | |||
| 352 | put_free_pages(blkif, pages, segs_to_unmap); | 363 | put_free_pages(blkif, pages, segs_to_unmap); |
| 353 | segs_to_unmap = 0; | 364 | segs_to_unmap = 0; |
| 354 | } | 365 | } |
| 355 | kfree(persistent_gnt); | 366 | kfree(persistent_gnt); |
| 356 | } | 367 | } |
| 357 | if (segs_to_unmap > 0) { | 368 | if (segs_to_unmap > 0) { |
| 358 | ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); | 369 | unmap_data.count = segs_to_unmap; |
| 359 | BUG_ON(ret); | 370 | gnttab_unmap_refs_async(&unmap_data); |
| 371 | wait_for_completion(&unmap_completion); | ||
| 360 | put_free_pages(blkif, pages, segs_to_unmap); | 372 | put_free_pages(blkif, pages, segs_to_unmap); |
| 361 | } | 373 | } |
| 362 | } | 374 | } |
