[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3] xen/grant-table: Avoid m2p_override during mapping
On Mon, 20 Jan 2014, Zoltan Kiss wrote: > 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 original functions were renamed to __gnttab_[un]map_refs, with a new > parameter m2p_override > - based on m2p_override either they follow the original behaviour, or just set > the private flag and call set_phys_to_machine > - gnttab_[un]map_refs are now a wrapper to call __gnttab_[un]map_refs with > m2p_override false > - a new function gnttab_[un]map_refs_userspace provides the old behaviour > > v2: > - move the storing of the old mfn in page->index to gnttab_map_refs > - move the function header update to a separate patch > > v3: > - a new approach to retain old behaviour where it needed > - squash the patches into one > > Signed-off-by: Zoltan Kiss <zoltan.kiss@xxxxxxxxxx> > Suggested-by: David Vrabel <david.vrabel@xxxxxxxxxx> > --- > drivers/block/xen-blkback/blkback.c | 15 +++---- > drivers/xen/gntdev.c | 13 +++--- > drivers/xen/grant-table.c | 81 > +++++++++++++++++++++++++++++------ > include/xen/grant_table.h | 8 +++- > 4 files changed, 87 insertions(+), 30 deletions(-) > > diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c > index aa846a4..87ded60 100644 > --- a/drivers/xen/grant-table.c > +++ b/drivers/xen/grant-table.c > @@ -880,15 +880,17 @@ void gnttab_batch_copy(struct gnttab_copy *batch, > unsigned count) > } > EXPORT_SYMBOL_GPL(gnttab_batch_copy); > > -int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > +int __gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > struct gnttab_map_grant_ref *kmap_ops, > - struct page **pages, unsigned int count) > + struct page **pages, unsigned int count, > + bool m2p_override) > { > int i, ret; > bool lazy = false; > pte_t *pte; > unsigned long mfn; > > + BUG_ON(kmap_ops && !m2p_override); > ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count); > if (ret) > return ret; > @@ -907,10 +909,12 @@ int gnttab_map_refs(struct gnttab_map_grant_ref > *map_ops, > set_phys_to_machine(map_ops[i].host_addr >> PAGE_SHIFT, > map_ops[i].dev_bus_addr >> PAGE_SHIFT); > } > - return ret; > + return 0; > } > > - if (!in_interrupt() && paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { > + if (m2p_override && > + !in_interrupt() && > + paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { > arch_enter_lazy_mmu_mode(); > lazy = true; > } > @@ -927,8 +931,18 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > } else { > mfn = PFN_DOWN(map_ops[i].dev_bus_addr); > } > - ret = m2p_add_override(mfn, pages[i], kmap_ops ? > - &kmap_ops[i] : NULL); > + if (m2p_override) > + ret = m2p_add_override(mfn, pages[i], kmap_ops ? > + &kmap_ops[i] : NULL); > + else { > + unsigned long pfn = page_to_pfn(pages[i]); > + WARN_ON(PagePrivate(pages[i])); > + SetPagePrivate(pages[i]); > + set_page_private(pages[i], mfn); > + pages[i]->index = pfn_to_mfn(pfn); > + if (unlikely(!set_phys_to_machine(pfn, > FOREIGN_FRAME(mfn)))) > + return -ENOMEM; What happens if the page is PageHighMem? This looks like a subset of m2p_add_override, but it is missing some relevant bits, like the PageHighMem check, or the p2m(m2p(mfn)) == mfn check. Maybe we can find a way to avoid duplicating the code. We could split m2p_add_override in two functions or add yet another parameter to it. > + } > if (ret) > goto out; > } > @@ -937,17 +951,33 @@ int gnttab_map_refs(struct gnttab_map_grant_ref > *map_ops, > if (lazy) > arch_leave_lazy_mmu_mode(); > > - return ret; > + return 0; > +} > + > +int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > + struct page **pages, unsigned int count) > +{ > + return __gnttab_map_refs(map_ops, NULL, pages, count, false); > } > EXPORT_SYMBOL_GPL(gnttab_map_refs); > > -int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, > +int gnttab_map_refs_userspace(struct gnttab_map_grant_ref *map_ops, > + struct gnttab_map_grant_ref *kmap_ops, > + struct page **pages, unsigned int count) > +{ > + return __gnttab_map_refs(map_ops, kmap_ops, pages, count, true); > +} > +EXPORT_SYMBOL_GPL(gnttab_map_refs_userspace); > + > +int __gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, > struct gnttab_map_grant_ref *kmap_ops, > - struct page **pages, unsigned int count) > + struct page **pages, unsigned int count, > + bool m2p_override) > { > int i, ret; > bool lazy = false; > > + BUG_ON(kmap_ops && !m2p_override); > ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, > count); > if (ret) > return ret; > @@ -958,17 +988,26 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref > *unmap_ops, > set_phys_to_machine(unmap_ops[i].host_addr >> > PAGE_SHIFT, > INVALID_P2M_ENTRY); > } > - return ret; > + return 0; > } > > - if (!in_interrupt() && paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { > + if (m2p_override && > + !in_interrupt() && > + paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { > arch_enter_lazy_mmu_mode(); > lazy = true; > } > > for (i = 0; i < count; i++) { > - ret = m2p_remove_override(pages[i], kmap_ops ? > - &kmap_ops[i] : NULL); > + if (m2p_override) > + ret = m2p_remove_override(pages[i], kmap_ops ? > + &kmap_ops[i] : NULL); > + else { > + unsigned long pfn = page_to_pfn(pages[i]); > + WARN_ON(!PagePrivate(pages[i])); > + ClearPagePrivate(pages[i]); > + set_phys_to_machine(pfn, pages[i]->index); same here: let's try to avoid code duplication > + } > if (ret) > goto out; > } > @@ -977,10 +1016,24 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref > *unmap_ops, > if (lazy) > arch_leave_lazy_mmu_mode(); > > - return ret; > + return 0; > +} > + > +int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *map_ops, > + struct page **pages, unsigned int count) > +{ > + return __gnttab_unmap_refs(map_ops, NULL, pages, count, false); > } > EXPORT_SYMBOL_GPL(gnttab_unmap_refs); > > +int gnttab_unmap_refs_userspace(struct gnttab_unmap_grant_ref *map_ops, > + struct gnttab_map_grant_ref *kmap_ops, > + struct page **pages, unsigned int count) > +{ > + return __gnttab_unmap_refs(map_ops, kmap_ops, pages, count, true); > +} > +EXPORT_SYMBOL_GPL(gnttab_unmap_refs_userspace); > + > static unsigned nr_status_frames(unsigned nr_grant_frames) > { > BUG_ON(grefs_per_grant_frame == 0); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |