* [PATCH v5] xen/grant-table: Avoid m2p_override during mapping @ 2014-01-23 13:07 Zoltan Kiss 2014-01-24 14:37 ` Konrad Rzeszutek Wilk 2014-01-24 14:37 ` [Xen-devel] " Konrad Rzeszutek Wilk 0 siblings, 2 replies; 7+ messages in thread From: Zoltan Kiss @ 2014-01-23 13:07 UTC (permalink / raw) To: ian.campbell, wei.liu2, xen-devel, netdev, linux-kernel, jonathan.davies Cc: Zoltan Kiss 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 It also removes a stray space from page.h and change ret to 0 if XENFEAT_auto_translated_physmap, as that is the only possible return value there. 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 v4: - move out the common bits from m2p* functions, and pass pfn/mfn as parameter - clear page->private before doing anything with the page, so m2p_find_override won't race with this v5: - change return value handling in __gnttab_[un]map_refs - remove a stray space in page.h - add detail why ret = 0 now at some places Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com> Suggested-by: David Vrabel <david.vrabel@citrix.com> --- arch/x86/include/asm/xen/page.h | 12 +++-- arch/x86/xen/p2m.c | 25 ++-------- drivers/block/xen-blkback/blkback.c | 15 +++--- drivers/xen/gntdev.c | 13 +++-- drivers/xen/grant-table.c | 90 ++++++++++++++++++++++++++++++----- include/xen/grant_table.h | 8 +++- 6 files changed, 109 insertions(+), 54 deletions(-) diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index b913915..68a1438 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -49,10 +49,14 @@ extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); extern unsigned long set_phys_range_identity(unsigned long pfn_s, unsigned long pfn_e); -extern int m2p_add_override(unsigned long mfn, struct page *page, - struct gnttab_map_grant_ref *kmap_op); +extern int m2p_add_override(unsigned long mfn, + struct page *page, + struct gnttab_map_grant_ref *kmap_op, + unsigned long pfn); extern int m2p_remove_override(struct page *page, - struct gnttab_map_grant_ref *kmap_op); + struct gnttab_map_grant_ref *kmap_op, + unsigned long pfn, + unsigned long mfn); extern struct page *m2p_find_override(unsigned long mfn); extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); @@ -121,7 +125,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) pfn = m2p_find_override_pfn(mfn, ~0); } - /* + /* * pfn is ~0 if there are no entries in the m2p for mfn or if the * entry doesn't map back to the mfn and m2p_override doesn't have a * valid entry for it. diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 2ae8699..0060178 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -872,15 +872,13 @@ static unsigned long mfn_hash(unsigned long mfn) /* Add an MFN override for a particular page */ int m2p_add_override(unsigned long mfn, struct page *page, - struct gnttab_map_grant_ref *kmap_op) + struct gnttab_map_grant_ref *kmap_op, unsigned long pfn) { unsigned long flags; - unsigned long pfn; unsigned long uninitialized_var(address); unsigned level; pte_t *ptep = NULL; - pfn = page_to_pfn(page); if (!PageHighMem(page)) { address = (unsigned long)__va(pfn << PAGE_SHIFT); ptep = lookup_address(address, &level); @@ -888,13 +886,6 @@ int m2p_add_override(unsigned long mfn, struct page *page, "m2p_add_override: pfn %lx not mapped", pfn)) return -EINVAL; } - WARN_ON(PagePrivate(page)); - SetPagePrivate(page); - set_page_private(page, mfn); - page->index = pfn_to_mfn(pfn); - - if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) - return -ENOMEM; if (kmap_op != NULL) { if (!PageHighMem(page)) { @@ -933,20 +924,15 @@ int m2p_add_override(unsigned long mfn, struct page *page, } EXPORT_SYMBOL_GPL(m2p_add_override); int m2p_remove_override(struct page *page, - struct gnttab_map_grant_ref *kmap_op) + struct gnttab_map_grant_ref *kmap_op, + unsigned long pfn, + unsigned long mfn) { unsigned long flags; - unsigned long mfn; - unsigned long pfn; unsigned long uninitialized_var(address); unsigned level; pte_t *ptep = NULL; - pfn = page_to_pfn(page); - mfn = get_phys_to_machine(pfn); - if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) - return -EINVAL; - if (!PageHighMem(page)) { address = (unsigned long)__va(pfn << PAGE_SHIFT); ptep = lookup_address(address, &level); @@ -959,10 +945,7 @@ int m2p_remove_override(struct page *page, spin_lock_irqsave(&m2p_override_lock, flags); list_del(&page->lru); spin_unlock_irqrestore(&m2p_override_lock, flags); - WARN_ON(!PagePrivate(page)); - ClearPagePrivate(page); - set_phys_to_machine(pfn, page->index); if (kmap_op != NULL) { if (!PageHighMem(page)) { struct multicall_space mcs; diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 6620b73..875025f 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -285,8 +285,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || !rb_next(&persistent_gnt->node)) { - ret = gnttab_unmap_refs(unmap, NULL, pages, - segs_to_unmap); + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); BUG_ON(ret); put_free_pages(blkif, pages, segs_to_unmap); segs_to_unmap = 0; @@ -321,8 +320,7 @@ static void unmap_purged_grants(struct work_struct *work) pages[segs_to_unmap] = persistent_gnt->page; if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { - ret = gnttab_unmap_refs(unmap, NULL, pages, - segs_to_unmap); + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); BUG_ON(ret); put_free_pages(blkif, pages, segs_to_unmap); segs_to_unmap = 0; @@ -330,7 +328,7 @@ static void unmap_purged_grants(struct work_struct *work) kfree(persistent_gnt); } if (segs_to_unmap > 0) { - ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); BUG_ON(ret); put_free_pages(blkif, pages, segs_to_unmap); } @@ -670,15 +668,14 @@ static void xen_blkbk_unmap(struct xen_blkif *blkif, GNTMAP_host_map, pages[i]->handle); pages[i]->handle = BLKBACK_INVALID_HANDLE; if (++invcount == BLKIF_MAX_SEGMENTS_PER_REQUEST) { - ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, - invcount); + ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); BUG_ON(ret); put_free_pages(blkif, unmap_pages, invcount); invcount = 0; } } if (invcount) { - ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount); + ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); BUG_ON(ret); put_free_pages(blkif, unmap_pages, invcount); } @@ -740,7 +737,7 @@ again: } if (segs_to_map) { - ret = gnttab_map_refs(map, NULL, pages_to_gnt, segs_to_map); + ret = gnttab_map_refs(map, pages_to_gnt, segs_to_map); BUG_ON(ret); } diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index e41c79c..e652c0e 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -284,8 +284,10 @@ static int map_grant_pages(struct grant_map *map) } pr_debug("map %d+%d\n", map->index, map->count); - err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL, - map->pages, map->count); + err = gnttab_map_refs_userspace(map->map_ops, + use_ptemod ? map->kmap_ops : NULL, + map->pages, + map->count); if (err) return err; @@ -315,9 +317,10 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) } } - err = gnttab_unmap_refs(map->unmap_ops + offset, - use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset, - pages); + err = gnttab_unmap_refs_userspace(map->unmap_ops + offset, + use_ptemod ? map->kmap_ops + offset : NULL, + map->pages + offset, + pages); if (err) return err; diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index aa846a4..2add483 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; + unsigned long mfn, pfn; + 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,20 @@ 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); + 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)))) { + ret = -ENOMEM; + goto out; + } + if (m2p_override) + ret = m2p_add_override(mfn, pages[i], kmap_ops ? + &kmap_ops[i] : NULL, pfn); if (ret) goto out; } @@ -939,15 +955,32 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, return ret; } + +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; + unsigned long pfn, mfn; + BUG_ON(kmap_ops && !m2p_override); ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); if (ret) return ret; @@ -958,17 +991,34 @@ 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); + pfn = page_to_pfn(pages[i]); + mfn = get_phys_to_machine(pfn); + if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) { + ret = -EINVAL; + goto out; + } + + set_page_private(pages[i], INVALID_P2M_ENTRY); + WARN_ON(!PagePrivate(pages[i])); + ClearPagePrivate(pages[i]); + set_phys_to_machine(pfn, pages[i]->index); + if (m2p_override) + ret = m2p_remove_override(pages[i], + kmap_ops ? + &kmap_ops[i] : NULL, + pfn, + mfn); if (ret) goto out; } @@ -979,8 +1029,22 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, return ret; } + +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); diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index 694dcaf..9a919b1 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -184,11 +184,15 @@ unsigned int gnttab_max_grant_frames(void); #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, - struct gnttab_map_grant_ref *kmap_ops, struct page **pages, unsigned int count); +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); int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, - struct gnttab_map_grant_ref *kunmap_ops, struct page **pages, unsigned int count); +int gnttab_unmap_refs_userspace(struct gnttab_unmap_grant_ref *unmap_ops, + struct gnttab_map_grant_ref *kunmap_ops, + struct page **pages, unsigned int count); /* Perform a batch of grant map/copy operations. Retry every batch slot * for which the hypervisor returns GNTST_eagain. This is typically due ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v5] xen/grant-table: Avoid m2p_override during mapping 2014-01-23 13:07 [PATCH v5] xen/grant-table: Avoid m2p_override during mapping Zoltan Kiss @ 2014-01-24 14:37 ` Konrad Rzeszutek Wilk 2014-01-24 14:37 ` [Xen-devel] " Konrad Rzeszutek Wilk 1 sibling, 0 replies; 7+ messages in thread From: Konrad Rzeszutek Wilk @ 2014-01-24 14:37 UTC (permalink / raw) To: Zoltan Kiss, Stefano Stabellini, david.vrabel, boris.ostrovsky Cc: jonathan.davies, wei.liu2, ian.campbell, netdev, linux-kernel, xen-devel On Thu, Jan 23, 2014 at 01:07:10PM +0000, 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 > > It also removes a stray space from page.h and change ret to 0 if > XENFEAT_auto_translated_physmap, as that is the only possible return value > there. > > 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 > > v4: > - move out the common bits from m2p* functions, and pass pfn/mfn as parameter > - clear page->private before doing anything with the page, so m2p_find_override > won't race with this > > v5: > - change return value handling in __gnttab_[un]map_refs > - remove a stray space in page.h > - add detail why ret = 0 now at some places > > Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com> > Suggested-by: David Vrabel <david.vrabel@citrix.com> It looks OK to me and while it is not a bug-fix I think it should go for v3.14 - as it _should_ improve the backends. David or Boris; Stefano, please Ack/Nack it. Thank you. > --- > arch/x86/include/asm/xen/page.h | 12 +++-- > arch/x86/xen/p2m.c | 25 ++-------- > drivers/block/xen-blkback/blkback.c | 15 +++--- > drivers/xen/gntdev.c | 13 +++-- > drivers/xen/grant-table.c | 90 ++++++++++++++++++++++++++++++----- > include/xen/grant_table.h | 8 +++- > 6 files changed, 109 insertions(+), 54 deletions(-) > > diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h > index b913915..68a1438 100644 > --- a/arch/x86/include/asm/xen/page.h > +++ b/arch/x86/include/asm/xen/page.h > @@ -49,10 +49,14 @@ extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); > extern unsigned long set_phys_range_identity(unsigned long pfn_s, > unsigned long pfn_e); > > -extern int m2p_add_override(unsigned long mfn, struct page *page, > - struct gnttab_map_grant_ref *kmap_op); > +extern int m2p_add_override(unsigned long mfn, > + struct page *page, > + struct gnttab_map_grant_ref *kmap_op, > + unsigned long pfn); > extern int m2p_remove_override(struct page *page, > - struct gnttab_map_grant_ref *kmap_op); > + struct gnttab_map_grant_ref *kmap_op, > + unsigned long pfn, > + unsigned long mfn); > extern struct page *m2p_find_override(unsigned long mfn); > extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); > > @@ -121,7 +125,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) > pfn = m2p_find_override_pfn(mfn, ~0); > } > > - /* > + /* > * pfn is ~0 if there are no entries in the m2p for mfn or if the > * entry doesn't map back to the mfn and m2p_override doesn't have a > * valid entry for it. > diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c > index 2ae8699..0060178 100644 > --- a/arch/x86/xen/p2m.c > +++ b/arch/x86/xen/p2m.c > @@ -872,15 +872,13 @@ static unsigned long mfn_hash(unsigned long mfn) > > /* Add an MFN override for a particular page */ > int m2p_add_override(unsigned long mfn, struct page *page, > - struct gnttab_map_grant_ref *kmap_op) > + struct gnttab_map_grant_ref *kmap_op, unsigned long pfn) > { > unsigned long flags; > - unsigned long pfn; > unsigned long uninitialized_var(address); > unsigned level; > pte_t *ptep = NULL; > > - pfn = page_to_pfn(page); > if (!PageHighMem(page)) { > address = (unsigned long)__va(pfn << PAGE_SHIFT); > ptep = lookup_address(address, &level); > @@ -888,13 +886,6 @@ int m2p_add_override(unsigned long mfn, struct page *page, > "m2p_add_override: pfn %lx not mapped", pfn)) > return -EINVAL; > } > - WARN_ON(PagePrivate(page)); > - SetPagePrivate(page); > - set_page_private(page, mfn); > - page->index = pfn_to_mfn(pfn); > - > - if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) > - return -ENOMEM; > > if (kmap_op != NULL) { > if (!PageHighMem(page)) { > @@ -933,20 +924,15 @@ int m2p_add_override(unsigned long mfn, struct page *page, > } > EXPORT_SYMBOL_GPL(m2p_add_override); > int m2p_remove_override(struct page *page, > - struct gnttab_map_grant_ref *kmap_op) > + struct gnttab_map_grant_ref *kmap_op, > + unsigned long pfn, > + unsigned long mfn) > { > unsigned long flags; > - unsigned long mfn; > - unsigned long pfn; > unsigned long uninitialized_var(address); > unsigned level; > pte_t *ptep = NULL; > > - pfn = page_to_pfn(page); > - mfn = get_phys_to_machine(pfn); > - if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) > - return -EINVAL; > - > if (!PageHighMem(page)) { > address = (unsigned long)__va(pfn << PAGE_SHIFT); > ptep = lookup_address(address, &level); > @@ -959,10 +945,7 @@ int m2p_remove_override(struct page *page, > spin_lock_irqsave(&m2p_override_lock, flags); > list_del(&page->lru); > spin_unlock_irqrestore(&m2p_override_lock, flags); > - WARN_ON(!PagePrivate(page)); > - ClearPagePrivate(page); > > - set_phys_to_machine(pfn, page->index); > if (kmap_op != NULL) { > if (!PageHighMem(page)) { > struct multicall_space mcs; > diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c > index 6620b73..875025f 100644 > --- a/drivers/block/xen-blkback/blkback.c > +++ b/drivers/block/xen-blkback/blkback.c > @@ -285,8 +285,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, > > if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || > !rb_next(&persistent_gnt->node)) { > - ret = gnttab_unmap_refs(unmap, NULL, pages, > - segs_to_unmap); > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > BUG_ON(ret); > put_free_pages(blkif, pages, segs_to_unmap); > segs_to_unmap = 0; > @@ -321,8 +320,7 @@ static void unmap_purged_grants(struct work_struct *work) > pages[segs_to_unmap] = persistent_gnt->page; > > if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { > - ret = gnttab_unmap_refs(unmap, NULL, pages, > - segs_to_unmap); > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > BUG_ON(ret); > put_free_pages(blkif, pages, segs_to_unmap); > segs_to_unmap = 0; > @@ -330,7 +328,7 @@ static void unmap_purged_grants(struct work_struct *work) > kfree(persistent_gnt); > } > if (segs_to_unmap > 0) { > - ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > BUG_ON(ret); > put_free_pages(blkif, pages, segs_to_unmap); > } > @@ -670,15 +668,14 @@ static void xen_blkbk_unmap(struct xen_blkif *blkif, > GNTMAP_host_map, pages[i]->handle); > pages[i]->handle = BLKBACK_INVALID_HANDLE; > if (++invcount == BLKIF_MAX_SEGMENTS_PER_REQUEST) { > - ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, > - invcount); > + ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); > BUG_ON(ret); > put_free_pages(blkif, unmap_pages, invcount); > invcount = 0; > } > } > if (invcount) { > - ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount); > + ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); > BUG_ON(ret); > put_free_pages(blkif, unmap_pages, invcount); > } > @@ -740,7 +737,7 @@ again: > } > > if (segs_to_map) { > - ret = gnttab_map_refs(map, NULL, pages_to_gnt, segs_to_map); > + ret = gnttab_map_refs(map, pages_to_gnt, segs_to_map); > BUG_ON(ret); > } > > diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c > index e41c79c..e652c0e 100644 > --- a/drivers/xen/gntdev.c > +++ b/drivers/xen/gntdev.c > @@ -284,8 +284,10 @@ static int map_grant_pages(struct grant_map *map) > } > > pr_debug("map %d+%d\n", map->index, map->count); > - err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL, > - map->pages, map->count); > + err = gnttab_map_refs_userspace(map->map_ops, > + use_ptemod ? map->kmap_ops : NULL, > + map->pages, > + map->count); > if (err) > return err; > > @@ -315,9 +317,10 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) > } > } > > - err = gnttab_unmap_refs(map->unmap_ops + offset, > - use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset, > - pages); > + err = gnttab_unmap_refs_userspace(map->unmap_ops + offset, > + use_ptemod ? map->kmap_ops + offset : NULL, > + map->pages + offset, > + pages); > if (err) > return err; > > diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c > index aa846a4..2add483 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; > + unsigned long mfn, pfn; > > + 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,20 @@ 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); > + 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)))) { > + ret = -ENOMEM; > + goto out; > + } > + if (m2p_override) > + ret = m2p_add_override(mfn, pages[i], kmap_ops ? > + &kmap_ops[i] : NULL, pfn); > if (ret) > goto out; > } > @@ -939,15 +955,32 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > > return ret; > } > + > +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; > + unsigned long pfn, mfn; > > + BUG_ON(kmap_ops && !m2p_override); > ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); > if (ret) > return ret; > @@ -958,17 +991,34 @@ 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); > + pfn = page_to_pfn(pages[i]); > + mfn = get_phys_to_machine(pfn); > + if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) { > + ret = -EINVAL; > + goto out; > + } > + > + set_page_private(pages[i], INVALID_P2M_ENTRY); > + WARN_ON(!PagePrivate(pages[i])); > + ClearPagePrivate(pages[i]); > + set_phys_to_machine(pfn, pages[i]->index); > + if (m2p_override) > + ret = m2p_remove_override(pages[i], > + kmap_ops ? > + &kmap_ops[i] : NULL, > + pfn, > + mfn); > if (ret) > goto out; > } > @@ -979,8 +1029,22 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, > > return ret; > } > + > +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); > diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h > index 694dcaf..9a919b1 100644 > --- a/include/xen/grant_table.h > +++ b/include/xen/grant_table.h > @@ -184,11 +184,15 @@ unsigned int gnttab_max_grant_frames(void); > #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) > > int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > - struct gnttab_map_grant_ref *kmap_ops, > struct page **pages, unsigned int count); > +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); > int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, > - struct gnttab_map_grant_ref *kunmap_ops, > struct page **pages, unsigned int count); > +int gnttab_unmap_refs_userspace(struct gnttab_unmap_grant_ref *unmap_ops, > + struct gnttab_map_grant_ref *kunmap_ops, > + struct page **pages, unsigned int count); > > /* Perform a batch of grant map/copy operations. Retry every batch slot > * for which the hypervisor returns GNTST_eagain. This is typically due > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xen-devel] [PATCH v5] xen/grant-table: Avoid m2p_override during mapping 2014-01-23 13:07 [PATCH v5] xen/grant-table: Avoid m2p_override during mapping Zoltan Kiss 2014-01-24 14:37 ` Konrad Rzeszutek Wilk @ 2014-01-24 14:37 ` Konrad Rzeszutek Wilk 2014-01-24 14:44 ` David Vrabel ` (3 more replies) 1 sibling, 4 replies; 7+ messages in thread From: Konrad Rzeszutek Wilk @ 2014-01-24 14:37 UTC (permalink / raw) To: Zoltan Kiss, Stefano Stabellini, david.vrabel, boris.ostrovsky Cc: ian.campbell, wei.liu2, xen-devel, netdev, linux-kernel, jonathan.davies On Thu, Jan 23, 2014 at 01:07:10PM +0000, 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 > > It also removes a stray space from page.h and change ret to 0 if > XENFEAT_auto_translated_physmap, as that is the only possible return value > there. > > 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 > > v4: > - move out the common bits from m2p* functions, and pass pfn/mfn as parameter > - clear page->private before doing anything with the page, so m2p_find_override > won't race with this > > v5: > - change return value handling in __gnttab_[un]map_refs > - remove a stray space in page.h > - add detail why ret = 0 now at some places > > Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com> > Suggested-by: David Vrabel <david.vrabel@citrix.com> It looks OK to me and while it is not a bug-fix I think it should go for v3.14 - as it _should_ improve the backends. David or Boris; Stefano, please Ack/Nack it. Thank you. > --- > arch/x86/include/asm/xen/page.h | 12 +++-- > arch/x86/xen/p2m.c | 25 ++-------- > drivers/block/xen-blkback/blkback.c | 15 +++--- > drivers/xen/gntdev.c | 13 +++-- > drivers/xen/grant-table.c | 90 ++++++++++++++++++++++++++++++----- > include/xen/grant_table.h | 8 +++- > 6 files changed, 109 insertions(+), 54 deletions(-) > > diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h > index b913915..68a1438 100644 > --- a/arch/x86/include/asm/xen/page.h > +++ b/arch/x86/include/asm/xen/page.h > @@ -49,10 +49,14 @@ extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); > extern unsigned long set_phys_range_identity(unsigned long pfn_s, > unsigned long pfn_e); > > -extern int m2p_add_override(unsigned long mfn, struct page *page, > - struct gnttab_map_grant_ref *kmap_op); > +extern int m2p_add_override(unsigned long mfn, > + struct page *page, > + struct gnttab_map_grant_ref *kmap_op, > + unsigned long pfn); > extern int m2p_remove_override(struct page *page, > - struct gnttab_map_grant_ref *kmap_op); > + struct gnttab_map_grant_ref *kmap_op, > + unsigned long pfn, > + unsigned long mfn); > extern struct page *m2p_find_override(unsigned long mfn); > extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); > > @@ -121,7 +125,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) > pfn = m2p_find_override_pfn(mfn, ~0); > } > > - /* > + /* > * pfn is ~0 if there are no entries in the m2p for mfn or if the > * entry doesn't map back to the mfn and m2p_override doesn't have a > * valid entry for it. > diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c > index 2ae8699..0060178 100644 > --- a/arch/x86/xen/p2m.c > +++ b/arch/x86/xen/p2m.c > @@ -872,15 +872,13 @@ static unsigned long mfn_hash(unsigned long mfn) > > /* Add an MFN override for a particular page */ > int m2p_add_override(unsigned long mfn, struct page *page, > - struct gnttab_map_grant_ref *kmap_op) > + struct gnttab_map_grant_ref *kmap_op, unsigned long pfn) > { > unsigned long flags; > - unsigned long pfn; > unsigned long uninitialized_var(address); > unsigned level; > pte_t *ptep = NULL; > > - pfn = page_to_pfn(page); > if (!PageHighMem(page)) { > address = (unsigned long)__va(pfn << PAGE_SHIFT); > ptep = lookup_address(address, &level); > @@ -888,13 +886,6 @@ int m2p_add_override(unsigned long mfn, struct page *page, > "m2p_add_override: pfn %lx not mapped", pfn)) > return -EINVAL; > } > - WARN_ON(PagePrivate(page)); > - SetPagePrivate(page); > - set_page_private(page, mfn); > - page->index = pfn_to_mfn(pfn); > - > - if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) > - return -ENOMEM; > > if (kmap_op != NULL) { > if (!PageHighMem(page)) { > @@ -933,20 +924,15 @@ int m2p_add_override(unsigned long mfn, struct page *page, > } > EXPORT_SYMBOL_GPL(m2p_add_override); > int m2p_remove_override(struct page *page, > - struct gnttab_map_grant_ref *kmap_op) > + struct gnttab_map_grant_ref *kmap_op, > + unsigned long pfn, > + unsigned long mfn) > { > unsigned long flags; > - unsigned long mfn; > - unsigned long pfn; > unsigned long uninitialized_var(address); > unsigned level; > pte_t *ptep = NULL; > > - pfn = page_to_pfn(page); > - mfn = get_phys_to_machine(pfn); > - if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) > - return -EINVAL; > - > if (!PageHighMem(page)) { > address = (unsigned long)__va(pfn << PAGE_SHIFT); > ptep = lookup_address(address, &level); > @@ -959,10 +945,7 @@ int m2p_remove_override(struct page *page, > spin_lock_irqsave(&m2p_override_lock, flags); > list_del(&page->lru); > spin_unlock_irqrestore(&m2p_override_lock, flags); > - WARN_ON(!PagePrivate(page)); > - ClearPagePrivate(page); > > - set_phys_to_machine(pfn, page->index); > if (kmap_op != NULL) { > if (!PageHighMem(page)) { > struct multicall_space mcs; > diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c > index 6620b73..875025f 100644 > --- a/drivers/block/xen-blkback/blkback.c > +++ b/drivers/block/xen-blkback/blkback.c > @@ -285,8 +285,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, > > if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || > !rb_next(&persistent_gnt->node)) { > - ret = gnttab_unmap_refs(unmap, NULL, pages, > - segs_to_unmap); > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > BUG_ON(ret); > put_free_pages(blkif, pages, segs_to_unmap); > segs_to_unmap = 0; > @@ -321,8 +320,7 @@ static void unmap_purged_grants(struct work_struct *work) > pages[segs_to_unmap] = persistent_gnt->page; > > if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { > - ret = gnttab_unmap_refs(unmap, NULL, pages, > - segs_to_unmap); > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > BUG_ON(ret); > put_free_pages(blkif, pages, segs_to_unmap); > segs_to_unmap = 0; > @@ -330,7 +328,7 @@ static void unmap_purged_grants(struct work_struct *work) > kfree(persistent_gnt); > } > if (segs_to_unmap > 0) { > - ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > BUG_ON(ret); > put_free_pages(blkif, pages, segs_to_unmap); > } > @@ -670,15 +668,14 @@ static void xen_blkbk_unmap(struct xen_blkif *blkif, > GNTMAP_host_map, pages[i]->handle); > pages[i]->handle = BLKBACK_INVALID_HANDLE; > if (++invcount == BLKIF_MAX_SEGMENTS_PER_REQUEST) { > - ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, > - invcount); > + ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); > BUG_ON(ret); > put_free_pages(blkif, unmap_pages, invcount); > invcount = 0; > } > } > if (invcount) { > - ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount); > + ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); > BUG_ON(ret); > put_free_pages(blkif, unmap_pages, invcount); > } > @@ -740,7 +737,7 @@ again: > } > > if (segs_to_map) { > - ret = gnttab_map_refs(map, NULL, pages_to_gnt, segs_to_map); > + ret = gnttab_map_refs(map, pages_to_gnt, segs_to_map); > BUG_ON(ret); > } > > diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c > index e41c79c..e652c0e 100644 > --- a/drivers/xen/gntdev.c > +++ b/drivers/xen/gntdev.c > @@ -284,8 +284,10 @@ static int map_grant_pages(struct grant_map *map) > } > > pr_debug("map %d+%d\n", map->index, map->count); > - err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL, > - map->pages, map->count); > + err = gnttab_map_refs_userspace(map->map_ops, > + use_ptemod ? map->kmap_ops : NULL, > + map->pages, > + map->count); > if (err) > return err; > > @@ -315,9 +317,10 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) > } > } > > - err = gnttab_unmap_refs(map->unmap_ops + offset, > - use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset, > - pages); > + err = gnttab_unmap_refs_userspace(map->unmap_ops + offset, > + use_ptemod ? map->kmap_ops + offset : NULL, > + map->pages + offset, > + pages); > if (err) > return err; > > diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c > index aa846a4..2add483 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; > + unsigned long mfn, pfn; > > + 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,20 @@ 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); > + 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)))) { > + ret = -ENOMEM; > + goto out; > + } > + if (m2p_override) > + ret = m2p_add_override(mfn, pages[i], kmap_ops ? > + &kmap_ops[i] : NULL, pfn); > if (ret) > goto out; > } > @@ -939,15 +955,32 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > > return ret; > } > + > +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; > + unsigned long pfn, mfn; > > + BUG_ON(kmap_ops && !m2p_override); > ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); > if (ret) > return ret; > @@ -958,17 +991,34 @@ 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); > + pfn = page_to_pfn(pages[i]); > + mfn = get_phys_to_machine(pfn); > + if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) { > + ret = -EINVAL; > + goto out; > + } > + > + set_page_private(pages[i], INVALID_P2M_ENTRY); > + WARN_ON(!PagePrivate(pages[i])); > + ClearPagePrivate(pages[i]); > + set_phys_to_machine(pfn, pages[i]->index); > + if (m2p_override) > + ret = m2p_remove_override(pages[i], > + kmap_ops ? > + &kmap_ops[i] : NULL, > + pfn, > + mfn); > if (ret) > goto out; > } > @@ -979,8 +1029,22 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, > > return ret; > } > + > +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); > diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h > index 694dcaf..9a919b1 100644 > --- a/include/xen/grant_table.h > +++ b/include/xen/grant_table.h > @@ -184,11 +184,15 @@ unsigned int gnttab_max_grant_frames(void); > #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) > > int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > - struct gnttab_map_grant_ref *kmap_ops, > struct page **pages, unsigned int count); > +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); > int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, > - struct gnttab_map_grant_ref *kunmap_ops, > struct page **pages, unsigned int count); > +int gnttab_unmap_refs_userspace(struct gnttab_unmap_grant_ref *unmap_ops, > + struct gnttab_map_grant_ref *kunmap_ops, > + struct page **pages, unsigned int count); > > /* Perform a batch of grant map/copy operations. Retry every batch slot > * for which the hypervisor returns GNTST_eagain. This is typically due > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5] xen/grant-table: Avoid m2p_override during mapping 2014-01-24 14:37 ` [Xen-devel] " Konrad Rzeszutek Wilk @ 2014-01-24 14:44 ` David Vrabel 2014-01-24 14:44 ` [Xen-devel] " David Vrabel ` (2 subsequent siblings) 3 siblings, 0 replies; 7+ messages in thread From: David Vrabel @ 2014-01-24 14:44 UTC (permalink / raw) To: Konrad Rzeszutek Wilk Cc: jonathan.davies, wei.liu2, ian.campbell, Stefano Stabellini, netdev, linux-kernel, Zoltan Kiss, xen-devel, boris.ostrovsky On 24/01/14 14:37, Konrad Rzeszutek Wilk wrote: > On Thu, Jan 23, 2014 at 01:07:10PM +0000, 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 >> >> It also removes a stray space from page.h and change ret to 0 if >> XENFEAT_auto_translated_physmap, as that is the only possible return value >> there. >> >> 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 >> >> v4: >> - move out the common bits from m2p* functions, and pass pfn/mfn as parameter >> - clear page->private before doing anything with the page, so m2p_find_override >> won't race with this >> >> v5: >> - change return value handling in __gnttab_[un]map_refs >> - remove a stray space in page.h >> - add detail why ret = 0 now at some places >> >> Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com> >> Suggested-by: David Vrabel <david.vrabel@citrix.com> > > It looks OK to me and while it is not a bug-fix I think it should > go for v3.14 - as it _should_ improve the backends. > > David or Boris; Stefano, please Ack/Nack it. Reviewed-by: David Vrabel <david.vrabel@citrix.com> David ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xen-devel] [PATCH v5] xen/grant-table: Avoid m2p_override during mapping 2014-01-24 14:37 ` [Xen-devel] " Konrad Rzeszutek Wilk 2014-01-24 14:44 ` David Vrabel @ 2014-01-24 14:44 ` David Vrabel 2014-01-24 14:48 ` Stefano Stabellini 2014-01-24 14:48 ` Stefano Stabellini 3 siblings, 0 replies; 7+ messages in thread From: David Vrabel @ 2014-01-24 14:44 UTC (permalink / raw) To: Konrad Rzeszutek Wilk Cc: Zoltan Kiss, Stefano Stabellini, boris.ostrovsky, ian.campbell, wei.liu2, xen-devel, netdev, linux-kernel, jonathan.davies On 24/01/14 14:37, Konrad Rzeszutek Wilk wrote: > On Thu, Jan 23, 2014 at 01:07:10PM +0000, 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 >> >> It also removes a stray space from page.h and change ret to 0 if >> XENFEAT_auto_translated_physmap, as that is the only possible return value >> there. >> >> 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 >> >> v4: >> - move out the common bits from m2p* functions, and pass pfn/mfn as parameter >> - clear page->private before doing anything with the page, so m2p_find_override >> won't race with this >> >> v5: >> - change return value handling in __gnttab_[un]map_refs >> - remove a stray space in page.h >> - add detail why ret = 0 now at some places >> >> Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com> >> Suggested-by: David Vrabel <david.vrabel@citrix.com> > > It looks OK to me and while it is not a bug-fix I think it should > go for v3.14 - as it _should_ improve the backends. > > David or Boris; Stefano, please Ack/Nack it. Reviewed-by: David Vrabel <david.vrabel@citrix.com> David ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xen-devel] [PATCH v5] xen/grant-table: Avoid m2p_override during mapping 2014-01-24 14:37 ` [Xen-devel] " Konrad Rzeszutek Wilk 2014-01-24 14:44 ` David Vrabel 2014-01-24 14:44 ` [Xen-devel] " David Vrabel @ 2014-01-24 14:48 ` Stefano Stabellini 2014-01-24 14:48 ` Stefano Stabellini 3 siblings, 0 replies; 7+ messages in thread From: Stefano Stabellini @ 2014-01-24 14:48 UTC (permalink / raw) To: Konrad Rzeszutek Wilk Cc: Zoltan Kiss, Stefano Stabellini, david.vrabel, boris.ostrovsky, ian.campbell, wei.liu2, xen-devel, netdev, linux-kernel, jonathan.davies On Fri, 24 Jan 2014, Konrad Rzeszutek Wilk wrote: > On Thu, Jan 23, 2014 at 01:07:10PM +0000, 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 > > > > It also removes a stray space from page.h and change ret to 0 if > > XENFEAT_auto_translated_physmap, as that is the only possible return value > > there. > > > > 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 > > > > v4: > > - move out the common bits from m2p* functions, and pass pfn/mfn as parameter > > - clear page->private before doing anything with the page, so m2p_find_override > > won't race with this > > > > v5: > > - change return value handling in __gnttab_[un]map_refs > > - remove a stray space in page.h > > - add detail why ret = 0 now at some places > > > > Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com> > > Suggested-by: David Vrabel <david.vrabel@citrix.com> > > It looks OK to me and while it is not a bug-fix I think it should > go for v3.14 - as it _should_ improve the backends. > > David or Boris; Stefano, please Ack/Nack it. > > Thank you. I reviewed-by the v6 version of the patch > > arch/x86/include/asm/xen/page.h | 12 +++-- > > arch/x86/xen/p2m.c | 25 ++-------- > > drivers/block/xen-blkback/blkback.c | 15 +++--- > > drivers/xen/gntdev.c | 13 +++-- > > drivers/xen/grant-table.c | 90 ++++++++++++++++++++++++++++++----- > > include/xen/grant_table.h | 8 +++- > > 6 files changed, 109 insertions(+), 54 deletions(-) > > > > diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h > > index b913915..68a1438 100644 > > --- a/arch/x86/include/asm/xen/page.h > > +++ b/arch/x86/include/asm/xen/page.h > > @@ -49,10 +49,14 @@ extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); > > extern unsigned long set_phys_range_identity(unsigned long pfn_s, > > unsigned long pfn_e); > > > > -extern int m2p_add_override(unsigned long mfn, struct page *page, > > - struct gnttab_map_grant_ref *kmap_op); > > +extern int m2p_add_override(unsigned long mfn, > > + struct page *page, > > + struct gnttab_map_grant_ref *kmap_op, > > + unsigned long pfn); > > extern int m2p_remove_override(struct page *page, > > - struct gnttab_map_grant_ref *kmap_op); > > + struct gnttab_map_grant_ref *kmap_op, > > + unsigned long pfn, > > + unsigned long mfn); > > extern struct page *m2p_find_override(unsigned long mfn); > > extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); > > > > @@ -121,7 +125,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) > > pfn = m2p_find_override_pfn(mfn, ~0); > > } > > > > - /* > > + /* > > * pfn is ~0 if there are no entries in the m2p for mfn or if the > > * entry doesn't map back to the mfn and m2p_override doesn't have a > > * valid entry for it. > > diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c > > index 2ae8699..0060178 100644 > > --- a/arch/x86/xen/p2m.c > > +++ b/arch/x86/xen/p2m.c > > @@ -872,15 +872,13 @@ static unsigned long mfn_hash(unsigned long mfn) > > > > /* Add an MFN override for a particular page */ > > int m2p_add_override(unsigned long mfn, struct page *page, > > - struct gnttab_map_grant_ref *kmap_op) > > + struct gnttab_map_grant_ref *kmap_op, unsigned long pfn) > > { > > unsigned long flags; > > - unsigned long pfn; > > unsigned long uninitialized_var(address); > > unsigned level; > > pte_t *ptep = NULL; > > > > - pfn = page_to_pfn(page); > > if (!PageHighMem(page)) { > > address = (unsigned long)__va(pfn << PAGE_SHIFT); > > ptep = lookup_address(address, &level); > > @@ -888,13 +886,6 @@ int m2p_add_override(unsigned long mfn, struct page *page, > > "m2p_add_override: pfn %lx not mapped", pfn)) > > return -EINVAL; > > } > > - WARN_ON(PagePrivate(page)); > > - SetPagePrivate(page); > > - set_page_private(page, mfn); > > - page->index = pfn_to_mfn(pfn); > > - > > - if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) > > - return -ENOMEM; > > > > if (kmap_op != NULL) { > > if (!PageHighMem(page)) { > > @@ -933,20 +924,15 @@ int m2p_add_override(unsigned long mfn, struct page *page, > > } > > EXPORT_SYMBOL_GPL(m2p_add_override); > > int m2p_remove_override(struct page *page, > > - struct gnttab_map_grant_ref *kmap_op) > > + struct gnttab_map_grant_ref *kmap_op, > > + unsigned long pfn, > > + unsigned long mfn) > > { > > unsigned long flags; > > - unsigned long mfn; > > - unsigned long pfn; > > unsigned long uninitialized_var(address); > > unsigned level; > > pte_t *ptep = NULL; > > > > - pfn = page_to_pfn(page); > > - mfn = get_phys_to_machine(pfn); > > - if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) > > - return -EINVAL; > > - > > if (!PageHighMem(page)) { > > address = (unsigned long)__va(pfn << PAGE_SHIFT); > > ptep = lookup_address(address, &level); > > @@ -959,10 +945,7 @@ int m2p_remove_override(struct page *page, > > spin_lock_irqsave(&m2p_override_lock, flags); > > list_del(&page->lru); > > spin_unlock_irqrestore(&m2p_override_lock, flags); > > - WARN_ON(!PagePrivate(page)); > > - ClearPagePrivate(page); > > > > - set_phys_to_machine(pfn, page->index); > > if (kmap_op != NULL) { > > if (!PageHighMem(page)) { > > struct multicall_space mcs; > > diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c > > index 6620b73..875025f 100644 > > --- a/drivers/block/xen-blkback/blkback.c > > +++ b/drivers/block/xen-blkback/blkback.c > > @@ -285,8 +285,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, > > > > if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || > > !rb_next(&persistent_gnt->node)) { > > - ret = gnttab_unmap_refs(unmap, NULL, pages, > > - segs_to_unmap); > > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > > BUG_ON(ret); > > put_free_pages(blkif, pages, segs_to_unmap); > > segs_to_unmap = 0; > > @@ -321,8 +320,7 @@ static void unmap_purged_grants(struct work_struct *work) > > pages[segs_to_unmap] = persistent_gnt->page; > > > > if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { > > - ret = gnttab_unmap_refs(unmap, NULL, pages, > > - segs_to_unmap); > > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > > BUG_ON(ret); > > put_free_pages(blkif, pages, segs_to_unmap); > > segs_to_unmap = 0; > > @@ -330,7 +328,7 @@ static void unmap_purged_grants(struct work_struct *work) > > kfree(persistent_gnt); > > } > > if (segs_to_unmap > 0) { > > - ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); > > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > > BUG_ON(ret); > > put_free_pages(blkif, pages, segs_to_unmap); > > } > > @@ -670,15 +668,14 @@ static void xen_blkbk_unmap(struct xen_blkif *blkif, > > GNTMAP_host_map, pages[i]->handle); > > pages[i]->handle = BLKBACK_INVALID_HANDLE; > > if (++invcount == BLKIF_MAX_SEGMENTS_PER_REQUEST) { > > - ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, > > - invcount); > > + ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); > > BUG_ON(ret); > > put_free_pages(blkif, unmap_pages, invcount); > > invcount = 0; > > } > > } > > if (invcount) { > > - ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount); > > + ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); > > BUG_ON(ret); > > put_free_pages(blkif, unmap_pages, invcount); > > } > > @@ -740,7 +737,7 @@ again: > > } > > > > if (segs_to_map) { > > - ret = gnttab_map_refs(map, NULL, pages_to_gnt, segs_to_map); > > + ret = gnttab_map_refs(map, pages_to_gnt, segs_to_map); > > BUG_ON(ret); > > } > > > > diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c > > index e41c79c..e652c0e 100644 > > --- a/drivers/xen/gntdev.c > > +++ b/drivers/xen/gntdev.c > > @@ -284,8 +284,10 @@ static int map_grant_pages(struct grant_map *map) > > } > > > > pr_debug("map %d+%d\n", map->index, map->count); > > - err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL, > > - map->pages, map->count); > > + err = gnttab_map_refs_userspace(map->map_ops, > > + use_ptemod ? map->kmap_ops : NULL, > > + map->pages, > > + map->count); > > if (err) > > return err; > > > > @@ -315,9 +317,10 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) > > } > > } > > > > - err = gnttab_unmap_refs(map->unmap_ops + offset, > > - use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset, > > - pages); > > + err = gnttab_unmap_refs_userspace(map->unmap_ops + offset, > > + use_ptemod ? map->kmap_ops + offset : NULL, > > + map->pages + offset, > > + pages); > > if (err) > > return err; > > > > diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c > > index aa846a4..2add483 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; > > + unsigned long mfn, pfn; > > > > + 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,20 @@ 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); > > + 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)))) { > > + ret = -ENOMEM; > > + goto out; > > + } > > + if (m2p_override) > > + ret = m2p_add_override(mfn, pages[i], kmap_ops ? > > + &kmap_ops[i] : NULL, pfn); > > if (ret) > > goto out; > > } > > @@ -939,15 +955,32 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > > > > return ret; > > } > > + > > +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; > > + unsigned long pfn, mfn; > > > > + BUG_ON(kmap_ops && !m2p_override); > > ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); > > if (ret) > > return ret; > > @@ -958,17 +991,34 @@ 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); > > + pfn = page_to_pfn(pages[i]); > > + mfn = get_phys_to_machine(pfn); > > + if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) { > > + ret = -EINVAL; > > + goto out; > > + } > > + > > + set_page_private(pages[i], INVALID_P2M_ENTRY); > > + WARN_ON(!PagePrivate(pages[i])); > > + ClearPagePrivate(pages[i]); > > + set_phys_to_machine(pfn, pages[i]->index); > > + if (m2p_override) > > + ret = m2p_remove_override(pages[i], > > + kmap_ops ? > > + &kmap_ops[i] : NULL, > > + pfn, > > + mfn); > > if (ret) > > goto out; > > } > > @@ -979,8 +1029,22 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, > > > > return ret; > > } > > + > > +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); > > diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h > > index 694dcaf..9a919b1 100644 > > --- a/include/xen/grant_table.h > > +++ b/include/xen/grant_table.h > > @@ -184,11 +184,15 @@ unsigned int gnttab_max_grant_frames(void); > > #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) > > > > int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > > - struct gnttab_map_grant_ref *kmap_ops, > > struct page **pages, unsigned int count); > > +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); > > int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, > > - struct gnttab_map_grant_ref *kunmap_ops, > > struct page **pages, unsigned int count); > > +int gnttab_unmap_refs_userspace(struct gnttab_unmap_grant_ref *unmap_ops, > > + struct gnttab_map_grant_ref *kunmap_ops, > > + struct page **pages, unsigned int count); > > > > /* Perform a batch of grant map/copy operations. Retry every batch slot > > * for which the hypervisor returns GNTST_eagain. This is typically due > > > > _______________________________________________ > > Xen-devel mailing list > > Xen-devel@lists.xen.org > > http://lists.xen.org/xen-devel > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5] xen/grant-table: Avoid m2p_override during mapping 2014-01-24 14:37 ` [Xen-devel] " Konrad Rzeszutek Wilk ` (2 preceding siblings ...) 2014-01-24 14:48 ` Stefano Stabellini @ 2014-01-24 14:48 ` Stefano Stabellini 3 siblings, 0 replies; 7+ messages in thread From: Stefano Stabellini @ 2014-01-24 14:48 UTC (permalink / raw) To: Konrad Rzeszutek Wilk Cc: jonathan.davies, wei.liu2, ian.campbell, Stefano Stabellini, netdev, linux-kernel, david.vrabel, Zoltan Kiss, xen-devel, boris.ostrovsky On Fri, 24 Jan 2014, Konrad Rzeszutek Wilk wrote: > On Thu, Jan 23, 2014 at 01:07:10PM +0000, 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 > > > > It also removes a stray space from page.h and change ret to 0 if > > XENFEAT_auto_translated_physmap, as that is the only possible return value > > there. > > > > 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 > > > > v4: > > - move out the common bits from m2p* functions, and pass pfn/mfn as parameter > > - clear page->private before doing anything with the page, so m2p_find_override > > won't race with this > > > > v5: > > - change return value handling in __gnttab_[un]map_refs > > - remove a stray space in page.h > > - add detail why ret = 0 now at some places > > > > Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com> > > Suggested-by: David Vrabel <david.vrabel@citrix.com> > > It looks OK to me and while it is not a bug-fix I think it should > go for v3.14 - as it _should_ improve the backends. > > David or Boris; Stefano, please Ack/Nack it. > > Thank you. I reviewed-by the v6 version of the patch > > arch/x86/include/asm/xen/page.h | 12 +++-- > > arch/x86/xen/p2m.c | 25 ++-------- > > drivers/block/xen-blkback/blkback.c | 15 +++--- > > drivers/xen/gntdev.c | 13 +++-- > > drivers/xen/grant-table.c | 90 ++++++++++++++++++++++++++++++----- > > include/xen/grant_table.h | 8 +++- > > 6 files changed, 109 insertions(+), 54 deletions(-) > > > > diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h > > index b913915..68a1438 100644 > > --- a/arch/x86/include/asm/xen/page.h > > +++ b/arch/x86/include/asm/xen/page.h > > @@ -49,10 +49,14 @@ extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); > > extern unsigned long set_phys_range_identity(unsigned long pfn_s, > > unsigned long pfn_e); > > > > -extern int m2p_add_override(unsigned long mfn, struct page *page, > > - struct gnttab_map_grant_ref *kmap_op); > > +extern int m2p_add_override(unsigned long mfn, > > + struct page *page, > > + struct gnttab_map_grant_ref *kmap_op, > > + unsigned long pfn); > > extern int m2p_remove_override(struct page *page, > > - struct gnttab_map_grant_ref *kmap_op); > > + struct gnttab_map_grant_ref *kmap_op, > > + unsigned long pfn, > > + unsigned long mfn); > > extern struct page *m2p_find_override(unsigned long mfn); > > extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); > > > > @@ -121,7 +125,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) > > pfn = m2p_find_override_pfn(mfn, ~0); > > } > > > > - /* > > + /* > > * pfn is ~0 if there are no entries in the m2p for mfn or if the > > * entry doesn't map back to the mfn and m2p_override doesn't have a > > * valid entry for it. > > diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c > > index 2ae8699..0060178 100644 > > --- a/arch/x86/xen/p2m.c > > +++ b/arch/x86/xen/p2m.c > > @@ -872,15 +872,13 @@ static unsigned long mfn_hash(unsigned long mfn) > > > > /* Add an MFN override for a particular page */ > > int m2p_add_override(unsigned long mfn, struct page *page, > > - struct gnttab_map_grant_ref *kmap_op) > > + struct gnttab_map_grant_ref *kmap_op, unsigned long pfn) > > { > > unsigned long flags; > > - unsigned long pfn; > > unsigned long uninitialized_var(address); > > unsigned level; > > pte_t *ptep = NULL; > > > > - pfn = page_to_pfn(page); > > if (!PageHighMem(page)) { > > address = (unsigned long)__va(pfn << PAGE_SHIFT); > > ptep = lookup_address(address, &level); > > @@ -888,13 +886,6 @@ int m2p_add_override(unsigned long mfn, struct page *page, > > "m2p_add_override: pfn %lx not mapped", pfn)) > > return -EINVAL; > > } > > - WARN_ON(PagePrivate(page)); > > - SetPagePrivate(page); > > - set_page_private(page, mfn); > > - page->index = pfn_to_mfn(pfn); > > - > > - if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) > > - return -ENOMEM; > > > > if (kmap_op != NULL) { > > if (!PageHighMem(page)) { > > @@ -933,20 +924,15 @@ int m2p_add_override(unsigned long mfn, struct page *page, > > } > > EXPORT_SYMBOL_GPL(m2p_add_override); > > int m2p_remove_override(struct page *page, > > - struct gnttab_map_grant_ref *kmap_op) > > + struct gnttab_map_grant_ref *kmap_op, > > + unsigned long pfn, > > + unsigned long mfn) > > { > > unsigned long flags; > > - unsigned long mfn; > > - unsigned long pfn; > > unsigned long uninitialized_var(address); > > unsigned level; > > pte_t *ptep = NULL; > > > > - pfn = page_to_pfn(page); > > - mfn = get_phys_to_machine(pfn); > > - if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) > > - return -EINVAL; > > - > > if (!PageHighMem(page)) { > > address = (unsigned long)__va(pfn << PAGE_SHIFT); > > ptep = lookup_address(address, &level); > > @@ -959,10 +945,7 @@ int m2p_remove_override(struct page *page, > > spin_lock_irqsave(&m2p_override_lock, flags); > > list_del(&page->lru); > > spin_unlock_irqrestore(&m2p_override_lock, flags); > > - WARN_ON(!PagePrivate(page)); > > - ClearPagePrivate(page); > > > > - set_phys_to_machine(pfn, page->index); > > if (kmap_op != NULL) { > > if (!PageHighMem(page)) { > > struct multicall_space mcs; > > diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c > > index 6620b73..875025f 100644 > > --- a/drivers/block/xen-blkback/blkback.c > > +++ b/drivers/block/xen-blkback/blkback.c > > @@ -285,8 +285,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, > > > > if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || > > !rb_next(&persistent_gnt->node)) { > > - ret = gnttab_unmap_refs(unmap, NULL, pages, > > - segs_to_unmap); > > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > > BUG_ON(ret); > > put_free_pages(blkif, pages, segs_to_unmap); > > segs_to_unmap = 0; > > @@ -321,8 +320,7 @@ static void unmap_purged_grants(struct work_struct *work) > > pages[segs_to_unmap] = persistent_gnt->page; > > > > if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { > > - ret = gnttab_unmap_refs(unmap, NULL, pages, > > - segs_to_unmap); > > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > > BUG_ON(ret); > > put_free_pages(blkif, pages, segs_to_unmap); > > segs_to_unmap = 0; > > @@ -330,7 +328,7 @@ static void unmap_purged_grants(struct work_struct *work) > > kfree(persistent_gnt); > > } > > if (segs_to_unmap > 0) { > > - ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); > > + ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); > > BUG_ON(ret); > > put_free_pages(blkif, pages, segs_to_unmap); > > } > > @@ -670,15 +668,14 @@ static void xen_blkbk_unmap(struct xen_blkif *blkif, > > GNTMAP_host_map, pages[i]->handle); > > pages[i]->handle = BLKBACK_INVALID_HANDLE; > > if (++invcount == BLKIF_MAX_SEGMENTS_PER_REQUEST) { > > - ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, > > - invcount); > > + ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); > > BUG_ON(ret); > > put_free_pages(blkif, unmap_pages, invcount); > > invcount = 0; > > } > > } > > if (invcount) { > > - ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount); > > + ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); > > BUG_ON(ret); > > put_free_pages(blkif, unmap_pages, invcount); > > } > > @@ -740,7 +737,7 @@ again: > > } > > > > if (segs_to_map) { > > - ret = gnttab_map_refs(map, NULL, pages_to_gnt, segs_to_map); > > + ret = gnttab_map_refs(map, pages_to_gnt, segs_to_map); > > BUG_ON(ret); > > } > > > > diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c > > index e41c79c..e652c0e 100644 > > --- a/drivers/xen/gntdev.c > > +++ b/drivers/xen/gntdev.c > > @@ -284,8 +284,10 @@ static int map_grant_pages(struct grant_map *map) > > } > > > > pr_debug("map %d+%d\n", map->index, map->count); > > - err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL, > > - map->pages, map->count); > > + err = gnttab_map_refs_userspace(map->map_ops, > > + use_ptemod ? map->kmap_ops : NULL, > > + map->pages, > > + map->count); > > if (err) > > return err; > > > > @@ -315,9 +317,10 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) > > } > > } > > > > - err = gnttab_unmap_refs(map->unmap_ops + offset, > > - use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset, > > - pages); > > + err = gnttab_unmap_refs_userspace(map->unmap_ops + offset, > > + use_ptemod ? map->kmap_ops + offset : NULL, > > + map->pages + offset, > > + pages); > > if (err) > > return err; > > > > diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c > > index aa846a4..2add483 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; > > + unsigned long mfn, pfn; > > > > + 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,20 @@ 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); > > + 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)))) { > > + ret = -ENOMEM; > > + goto out; > > + } > > + if (m2p_override) > > + ret = m2p_add_override(mfn, pages[i], kmap_ops ? > > + &kmap_ops[i] : NULL, pfn); > > if (ret) > > goto out; > > } > > @@ -939,15 +955,32 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > > > > return ret; > > } > > + > > +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; > > + unsigned long pfn, mfn; > > > > + BUG_ON(kmap_ops && !m2p_override); > > ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); > > if (ret) > > return ret; > > @@ -958,17 +991,34 @@ 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); > > + pfn = page_to_pfn(pages[i]); > > + mfn = get_phys_to_machine(pfn); > > + if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) { > > + ret = -EINVAL; > > + goto out; > > + } > > + > > + set_page_private(pages[i], INVALID_P2M_ENTRY); > > + WARN_ON(!PagePrivate(pages[i])); > > + ClearPagePrivate(pages[i]); > > + set_phys_to_machine(pfn, pages[i]->index); > > + if (m2p_override) > > + ret = m2p_remove_override(pages[i], > > + kmap_ops ? > > + &kmap_ops[i] : NULL, > > + pfn, > > + mfn); > > if (ret) > > goto out; > > } > > @@ -979,8 +1029,22 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, > > > > return ret; > > } > > + > > +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); > > diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h > > index 694dcaf..9a919b1 100644 > > --- a/include/xen/grant_table.h > > +++ b/include/xen/grant_table.h > > @@ -184,11 +184,15 @@ unsigned int gnttab_max_grant_frames(void); > > #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) > > > > int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, > > - struct gnttab_map_grant_ref *kmap_ops, > > struct page **pages, unsigned int count); > > +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); > > int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, > > - struct gnttab_map_grant_ref *kunmap_ops, > > struct page **pages, unsigned int count); > > +int gnttab_unmap_refs_userspace(struct gnttab_unmap_grant_ref *unmap_ops, > > + struct gnttab_map_grant_ref *kunmap_ops, > > + struct page **pages, unsigned int count); > > > > /* Perform a batch of grant map/copy operations. Retry every batch slot > > * for which the hypervisor returns GNTST_eagain. This is typically due > > > > _______________________________________________ > > Xen-devel mailing list > > Xen-devel@lists.xen.org > > http://lists.xen.org/xen-devel > ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-01-24 14:50 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-01-23 13:07 [PATCH v5] xen/grant-table: Avoid m2p_override during mapping Zoltan Kiss 2014-01-24 14:37 ` Konrad Rzeszutek Wilk 2014-01-24 14:37 ` [Xen-devel] " Konrad Rzeszutek Wilk 2014-01-24 14:44 ` David Vrabel 2014-01-24 14:44 ` [Xen-devel] " David Vrabel 2014-01-24 14:48 ` Stefano Stabellini 2014-01-24 14:48 ` Stefano Stabellini
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.