diff mbox

[Xen-devel,RFC,2/3] xen/grant-table: Extend API to work with DMA buffers

Message ID 20180517082604.14828-3-andr2000@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Oleksandr Andrushchenko May 17, 2018, 8:26 a.m. UTC
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(+)

Comments

Boris Ostrovsky May 18, 2018, 10:19 p.m. UTC | #1
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.

-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);
Oleksandr Andrushchenko May 21, 2018, 5:44 a.m. UTC | #2
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);
diff mbox

Patch

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);
+
 /* 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);