Messages in this thread | | | Subject | Re: [Xen-devel][RFC 2/3] xen/grant-table: Extend API to work with DMA buffers | From | Oleksandr Andrushchenko <> | Date | Mon, 21 May 2018 08:44:40 +0300 |
| |
On 05/19/2018 01:19 AM, Boris Ostrovsky wrote: > On 05/17/2018 04:26 AM, Oleksandr Andrushchenko wrote: >> From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> >> >> Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> >> --- >> drivers/xen/grant-table.c | 49 +++++++++++++++++++++++++++++++++++++++ >> include/xen/grant_table.h | 7 ++++++ >> 2 files changed, 56 insertions(+) >> >> diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c >> index bb36b1e1dbcc..c27bcc420575 100644 >> --- a/drivers/xen/grant-table.c >> +++ b/drivers/xen/grant-table.c >> @@ -729,6 +729,55 @@ void gnttab_free_pages(int nr_pages, struct page **pages) >> } >> EXPORT_SYMBOL(gnttab_free_pages); >> >> +int gnttab_dma_alloc_pages(struct device *dev, bool coherent, >> + int nr_pages, struct page **pages, >> + void **vaddr, dma_addr_t *dev_bus_addr) >> +{ >> + int i; >> + int ret; >> + >> + ret = alloc_dma_xenballooned_pages(dev, coherent, nr_pages, pages, >> + vaddr, dev_bus_addr); >> + if (ret < 0) >> + return ret; >> + >> + for (i = 0; i < nr_pages; i++) { >> +#if BITS_PER_LONG < 64 >> + struct xen_page_foreign *foreign; >> + >> + foreign = kzalloc(sizeof(*foreign), GFP_KERNEL); >> + if (!foreign) { >> + gnttab_dma_free_pages(dev, flags, nr_pages, pages, >> + *vaddr, *dev_bus_addr); >> + return -ENOMEM; >> + } >> + set_page_private(pages[i], (unsigned long)foreign); >> +#endif >> + SetPagePrivate(pages[i]); >> + } >> + return 0; >> +} >> +EXPORT_SYMBOL(gnttab_dma_alloc_pages); >> + >> +void gnttab_dma_free_pages(struct device *dev, bool coherent, >> + int nr_pages, struct page **pages, >> + void *vaddr, dma_addr_t dev_bus_addr) >> +{ >> + int i; >> + >> + for (i = 0; i < nr_pages; i++) { >> + if (PagePrivate(pages[i])) { >> +#if BITS_PER_LONG < 64 >> + kfree((void *)page_private(pages[i])); >> +#endif >> + ClearPagePrivate(pages[i]); >> + } >> + } >> + free_dma_xenballooned_pages(dev, coherent, nr_pages, pages, >> + vaddr, dev_bus_addr); >> +} >> +EXPORT_SYMBOL(gnttab_dma_free_pages); > > Given that these routines look almost exactly like their non-dma > counterparts I wonder whether common code could be factored out. Yes, this can be done > -boris > > > > >> + >> /* Handling of paged out grant targets (GNTST_eagain) */ >> #define MAX_DELAY 256 >> static inline void >> diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h >> index 34b1379f9777..20ee2b5ba965 100644 >> --- a/include/xen/grant_table.h >> +++ b/include/xen/grant_table.h >> @@ -195,6 +195,13 @@ void gnttab_free_auto_xlat_frames(void); >> int gnttab_alloc_pages(int nr_pages, struct page **pages); >> void gnttab_free_pages(int nr_pages, struct page **pages); >> >> +int gnttab_dma_alloc_pages(struct device *dev, bool coherent, >> + int nr_pages, struct page **pages, >> + void **vaddr, dma_addr_t *dev_bus_addr); >> +void gnttab_dma_free_pages(struct device *dev, bool coherent, >> + int nr_pages, struct page **pages, >> + void *vaddr, dma_addr_t dev_bus_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);
| |