aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2015-01-05 09:13:41 -0500
committerDavid Vrabel <david.vrabel@citrix.com>2015-01-28 09:03:10 -0500
commit853d0289340026b30f93fd0e768340221d4e605c (patch)
tree17d52ad1d7ae43007d8b664bbdba2a50db7dbb81
parentd8ac3dd41aea245f65465449efc35dd3ac71e91d (diff)
xen/grant-table: pre-populate kernel unmap ops for xen_gnttab_unmap_refs()
When unmapping grants, instead of converting the kernel map ops to unmap ops on the fly, pre-populate the set of unmap ops. This allows the grant unmap for the kernel mappings to be trivially batched in the future. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
-rw-r--r--arch/arm/include/asm/xen/page.h2
-rw-r--r--arch/arm/xen/p2m.c2
-rw-r--r--arch/x86/include/asm/xen/page.h2
-rw-r--r--arch/x86/xen/p2m.c21
-rw-r--r--drivers/xen/gntdev.c20
-rw-r--r--drivers/xen/grant-table.c4
-rw-r--r--include/xen/grant_table.h2
7 files changed, 30 insertions, 23 deletions
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 68c739b3fdf4..2f7e6ff67d51 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -92,7 +92,7 @@ extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
92 struct page **pages, unsigned int count); 92 struct page **pages, unsigned int count);
93 93
94extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, 94extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
95 struct gnttab_map_grant_ref *kmap_ops, 95 struct gnttab_unmap_grant_ref *kunmap_ops,
96 struct page **pages, unsigned int count); 96 struct page **pages, unsigned int count);
97 97
98bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); 98bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c
index 054857776254..cb7a14c5cd69 100644
--- a/arch/arm/xen/p2m.c
+++ b/arch/arm/xen/p2m.c
@@ -102,7 +102,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
102EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping); 102EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping);
103 103
104int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, 104int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
105 struct gnttab_map_grant_ref *kmap_ops, 105 struct gnttab_unmap_grant_ref *kunmap_ops,
106 struct page **pages, unsigned int count) 106 struct page **pages, unsigned int count)
107{ 107{
108 int i; 108 int i;
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index 5eea09915a15..e9f52fe2d56a 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -55,7 +55,7 @@ extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
55 struct gnttab_map_grant_ref *kmap_ops, 55 struct gnttab_map_grant_ref *kmap_ops,
56 struct page **pages, unsigned int count); 56 struct page **pages, unsigned int count);
57extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, 57extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
58 struct gnttab_map_grant_ref *kmap_ops, 58 struct gnttab_unmap_grant_ref *kunmap_ops,
59 struct page **pages, unsigned int count); 59 struct page **pages, unsigned int count);
60extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); 60extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
61 61
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 70fb5075c901..df40b2888eae 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -816,7 +816,7 @@ static struct page *m2p_find_override(unsigned long mfn)
816} 816}
817 817
818static int m2p_remove_override(struct page *page, 818static int m2p_remove_override(struct page *page,
819 struct gnttab_map_grant_ref *kmap_op, 819 struct gnttab_unmap_grant_ref *kunmap_op,
820 unsigned long mfn) 820 unsigned long mfn)
821{ 821{
822 unsigned long flags; 822 unsigned long flags;
@@ -840,7 +840,7 @@ static int m2p_remove_override(struct page *page,
840 list_del(&page->lru); 840 list_del(&page->lru);
841 spin_unlock_irqrestore(&m2p_override_lock, flags); 841 spin_unlock_irqrestore(&m2p_override_lock, flags);
842 842
843 if (kmap_op != NULL) { 843 if (kunmap_op != NULL) {
844 if (!PageHighMem(page)) { 844 if (!PageHighMem(page)) {
845 struct multicall_space mcs; 845 struct multicall_space mcs;
846 struct gnttab_unmap_and_replace *unmap_op; 846 struct gnttab_unmap_and_replace *unmap_op;
@@ -855,13 +855,13 @@ static int m2p_remove_override(struct page *page,
855 * issued. In this case handle is going to -1 because 855 * issued. In this case handle is going to -1 because
856 * it hasn't been modified yet. 856 * it hasn't been modified yet.
857 */ 857 */
858 if (kmap_op->handle == -1) 858 if (kunmap_op->handle == -1)
859 xen_mc_flush(); 859 xen_mc_flush();
860 /* 860 /*
861 * Now if kmap_op->handle is negative it means that the 861 * Now if kmap_op->handle is negative it means that the
862 * hypercall actually returned an error. 862 * hypercall actually returned an error.
863 */ 863 */
864 if (kmap_op->handle == GNTST_general_error) { 864 if (kunmap_op->handle == GNTST_general_error) {
865 pr_warn("m2p_remove_override: pfn %lx mfn %lx, failed to modify kernel mappings", 865 pr_warn("m2p_remove_override: pfn %lx mfn %lx, failed to modify kernel mappings",
866 pfn, mfn); 866 pfn, mfn);
867 put_balloon_scratch_page(); 867 put_balloon_scratch_page();
@@ -873,9 +873,9 @@ static int m2p_remove_override(struct page *page,
873 mcs = __xen_mc_entry( 873 mcs = __xen_mc_entry(
874 sizeof(struct gnttab_unmap_and_replace)); 874 sizeof(struct gnttab_unmap_and_replace));
875 unmap_op = mcs.args; 875 unmap_op = mcs.args;
876 unmap_op->host_addr = kmap_op->host_addr; 876 unmap_op->host_addr = kunmap_op->host_addr;
877 unmap_op->new_addr = scratch_page_address; 877 unmap_op->new_addr = scratch_page_address;
878 unmap_op->handle = kmap_op->handle; 878 unmap_op->handle = kunmap_op->handle;
879 879
880 MULTI_grant_table_op(mcs.mc, 880 MULTI_grant_table_op(mcs.mc,
881 GNTTABOP_unmap_and_replace, unmap_op, 1); 881 GNTTABOP_unmap_and_replace, unmap_op, 1);
@@ -887,7 +887,6 @@ static int m2p_remove_override(struct page *page,
887 887
888 xen_mc_issue(PARAVIRT_LAZY_MMU); 888 xen_mc_issue(PARAVIRT_LAZY_MMU);
889 889
890 kmap_op->host_addr = 0;
891 put_balloon_scratch_page(); 890 put_balloon_scratch_page();
892 } 891 }
893 } 892 }
@@ -912,7 +911,7 @@ static int m2p_remove_override(struct page *page,
912} 911}
913 912
914int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, 913int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
915 struct gnttab_map_grant_ref *kmap_ops, 914 struct gnttab_unmap_grant_ref *kunmap_ops,
916 struct page **pages, unsigned int count) 915 struct page **pages, unsigned int count)
917{ 916{
918 int i, ret = 0; 917 int i, ret = 0;
@@ -921,7 +920,7 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
921 if (xen_feature(XENFEAT_auto_translated_physmap)) 920 if (xen_feature(XENFEAT_auto_translated_physmap))
922 return 0; 921 return 0;
923 922
924 if (kmap_ops && 923 if (kunmap_ops &&
925 !in_interrupt() && 924 !in_interrupt() &&
926 paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { 925 paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) {
927 arch_enter_lazy_mmu_mode(); 926 arch_enter_lazy_mmu_mode();
@@ -942,8 +941,8 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
942 ClearPagePrivate(pages[i]); 941 ClearPagePrivate(pages[i]);
943 set_phys_to_machine(pfn, pages[i]->index); 942 set_phys_to_machine(pfn, pages[i]->index);
944 943
945 if (kmap_ops) 944 if (kunmap_ops)
946 ret = m2p_remove_override(pages[i], &kmap_ops[i], mfn); 945 ret = m2p_remove_override(pages[i], &kunmap_ops[i], mfn);
947 if (ret) 946 if (ret)
948 goto out; 947 goto out;
949 } 948 }
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 073b4a19a8b0..6444172f2842 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -91,6 +91,7 @@ struct grant_map {
91 struct gnttab_map_grant_ref *map_ops; 91 struct gnttab_map_grant_ref *map_ops;
92 struct gnttab_unmap_grant_ref *unmap_ops; 92 struct gnttab_unmap_grant_ref *unmap_ops;
93 struct gnttab_map_grant_ref *kmap_ops; 93 struct gnttab_map_grant_ref *kmap_ops;
94 struct gnttab_unmap_grant_ref *kunmap_ops;
94 struct page **pages; 95 struct page **pages;
95}; 96};
96 97
@@ -124,6 +125,7 @@ static void gntdev_free_map(struct grant_map *map)
124 kfree(map->map_ops); 125 kfree(map->map_ops);
125 kfree(map->unmap_ops); 126 kfree(map->unmap_ops);
126 kfree(map->kmap_ops); 127 kfree(map->kmap_ops);
128 kfree(map->kunmap_ops);
127 kfree(map); 129 kfree(map);
128} 130}
129 131
@@ -140,11 +142,13 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
140 add->map_ops = kcalloc(count, sizeof(add->map_ops[0]), GFP_KERNEL); 142 add->map_ops = kcalloc(count, sizeof(add->map_ops[0]), GFP_KERNEL);
141 add->unmap_ops = kcalloc(count, sizeof(add->unmap_ops[0]), GFP_KERNEL); 143 add->unmap_ops = kcalloc(count, sizeof(add->unmap_ops[0]), GFP_KERNEL);
142 add->kmap_ops = kcalloc(count, sizeof(add->kmap_ops[0]), GFP_KERNEL); 144 add->kmap_ops = kcalloc(count, sizeof(add->kmap_ops[0]), GFP_KERNEL);
145 add->kunmap_ops = kcalloc(count, sizeof(add->kunmap_ops[0]), GFP_KERNEL);
143 add->pages = kcalloc(count, sizeof(add->pages[0]), GFP_KERNEL); 146 add->pages = kcalloc(count, sizeof(add->pages[0]), GFP_KERNEL);
144 if (NULL == add->grants || 147 if (NULL == add->grants ||
145 NULL == add->map_ops || 148 NULL == add->map_ops ||
146 NULL == add->unmap_ops || 149 NULL == add->unmap_ops ||
147 NULL == add->kmap_ops || 150 NULL == add->kmap_ops ||
151 NULL == add->kunmap_ops ||
148 NULL == add->pages) 152 NULL == add->pages)
149 goto err; 153 goto err;
150 154
@@ -155,6 +159,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
155 add->map_ops[i].handle = -1; 159 add->map_ops[i].handle = -1;
156 add->unmap_ops[i].handle = -1; 160 add->unmap_ops[i].handle = -1;
157 add->kmap_ops[i].handle = -1; 161 add->kmap_ops[i].handle = -1;
162 add->kunmap_ops[i].handle = -1;
158 } 163 }
159 164
160 add->index = 0; 165 add->index = 0;
@@ -280,6 +285,8 @@ static int map_grant_pages(struct grant_map *map)
280 map->flags | GNTMAP_host_map, 285 map->flags | GNTMAP_host_map,
281 map->grants[i].ref, 286 map->grants[i].ref,
282 map->grants[i].domid); 287 map->grants[i].domid);
288 gnttab_set_unmap_op(&map->kunmap_ops[i], address,
289 map->flags | GNTMAP_host_map, -1);
283 } 290 }
284 } 291 }
285 292
@@ -290,13 +297,14 @@ static int map_grant_pages(struct grant_map *map)
290 return err; 297 return err;
291 298
292 for (i = 0; i < map->count; i++) { 299 for (i = 0; i < map->count; i++) {
293 if (map->map_ops[i].status) 300 if (map->map_ops[i].status) {
294 err = -EINVAL; 301 err = -EINVAL;
295 else { 302 continue;
296 BUG_ON(map->map_ops[i].handle == -1);
297 map->unmap_ops[i].handle = map->map_ops[i].handle;
298 pr_debug("map handle=%d\n", map->map_ops[i].handle);
299 } 303 }
304
305 map->unmap_ops[i].handle = map->map_ops[i].handle;
306 if (use_ptemod)
307 map->kunmap_ops[i].handle = map->kmap_ops[i].handle;
300 } 308 }
301 return err; 309 return err;
302} 310}
@@ -316,7 +324,7 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages)
316 } 324 }
317 325
318 err = gnttab_unmap_refs(map->unmap_ops + offset, 326 err = gnttab_unmap_refs(map->unmap_ops + offset,
319 use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset, 327 use_ptemod ? map->kunmap_ops + offset : NULL, map->pages + offset,
320 pages); 328 pages);
321 if (err) 329 if (err)
322 return err; 330 return err;
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 7786291ba229..999d7abdbcec 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -738,7 +738,7 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
738EXPORT_SYMBOL_GPL(gnttab_map_refs); 738EXPORT_SYMBOL_GPL(gnttab_map_refs);
739 739
740int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, 740int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
741 struct gnttab_map_grant_ref *kmap_ops, 741 struct gnttab_unmap_grant_ref *kunmap_ops,
742 struct page **pages, unsigned int count) 742 struct page **pages, unsigned int count)
743{ 743{
744 int ret; 744 int ret;
@@ -747,7 +747,7 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
747 if (ret) 747 if (ret)
748 return ret; 748 return ret;
749 749
750 return clear_foreign_p2m_mapping(unmap_ops, kmap_ops, pages, count); 750 return clear_foreign_p2m_mapping(unmap_ops, kunmap_ops, pages, count);
751} 751}
752EXPORT_SYMBOL_GPL(gnttab_unmap_refs); 752EXPORT_SYMBOL_GPL(gnttab_unmap_refs);
753 753
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index 3387465b9caa..7235d8f35459 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -167,7 +167,7 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
167 struct gnttab_map_grant_ref *kmap_ops, 167 struct gnttab_map_grant_ref *kmap_ops,
168 struct page **pages, unsigned int count); 168 struct page **pages, unsigned int count);
169int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, 169int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
170 struct gnttab_map_grant_ref *kunmap_ops, 170 struct gnttab_unmap_grant_ref *kunmap_ops,
171 struct page **pages, unsigned int count); 171 struct page **pages, unsigned int count);
172 172
173/* Perform a batch of grant map/copy operations. Retry every batch slot 173/* Perform a batch of grant map/copy operations. Retry every batch slot