Commit 325d73bf authored by Bob Liu's avatar Bob Liu Committed by David Vrabel

xen/blkback: safely unmap purge persistent grants

Commit c43cf3ea ("xen-blkback: safely unmap grants in case they
are still in use") use gnttab_unmap_refs_async() to wait until the
mapped pages are no longer in use before unmapping them, but that
commit missed the persistent case.  Purge persistent pages can't be
unmapped either unless no longer in use.
Signed-off-by: default avatarBob Liu <bob.liu@oracle.com>
Acked-by: default avatarRoger Pau Monné <roger.pau@citrix.com>
Signed-off-by: default avatarDavid Vrabel <david.vrabel@citrix.com>
parent b787f68c
...@@ -329,8 +329,18 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work) ...@@ -329,8 +329,18 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work)
struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
struct persistent_gnt *persistent_gnt; struct persistent_gnt *persistent_gnt;
int ret, segs_to_unmap = 0; int segs_to_unmap = 0;
struct xen_blkif *blkif = container_of(work, typeof(*blkif), persistent_purge_work); struct xen_blkif *blkif = container_of(work, typeof(*blkif), persistent_purge_work);
struct gntab_unmap_queue_data unmap_data;
struct completion unmap_completion;
init_completion(&unmap_completion);
unmap_data.data = &unmap_completion;
unmap_data.done = &free_persistent_gnts_unmap_callback;
unmap_data.pages = pages;
unmap_data.unmap_ops = unmap;
unmap_data.kunmap_ops = NULL;
while(!list_empty(&blkif->persistent_purge_list)) { while(!list_empty(&blkif->persistent_purge_list)) {
persistent_gnt = list_first_entry(&blkif->persistent_purge_list, persistent_gnt = list_first_entry(&blkif->persistent_purge_list,
...@@ -346,17 +356,19 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work) ...@@ -346,17 +356,19 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work)
pages[segs_to_unmap] = persistent_gnt->page; pages[segs_to_unmap] = persistent_gnt->page;
if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
ret = gnttab_unmap_refs(unmap, NULL, pages, unmap_data.count = segs_to_unmap;
segs_to_unmap); gnttab_unmap_refs_async(&unmap_data);
BUG_ON(ret); wait_for_completion(&unmap_completion);
put_free_pages(blkif, pages, segs_to_unmap); put_free_pages(blkif, pages, segs_to_unmap);
segs_to_unmap = 0; segs_to_unmap = 0;
} }
kfree(persistent_gnt); kfree(persistent_gnt);
} }
if (segs_to_unmap > 0) { if (segs_to_unmap > 0) {
ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); unmap_data.count = segs_to_unmap;
BUG_ON(ret); gnttab_unmap_refs_async(&unmap_data);
wait_for_completion(&unmap_completion);
put_free_pages(blkif, pages, segs_to_unmap); put_free_pages(blkif, pages, segs_to_unmap);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment