arm:dma-mapping Refactoring iommu dma-mapping code
Subsystems (6)
cover arm:dma-mapping Refactoring iommu dma-mapping code
From: Ritesh Harjani <[email protected]>
Hi All,
This patch series is to refractor iommu related common code from arch/arm/dma-mapping.c to lib/iommu-helper.c based on the various discussions with the maintainers/experts [1].
Currently the only user of the common lib/iommu-helper code will be ARM & ARM64 but later various architecture might try to use this iommu lib helper functions.
Major change of this refactoring starts with bringing out struct dma_iommu_mapping *mapping variable from arch/arm/include/asm/device.h to include/linux/device.h and by moving out complete structure defination of dma_iommu_mapping to inclue/linux/iommu-helper.h. Link [2] give more details on why this was done, also this change got approval from Will Daecon [2].
There are 1/2 more function definitions which I can think of moving out, but those can be done once this patch series is approved as those are not very big changes.
[1]: https://www.mail-archive.com/iommu at lists.linux-foundation.org/msg03458.html [2]: https://www.mail-archive.com/iommu at lists.linux-foundation.org/msg04272.html
Ritesh Harjani (4):
arm: dma-iommu: Move out dma_iommu_mapping struct
arm: dma-mapping: Refractor attach/detach dev function calls
arm: dma-mapping: Refractor iommu_alloc/free funcs arm:dma-iommu: Move out complete func defs
arch/arm/Kconfig | 46 +-- arch/arm/include/asm/device.h | 9 - arch/arm/include/asm/dma-iommu.h | 16 +- arch/arm/mm/dma-mapping.c | 566 +++--------------------------- drivers/gpu/drm/exynos/exynos_drm_iommu.c | 10 +- include/linux/device.h | 4 + include/linux/iommu-helper.h | 64 ++++ lib/iommu-helper.c | 561 +++++++++++++++++++++++++++++ 8 files changed, 705 insertions(+), 571 deletions(-)
Signature · 1 line
1.8.1.3
PATCH 1/4 arm: dma-iommu: Move out dma_iommu_mapping struct
From: Ritesh Harjani <[email protected]>
This patch is the 1st in the refractoring patch series of arm, dma-iommu-mapping code, which brings dma_iommu_mapping structure out to include/linux/iommu-helper.h
1. take out dma_iommu_mapping variable from arch/arm/asm/include/device.h to include/linux/device.h
2. take out complete structure defination of dma_iommu_mapping to include/linux/iommu-helper.h
3. Protect this variable with a config and let the archs define this config based on their use.
--- arch/arm/Kconfig | 4 ++++ arch/arm/include/asm/device.h | 9 --------- arch/arm/include/asm/dma-iommu.h | 16 +--------------- arch/arm/mm/dma-mapping.c | 20 ++++++++++---------- drivers/gpu/drm/exynos/exynos_drm_iommu.c | 10 +++++----- include/linux/device.h | 4 ++++ include/linux/iommu-helper.h | 22 ++++++++++++++++++++++ 7 files changed, 46 insertions(+), 39 deletions(-)
arch/arm/Kconfig +4 -0
@@ -78,6 +78,7 @@ config ARM_DMA_USE_IOMMU bool select ARM_HAS_SG_CHAIN select NEED_SG_DMA_LENGTH + select DMA_USE_IOMMU_HELPER_MAPPING if ARM_DMA_USE_IOMMU
@@ -1945,6 +1946,9 @@ config SWIOTLB config IOMMU_HELPER def_bool SWIOTLB +config DMA_USE_IOMMU_HELPER_MAPPING + def_bool n + config XEN_DOM0 def_bool y depends on XEN
arch/arm/include/asm/device.h +0 -9
@@ -14,9 +14,6 @@ struct dev_archdata {#ifdef CONFIG_IOMMU_API void *iommu;/* private IOMMU data */ #endif -#ifdef CONFIG_ARM_DMA_USE_IOMMU -struct dma_iommu_mapping *mapping; -#endif };struct omap_device ;
@@ -27,10 +24,4 @@ struct pdev_archdata { #endif }; -#ifdef CONFIG_ARM_DMA_USE_IOMMU -#define to_dma_iommu_mapping (dev) ((dev)->archdata.mapping) -#else -#define to_dma_iommu_mapping (dev) NULL -#endif -#endif
arch/arm/include/asm/dma-iommu.h +1 -15
@@ -8,21 +8,7 @@#include <linux/dma-debug.h> #include <linux/kmemcheck.h> #include <linux/kref.h> - -struct dma_iommu_mapping { -/* iommu specific data */ -struct iommu_domain *domain; - -unsigned long **bitmaps;/* array of bitmaps */ -unsigned int nr_bitmaps;/* nr of elements in array */ -unsigned int extensions; -size_t bitmap_size;/* size of a single bitmap */ -size_t bits;/* per bitmap */ -dma_addr_t base; - -spinlock_t lock; -struct kref kref; -}; +#include <linux/iommu-helper.h> struct dma_iommu_mapping *arm_iommu_create_mapping (struct bus_type *bus,dma_addr_t base,size_t size);
arch/arm/mm/dma-mapping.c +10 -10
@@ -1292,7 +1292,7 @@ err:static dma_addr_t __iommu_create_mapping (struct device *dev,struct page **pages,size_t size) { -struct dma_iommu_mapping *mapping = dev->archdata.mapping; +struct dma_iommu_mapping *mapping = dev->mapping;unsigned int count =PAGE_ALIGN (size) >>PAGE_SHIFT ;dma_addr_t dma_addr, iova;int i, ret =DMA_ERROR_CODE ;
@@ -1328,7 +1328,7 @@ fail:static int __iommu_remove_mapping (struct device *dev,dma_addr_t iova,size_t size) { -struct dma_iommu_mapping *mapping = dev->archdata.mapping; +struct dma_iommu_mapping *mapping = dev->mapping;/* * add optional in-page offset from iova to size and align
@@ -1541,7 +1541,7 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg, enum dma_data_direction dir, struct dma_attrs *attrs, bool is_coherent) { - struct dma_iommu_mapping *mapping = dev->archdata.mapping; + struct dma_iommu_mapping *mapping = dev->mapping;dma_addr_t iova, iova_base;int ret =0 ;unsigned int count;
@@ -1762,7 +1762,7 @@ static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *p unsigned long offset, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { - struct dma_iommu_mapping *mapping = dev->archdata.mapping; + struct dma_iommu_mapping *mapping = dev->mapping;dma_addr_t dma_addr;int ret, prot, len =PAGE_ALIGN (size + offset);
@@ -1815,7 +1815,7 @@ static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { - struct dma_iommu_mapping *mapping = dev->archdata.mapping; + struct dma_iommu_mapping *mapping = dev->mapping;dma_addr_t iova = handle &PAGE_MASK ;int offset = handle & ~PAGE_MASK ;int len =PAGE_ALIGN (size + offset);
@@ -1840,7 +1840,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { - struct dma_iommu_mapping *mapping = dev->archdata.mapping; + struct dma_iommu_mapping *mapping = dev->mapping;dma_addr_t iova = handle &PAGE_MASK ;struct page *page =phys_to_page (iommu_iova_to_phys (mapping->domain, iova));int offset = handle & ~PAGE_MASK ;
@@ -1859,7 +1859,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,static void arm_iommu_sync_single_for_cpu (struct device *dev,dma_addr_t handle,size_t size,enum dma_data_direction dir) { -struct dma_iommu_mapping *mapping = dev->archdata.mapping; +struct dma_iommu_mapping *mapping = dev->mapping;dma_addr_t iova = handle &PAGE_MASK ;struct page *page =phys_to_page (iommu_iova_to_phys (mapping->domain, iova));unsigned int offset = handle & ~PAGE_MASK ;
@@ -1873,7 +1873,7 @@ static void arm_iommu_sync_single_for_cpu(struct device *dev,static void arm_iommu_sync_single_for_device (struct device *dev,dma_addr_t handle,size_t size,enum dma_data_direction dir) { -struct dma_iommu_mapping *mapping = dev->archdata.mapping; +struct dma_iommu_mapping *mapping = dev->mapping;dma_addr_t iova = handle &PAGE_MASK ;struct page *page =phys_to_page (iommu_iova_to_phys (mapping->domain, iova));unsigned int offset = handle & ~PAGE_MASK ;
@@ -2045,7 +2045,7 @@ int arm_iommu_attach_device(struct device *dev,return err;kref_get (&mapping->kref); - dev->archdata.mapping = mapping; + dev->mapping = mapping;set_dma_ops (dev, &iommu_ops);pr_debug ("Attached IOMMU controller to %s device.\n" ,dev_name (dev));
@@ -2072,7 +2072,7 @@ void arm_iommu_detach_device(struct device *dev)iommu_detach_device (mapping->domain, dev);kref_put (&mapping->kref, release_iommu_mapping); - dev->archdata.mapping =NULL ; + dev->mapping =NULL ;set_dma_ops (dev,NULL );pr_debug ("Detached IOMMU controller from %s device.\n" ,dev_name (dev));
drivers/gpu/drm/exynos/exynos_drm_iommu.c +5 -5
@@ -46,7 +46,7 @@ int drm_create_iommu_mapping(struct drm_device *drm_dev) dev->dma_parms =devm_kzalloc (dev,sizeof (*dev->dma_parms),GFP_KERNEL );dma_set_max_seg_size (dev,0xffffffffu ); - dev->archdata.mapping = mapping; + dev->mapping = mapping;return 0 ; }
@@ -63,7 +63,7 @@ void drm_release_iommu_mapping(struct drm_device *drm_dev) {struct device *dev = drm_dev->dev; -arm_iommu_release_mapping (dev->archdata.mapping); +arm_iommu_release_mapping (dev->mapping); }/*
@@ -81,7 +81,7 @@ int drm_iommu_attach_device(struct drm_device *drm_dev,struct device *dev = drm_dev->dev;int ret; -if (!dev->archdata.mapping) { +if (!dev->mapping) {DRM_ERROR ("iommu_mapping is null.\n" );return -EFAULT ; }
@@ -91,7 +91,7 @@ int drm_iommu_attach_device(struct drm_device *drm_dev, GFP_KERNEL);dma_set_max_seg_size (subdrv_dev,0xffffffffu ); - ret =arm_iommu_attach_device (subdrv_dev, dev->archdata.mapping); + ret =arm_iommu_attach_device (subdrv_dev, dev->mapping);if (ret <0 ) {DRM_DEBUG_KMS ("failed iommu attach.\n" );return ret;
@@ -124,7 +124,7 @@ void drm_iommu_detach_device(struct drm_device *drm_dev, struct device *subdrv_dev) {struct device *dev = drm_dev->dev; -struct dma_iommu_mapping *mapping = dev->archdata.mapping; +struct dma_iommu_mapping *mapping = dev->mapping;if (!mapping || !mapping->domain)return ;
include/linux/device.h +4 -0
@@ -705,6 +705,10 @@ struct device {/* arch specific additions */ struct dev_archdata archdata; +#ifdef CONFIG_DMA_USE_IOMMU_HELPER_MAPPING +struct dma_iommu_mapping *mapping; +#endif +struct device_node *of_node;/* associated device tree node */ struct acpi_dev_node acpi_node;/* associated ACPI device node */
include/linux/iommu-helper.h +22 -0
@@ -3,6 +3,28 @@#include <linux/kernel.h> +#ifdef CONFIG_DMA_USE_IOMMU_HELPER_MAPPING +struct dma_iommu_mapping { +/* iommu specific data */ +struct iommu_domain *domain; + +unsigned long **bitmaps;/* array of bitmaps */ +unsigned int nr_bitmaps;/* nr of elements in array */ +unsigned int extensions; +size_t bitmap_size;/* size of a single bitmap */ +size_t bits;/* per bitmap */ +dma_addr_t base; + +spinlock_t lock; +struct kref kref; +}; + +#define to_dma_iommu_mapping (dev) ((dev)->mapping) +#else +#define to_dma_iommu_mapping (dev) NULL +#endif + +static inline unsigned long iommu_device_max_index (unsigned long size,unsigned long offset,u64 dma_mask)
Signature · 1 line
1.8.1.3
PATCH 2/4 arm: dma-mapping: Refractor attach/detach dev function calls
From: Ritesh Harjani <[email protected]>
Refractor following function calls to lib/iommu-helper.c
arm_iommu_attach/detach device function calls.
arm_iommu_init/release_mapping function calls.
--- arch/arm/mm/dma-mapping.c | 101 +++++-------------------------- include/linux/iommu-helper.h | 10 ++++ lib/iommu-helper.c | 140 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+), 86 deletions(-)
arch/arm/mm/dma-mapping.c +15 -86
@@ -1924,7 +1924,8 @@ struct dma_map_ops iommu_coherent_ops = {* @base: start address of the valid IO address space * @size: maximum size of the valid IO address space * -* Creates a mapping structure which holds information about used/unused +* Calls for lib/iommu-helper function which creates a mapping +* structure which holds information about used/unused * IO address ranges, which is required to perform memory allocation and * mapping with IOMMU aware functions. *
@@ -1934,71 +1935,10 @@ struct dma_map_ops iommu_coherent_ops = {struct dma_iommu_mapping *arm_iommu_create_mapping (struct bus_type *bus,dma_addr_t base,size_t size) { -unsigned int bits = size >>PAGE_SHIFT ; -unsigned int bitmap_size =BITS_TO_LONGS (bits) *sizeof (long ); -struct dma_iommu_mapping *mapping; -int extensions =1 ; -int err = -ENOMEM ; - -if (!bitmap_size) -return ERR_PTR (-EINVAL ); - -if (bitmap_size >PAGE_SIZE ) { - extensions = bitmap_size /PAGE_SIZE ; - bitmap_size =PAGE_SIZE ; - } - - mapping =kzalloc (sizeof (struct dma_iommu_mapping ),GFP_KERNEL ); -if (!mapping) - goto err; - - mapping->bitmap_size = bitmap_size; - mapping->bitmaps =kzalloc (extensions *sizeof (unsigned long *), -GFP_KERNEL ); -if (!mapping->bitmaps) - goto err2; - - mapping->bitmaps[0 ] =kzalloc (bitmap_size,GFP_KERNEL ); -if (!mapping->bitmaps[0 ]) - goto err3; - - mapping->nr_bitmaps =1 ; - mapping->extensions = extensions; - mapping->base = base; - mapping->bits =BITS_PER_BYTE * bitmap_size; - -spin_lock_init (&mapping->lock); - - mapping->domain =iommu_domain_alloc (bus); -if (!mapping->domain) - goto err4; - -kref_init (&mapping->kref); -return mapping; -err4: -kfree (mapping->bitmaps[0 ]); -err3: -kfree (mapping->bitmaps); -err2: -kfree (mapping); -err: -return ERR_PTR (err); +return __iommu_init_mapping (bus, base, size); }EXPORT_SYMBOL_GPL (arm_iommu_create_mapping); -static void release_iommu_mapping (struct kref *kref) -{ -int i; -struct dma_iommu_mapping *mapping = - container_of(kref, struct dma_iommu_mapping, kref); - -iommu_domain_free (mapping->domain); -for (i =0 ; i < mapping->nr_bitmaps; i++) -kfree (mapping->bitmaps[i]); -kfree (mapping->bitmaps); -kfree (mapping); -} -static int extend_iommu_mapping (struct dma_iommu_mapping *mapping) {int next_bitmap;
@@ -2019,8 +1959,7 @@ static int extend_iommu_mapping(struct dma_iommu_mapping *mapping)void arm_iommu_release_mapping (struct dma_iommu_mapping *mapping) { -if (mapping) -kref_put (&mapping->kref, release_iommu_mapping); +__iommu_release_mapping (mapping); }EXPORT_SYMBOL_GPL (arm_iommu_release_mapping);
@@ -2030,8 +1969,9 @@ EXPORT_SYMBOL_GPL(arm_iommu_release_mapping);* @mapping: io address space mapping structure (returned from * arm_iommu_create_mapping) * -* Attaches specified io address space mapping to the provided device, -* this replaces the dma operations (dma_map_ops pointer) with the +* Calls for lib/iommu-helper which attaches specified io +* address space mapping to the provided device, this +* replaces the dma operations (dma_map_ops pointer) with the * IOMMU aware version. More than one client might be attached to * the same io address space mapping. */
@@ -2040,13 +1980,12 @@ int arm_iommu_attach_device(struct device *dev, {int err; - err =iommu_attach_device (mapping->domain, dev); -if (err) -return err; + err =__iommu_attach_device (dev, mapping); -kref_get (&mapping->kref); - dev->mapping = mapping; -set_dma_ops (dev, &iommu_ops); +if (!err) +set_dma_ops (dev, &iommu_ops); +else +return err;pr_debug ("Attached IOMMU controller to %s device.\n" ,dev_name (dev));return 0 ;
@@ -2057,24 +1996,14 @@ EXPORT_SYMBOL_GPL(arm_iommu_attach_device);* arm_iommu_detach_device * @dev: valid struct device pointer * -* Detaches the provided device from a previously attached map. +* Calls for lib/iommu-helper which detaches the provided +* device from a previously attached map. * This voids the dma operations (dma_map_ops pointer) */ void arm_iommu_detach_device (struct device *dev) { -struct dma_iommu_mapping *mapping; - - mapping =to_dma_iommu_mapping (dev); -if (!mapping) { -dev_warn (dev,"Not attached\n" ); -return ; - } - -iommu_detach_device (mapping->domain, dev); -kref_put (&mapping->kref, release_iommu_mapping); - dev->mapping =NULL ; +__iommu_detach_device (dev);set_dma_ops (dev,NULL ); -pr_debug ("Detached IOMMU controller from %s device.\n" ,dev_name (dev)); }EXPORT_SYMBOL_GPL (arm_iommu_detach_device);
include/linux/iommu-helper.h +10 -0
@@ -19,6 +19,16 @@ struct dma_iommu_mapping { struct kref kref; }; +extern void __iommu_detach_device (struct device *dev); + +extern void __iommu_release_mapping (struct dma_iommu_mapping *mapping); + +extern int __iommu_attach_device (struct device *dev, +struct dma_iommu_mapping *mapping); + +extern struct dma_iommu_mapping * +__iommu_init_mapping (struct bus_type *bus,dma_addr_t base,size_t size); +#define to_dma_iommu_mapping (dev) ((dev)->mapping)#else #define to_dma_iommu_mapping (dev) NULL
lib/iommu-helper.c +140 -0
149 lines not on this page · raw message
Signature · 1 line
1.8.1.3
PATCH 3/4 arm: dma-mapping: Refractor iommu_alloc/free funcs
From: Ritesh Harjani <[email protected]>
iommu_alloc/free_buffer can be moved out tolib/iommu_helper.c as a part of refactoring
arm iommu dma-mapping code.
--- arch/arm/mm/dma-mapping.c | 95 +------------------------------------------- include/linux/iommu-helper.h | 8 ++++ lib/iommu-helper.c | 95 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 93 deletions(-)
arch/arm/mm/dma-mapping.c +2 -93
@@ -1161,98 +1161,6 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,spin_unlock_irqrestore (&mapping->lock, flags); } -static struct page **__iommu_alloc_buffer (struct device *dev,size_t size, -gfp_t gfp,struct dma_attrs *attrs) -{ -struct page **pages; -int count = size >>PAGE_SHIFT ; -int array_size = count *sizeof (struct page *); -int i =0 ; - -if (array_size <=PAGE_SIZE ) - pages =kzalloc (array_size, gfp); -else - pages =vzalloc (array_size); -if (!pages) -return NULL ; - -if (dma_get_attr (DMA_ATTR_FORCE_CONTIGUOUS , attrs)) - { -unsigned long order =get_order (size); -struct page *page; - - page =dma_alloc_from_contiguous (dev, count, order); -if (!page) - goto error; - -__dma_clear_buffer (page, size); - -for (i =0 ; i < count; i++) - pages[i] = page + i; - -return pages; - } - -/* -* IOMMU can map any pages, so himem can also be used here -*/ - gfp |= __GFP_NOWARN | __GFP_HIGHMEM; - -while (count) { -int j, order =__fls (count); - - pages[i] =alloc_pages (gfp, order); -while (!pages[i] && order) - pages[i] =alloc_pages (gfp, --order); -if (!pages[i]) - goto error; - -if (order) { -split_page (pages[i], order); - j =1 << order; -while (--j) - pages[i + j] = pages[i] + j; - } - -__dma_clear_buffer (pages[i],PAGE_SIZE << order); - i +=1 << order; - count -=1 << order; - } - -return pages; -error: -while (i--) -if (pages[i]) -__free_pages (pages[i],0 ); -if (array_size <=PAGE_SIZE ) -kfree (pages); -else -vfree (pages); -return NULL ; -} - -static int __iommu_free_buffer (struct device *dev,struct page **pages, -size_t size,struct dma_attrs *attrs) -{ -int count = size >>PAGE_SHIFT ; -int array_size = count *sizeof (struct page *); -int i; - -if (dma_get_attr (DMA_ATTR_FORCE_CONTIGUOUS , attrs)) { -dma_release_from_contiguous (dev, pages[0 ], count); - }else { -for (i =0 ; i < count; i++) -if (pages[i]) -__free_pages (pages[i],0 ); - } - -if (array_size <=PAGE_SIZE ) -kfree (pages); -else -vfree (pages); -return 0 ; -} -/* * Create a CPU mapping for a specified pages */
@@ -1417,7 +1325,8 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,*/ gfp &= ~(__GFP_COMP); - pages =__iommu_alloc_buffer (dev, size, gfp, attrs); + pages =__iommu_alloc_buffer (dev, size, gfp, attrs, + __dma_clear_buffer);if (!pages)return NULL ;
include/linux/iommu-helper.h +8 -0
@@ -2,6 +2,7 @@#define _LINUX_IOMMU_HELPER_H#include <linux/kernel.h> +#include <linux/dma-attrs.h> #ifdef CONFIG_DMA_USE_IOMMU_HELPER_MAPPING struct dma_iommu_mapping {
@@ -19,6 +20,13 @@ struct dma_iommu_mapping {struct kref kref; }; +extern struct page **__iommu_alloc_buffer (struct device *dev,size_t size, +gfp_t gfp,struct dma_attrs *attrs, +void (*arch_clear_buffer_cb)(struct page *,size_t )); + +extern int __iommu_free_buffer (struct device *dev,struct page **pages, +size_t size,struct dma_attrs *attrs); +extern void __iommu_detach_device (struct device *dev);extern void __iommu_release_mapping (struct dma_iommu_mapping *mapping);
lib/iommu-helper.c +95 -0
107 lines not on this page · raw message
Signature · 1 line
1.8.1.3
PATCH 4/4 arm:dma-iommu: Move out complete func defs
From: Ritesh Harjani <[email protected]>
Move out complete function definations fromarch/arm/dma-mapping to lib/iommu-helper
1. Moved out iova alloc/free routine and make them statically defined.
2. Moved out complete function definations calling for alloc/free_iova routing to lib/iommu-helper.c
3. Seprated out cache maintainance from iommu_map/unmap function routine, to be called from within arch/arm/dma-mapping.c
--- arch/arm/Kconfig | 42 ++--- arch/arm/mm/dma-mapping.c | 362 +++---------------------------------------- include/linux/iommu-helper.h | 28 +++- lib/iommu-helper.c | 329 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 399 insertions(+), 362 deletions(-)
arch/arm/Kconfig +21 -21
@@ -80,27 +80,6 @@ config ARM_DMA_USE_IOMMU select NEED_SG_DMA_LENGTH select DMA_USE_IOMMU_HELPER_MAPPING -if ARM_DMA_USE_IOMMU - -config ARM_DMA_IOMMU_ALIGNMENT - int "Maximum PAGE_SIZE order of alignment for DMA IOMMU buffers" - range 4 9 - default 8 - help - DMA mapping framework by default aligns all buffers to the smallest - PAGE_SIZE order which is greater than or equal to the requested buffer - size. This works well for buffers up to a few hundreds kilobytes, but - for larger buffers it just a waste of address space. Drivers which has - relatively small addressing window (like 64Mib) might run out of - virtual space with just a few allocations. - - With this parameter you can specify the maximum PAGE_SIZE order for - DMA IOMMU buffers. Larger buffers will be aligned only to this - specified order. The order is expressed as a power of two multiplied - by the PAGE_SIZE. - -endif - config HAVE_PWM bool
@@ -1949,6 +1928,27 @@ config IOMMU_HELPER config DMA_USE_IOMMU_HELPER_MAPPING def_bool n +if DMA_USE_IOMMU_HELPER_MAPPING + +config DMA_IOMMU_ALIGNMENT + int "Maximum PAGE_SIZE order of alignment for DMA IOMMU buffers" + range 4 9 + default 8 + help + DMA mapping framework by default aligns all buffers to the smallest + PAGE_SIZE order which is greater than or equal to the requested buffer + size. This works well for buffers up to a few hundreds kilobytes, but + for larger buffers it just a waste of address space. Drivers which has + relatively small addressing window (like 64Mib) might run out of + virtual space with just a few allocations. + + With this parameter you can specify the maximum PAGE_SIZE order for + DMA IOMMU buffers. Larger buffers will be aligned only to this + specified order. The order is expressed as a power of two multiplied + by the PAGE_SIZE. + +endif + config XEN_DOM0 def_bool y depends on XEN
arch/arm/mm/dma-mapping.c +24 -338
440 lines not on this page · raw message
include/linux/iommu-helper.h +26 -2
@@ -5,6 +5,12 @@#include <linux/dma-attrs.h> #ifdef CONFIG_DMA_USE_IOMMU_HELPER_MAPPING +#include <linux/mm_types.h> +#include <linux/dma-debug.h> +#include <linux/kmemcheck.h> +#include <linux/kref.h> +#include <linux/dma-mapping.h> + struct dma_iommu_mapping { /* iommu specific data */ struct iommu_domain *domain;
@@ -20,6 +26,25 @@ struct dma_iommu_mapping {struct kref kref; }; +extern dma_addr_t __iommu_create_mapping (struct device *dev,struct page **pages, +size_t size); + +extern int __iommu_remove_mapping (struct device *dev,dma_addr_t iova, +size_t size); + +extern dma_addr_t __iommu_map_page (struct device *dev,struct page *page, +unsigned long offset,size_t size,enum dma_data_direction dir); + +extern void __iommu_unmap_page (struct device *dev,dma_addr_t handle, +size_t size,enum dma_data_direction dir); + +extern int __iommu_map_sg (struct device *dev,struct scatterlist *sg,int nents, +enum dma_data_direction dir,struct dma_attrs *attrs); + +extern void __iommu_unmap_sg (struct device *dev,struct scatterlist *sg, +int nents,enum dma_data_direction dir, +struct dma_attrs *attrs); +extern struct page **__iommu_alloc_buffer (struct device *dev,size_t size,gfp_t gfp,struct dma_attrs *attrs,void (*arch_clear_buffer_cb)(struct page *,size_t ));
@@ -29,14 +54,13 @@ extern int __iommu_free_buffer(struct device *dev, struct page **pages,extern void __iommu_detach_device (struct device *dev); -extern void __iommu_release_mapping (struct dma_iommu_mapping *mapping); -extern int __iommu_attach_device (struct device *dev,struct dma_iommu_mapping *mapping);extern struct dma_iommu_mapping *__iommu_init_mapping (struct bus_type *bus,dma_addr_t base,size_t size); +extern void __iommu_release_mapping (struct dma_iommu_mapping *mapping);#define to_dma_iommu_mapping (dev) ((dev)->mapping)#else #define to_dma_iommu_mapping (dev) NULL
lib/iommu-helper.c +328 -1
353 lines not on this page · raw message
Signature · 1 line
1.8.1.3
cover arm:dma-mapping Refactoring iommu dma-mapping code
In reply to ritesh.harjani at gmail.comQuoted 2 lines · ritesh.harjani at gmail.com
From: Ritesh Harjani <[email protected]>
Hi All,
Hi Ritesh,
Thanks for the new patches. I have a few comments on the series as a whole.
Quoted 8 lines
This patch series is to refractor iommu related common code from
arch/arm/dma-mapping.ctolib/iommu-helper.cbased on the various discussions with the maintainers/experts [1].Currently the only user of the common
lib/iommu-helpercode will be ARM & ARM64 but later various architecture might try to use this iommu lib helper functions.
Quoted 5 lines
Major change of this refactoring starts with bringing out struct
dma_iommu_mapping*mapping variable fromarch/arm/include/asm/device.htoinclude/linux/device.hand by moving out complete structure defination ofdma_iommu_mappingtoinclue/linux/iommu-helper.h. Link [2] give more details on why this was done, also this change got approval from Will Daecon [2].
Well, I can't approve changes to include/linux/device.h, so that probably needs to be acked by Grant and/or Greg. Could you split that patch out into a separate change please, so that it can go in independently?
Also, I think you could merge patches 2 and 3, no?
Quoted 3 lines
There are 1/2 more function definitions which I can think of moving out, but those can be done once this patch series is approved as those are not very big changes.
This certainly looks good to start with, although I think you should consider renaming the functions in the helper library so that they aren't prefixed with double underscores. Maybe iommu_helper_* instead?
Finally, please drop the ChangeId entries from your commit messages (and you've consistently misspelled refactor as refractor).
Will