summaryrefslogtreecommitdiffstats
path: root/include/xen
diff options
context:
space:
mode:
authorJennifer Herbert <jennifer.herbert@citrix.com>2014-12-09 13:28:37 -0500
committerDavid Vrabel <david.vrabel@citrix.com>2015-01-28 09:03:14 -0500
commit3f9f1c67572f5e5e6dc84216d48d1480f3c4fcf6 (patch)
treef92be430b64202bce20f597e121f23a111cc3493 /include/xen
parentc2677a6fc4dee765fff8f7ac3d61f657dc295650 (diff)
xen/grant-table: add a mechanism to safely unmap pages that are in use
Introduce gnttab_unmap_refs_async() that can be used to safely unmap pages that may be in use (ref count > 1). If the pages are in use the unmap is deferred and retried later. This polling is not very clever but it should be good enough if the cases where the delay is necessary are rare. The initial delay is 5 ms and is increased linearly on each subsequent retry (to reduce load if the page is in use for a long time). This is needed to allow block backends using grant mapping to safely use network storage (block or filesystem based such as iSCSI or NFS). The network storage driver may complete a block request whilst there is a queued network packet retry (because the ack from the remote end races with deciding to queue the retry). The pages for the retried packet would be grant unmapped and the network driver (or hardware) would access the unmapped page. Signed-off-by: Jennifer Herbert <jennifer.herbert@citrix.com> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Diffstat (limited to 'include/xen')
-rw-r--r--include/xen/grant_table.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index d3bef563e8da..143ca5ffab7a 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -60,6 +60,22 @@ struct gnttab_free_callback {
60 u16 count; 60 u16 count;
61}; 61};
62 62
63struct gntab_unmap_queue_data;
64
65typedef void (*gnttab_unmap_refs_done)(int result, struct gntab_unmap_queue_data *data);
66
67struct gntab_unmap_queue_data
68{
69 struct delayed_work gnttab_work;
70 void *data;
71 gnttab_unmap_refs_done done;
72 struct gnttab_unmap_grant_ref *unmap_ops;
73 struct gnttab_unmap_grant_ref *kunmap_ops;
74 struct page **pages;
75 unsigned int count;
76 unsigned int age;
77};
78
63int gnttab_init(void); 79int gnttab_init(void);
64int gnttab_suspend(void); 80int gnttab_suspend(void);
65int gnttab_resume(void); 81int gnttab_resume(void);
@@ -174,6 +190,8 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
174int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, 190int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
175 struct gnttab_unmap_grant_ref *kunmap_ops, 191 struct gnttab_unmap_grant_ref *kunmap_ops,
176 struct page **pages, unsigned int count); 192 struct page **pages, unsigned int count);
193void gnttab_unmap_refs_async(struct gntab_unmap_queue_data* item);
194
177 195
178/* Perform a batch of grant map/copy operations. Retry every batch slot 196/* Perform a batch of grant map/copy operations. Retry every batch slot
179 * for which the hypervisor returns GNTST_eagain. This is typically due 197 * for which the hypervisor returns GNTST_eagain. This is typically due