diff options
author | Zoltan Kiss <zoltan.kiss@citrix.com> | 2014-02-27 10:55:30 -0500 |
---|---|---|
committer | David Vrabel <david.vrabel@citrix.com> | 2014-03-18 10:40:19 -0400 |
commit | 1429d46df4c538d28460d0b493997006a62a1093 (patch) | |
tree | 81e177be951fd3134d2e475307af278a1951061a /drivers/xen/grant-table.c | |
parent | 395edbb80b049884df075be54ef46cc742c3e266 (diff) |
xen/grant-table: Refactor gnttab_[un]map_refs to avoid m2p_override
The grant mapping API does m2p_override unnecessarily: only gntdev needs it,
for blkback and future netback patches it just cause a lock contention, as
those pages never go to userspace. Therefore this series does the following:
- the bulk of the original function (everything after the mapping hypercall)
is moved to arch-dependent set/clear_foreign_p2m_mapping
- the "if (xen_feature(XENFEAT_auto_translated_physmap))" branch goes to ARM
- therefore the ARM function could be much smaller, the m2p_override stubs
could be also removed
- on x86 the set_phys_to_machine calls were moved up to this new funcion
from m2p_override functions
- and m2p_override functions are only called when there is a kmap_ops param
It also removes a stray space from arch/x86/include/asm/xen/page.h.
Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com>
Suggested-by: Anthony Liguori <aliguori@amazon.com>
Suggested-by: David Vrabel <david.vrabel@citrix.com>
Suggested-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'drivers/xen/grant-table.c')
-rw-r--r-- | drivers/xen/grant-table.c | 73 |
1 files changed, 3 insertions, 70 deletions
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index b84e3ab839aa..6d325bda76da 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -933,9 +933,6 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
933 | struct page **pages, unsigned int count) | 933 | struct page **pages, unsigned int count) |
934 | { | 934 | { |
935 | int i, ret; | 935 | int i, ret; |
936 | bool lazy = false; | ||
937 | pte_t *pte; | ||
938 | unsigned long mfn; | ||
939 | 936 | ||
940 | ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count); | 937 | ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count); |
941 | if (ret) | 938 | if (ret) |
@@ -947,45 +944,7 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
947 | gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i, | 944 | gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i, |
948 | &map_ops[i].status, __func__); | 945 | &map_ops[i].status, __func__); |
949 | 946 | ||
950 | /* this is basically a nop on x86 */ | 947 | return set_foreign_p2m_mapping(map_ops, kmap_ops, pages, count); |
951 | if (xen_feature(XENFEAT_auto_translated_physmap)) { | ||
952 | for (i = 0; i < count; i++) { | ||
953 | if (map_ops[i].status) | ||
954 | continue; | ||
955 | set_phys_to_machine(map_ops[i].host_addr >> PAGE_SHIFT, | ||
956 | map_ops[i].dev_bus_addr >> PAGE_SHIFT); | ||
957 | } | ||
958 | return ret; | ||
959 | } | ||
960 | |||
961 | if (!in_interrupt() && paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { | ||
962 | arch_enter_lazy_mmu_mode(); | ||
963 | lazy = true; | ||
964 | } | ||
965 | |||
966 | for (i = 0; i < count; i++) { | ||
967 | /* Do not add to override if the map failed. */ | ||
968 | if (map_ops[i].status) | ||
969 | continue; | ||
970 | |||
971 | if (map_ops[i].flags & GNTMAP_contains_pte) { | ||
972 | pte = (pte_t *) (mfn_to_virt(PFN_DOWN(map_ops[i].host_addr)) + | ||
973 | (map_ops[i].host_addr & ~PAGE_MASK)); | ||
974 | mfn = pte_mfn(*pte); | ||
975 | } else { | ||
976 | mfn = PFN_DOWN(map_ops[i].dev_bus_addr); | ||
977 | } | ||
978 | ret = m2p_add_override(mfn, pages[i], kmap_ops ? | ||
979 | &kmap_ops[i] : NULL); | ||
980 | if (ret) | ||
981 | goto out; | ||
982 | } | ||
983 | |||
984 | out: | ||
985 | if (lazy) | ||
986 | arch_leave_lazy_mmu_mode(); | ||
987 | |||
988 | return ret; | ||
989 | } | 948 | } |
990 | EXPORT_SYMBOL_GPL(gnttab_map_refs); | 949 | EXPORT_SYMBOL_GPL(gnttab_map_refs); |
991 | 950 | ||
@@ -993,39 +952,13 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | |||
993 | struct gnttab_map_grant_ref *kmap_ops, | 952 | struct gnttab_map_grant_ref *kmap_ops, |
994 | struct page **pages, unsigned int count) | 953 | struct page **pages, unsigned int count) |
995 | { | 954 | { |
996 | int i, ret; | 955 | int ret; |
997 | bool lazy = false; | ||
998 | 956 | ||
999 | ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); | 957 | ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); |
1000 | if (ret) | 958 | if (ret) |
1001 | return ret; | 959 | return ret; |
1002 | 960 | ||
1003 | /* this is basically a nop on x86 */ | 961 | return clear_foreign_p2m_mapping(unmap_ops, kmap_ops, pages, count); |
1004 | if (xen_feature(XENFEAT_auto_translated_physmap)) { | ||
1005 | for (i = 0; i < count; i++) { | ||
1006 | set_phys_to_machine(unmap_ops[i].host_addr >> PAGE_SHIFT, | ||
1007 | INVALID_P2M_ENTRY); | ||
1008 | } | ||
1009 | return ret; | ||
1010 | } | ||
1011 | |||
1012 | if (!in_interrupt() && paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { | ||
1013 | arch_enter_lazy_mmu_mode(); | ||
1014 | lazy = true; | ||
1015 | } | ||
1016 | |||
1017 | for (i = 0; i < count; i++) { | ||
1018 | ret = m2p_remove_override(pages[i], kmap_ops ? | ||
1019 | &kmap_ops[i] : NULL); | ||
1020 | if (ret) | ||
1021 | goto out; | ||
1022 | } | ||
1023 | |||
1024 | out: | ||
1025 | if (lazy) | ||
1026 | arch_leave_lazy_mmu_mode(); | ||
1027 | |||
1028 | return ret; | ||
1029 | } | 962 | } |
1030 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); | 963 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); |
1031 | 964 | ||