[PATCH 3/3] mm: wire up GFP flag passing in dma_alloc_from_contiguous

Michal Hocko mhocko at kernel.org
Fri Jan 27 08:20:54 PST 2017


On Thu 19-01-17 18:07:07, Lucas Stach wrote:
> The callers of the DMA alloc functions already provide the proper
> context GFP flags. Make sure to pass them through to the CMA
> allocator, to make the CMA compaction context aware.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

Looks good to me
Acked-by: Michal Hocko <mhocko at suse.com>

> ---
>  arch/arm/mm/dma-mapping.c      | 16 +++++++++-------
>  arch/arm64/mm/dma-mapping.c    |  4 ++--
>  arch/mips/mm/dma-default.c     |  4 ++--
>  arch/x86/kernel/pci-dma.c      |  3 ++-
>  arch/xtensa/kernel/pci-dma.c   |  3 ++-
>  drivers/base/dma-contiguous.c  |  5 +++--
>  drivers/iommu/amd_iommu.c      |  2 +-
>  drivers/iommu/intel-iommu.c    |  2 +-
>  include/linux/dma-contiguous.h |  4 ++--
>  9 files changed, 24 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index ab7710002ba6..4d6ec7d821c8 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -349,7 +349,7 @@ static void __dma_free_buffer(struct page *page, size_t size)
>  static void *__alloc_from_contiguous(struct device *dev, size_t size,
>  				     pgprot_t prot, struct page **ret_page,
>  				     const void *caller, bool want_vaddr,
> -				     int coherent_flag);
> +				     int coherent_flag, gfp_t gfp);
>  
>  static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
>  				 pgprot_t prot, struct page **ret_page,
> @@ -420,7 +420,8 @@ static int __init atomic_pool_init(void)
>  	 */
>  	if (dev_get_cma_area(NULL))
>  		ptr = __alloc_from_contiguous(NULL, atomic_pool_size, prot,
> -				      &page, atomic_pool_init, true, NORMAL);
> +				      &page, atomic_pool_init, true, NORMAL,
> +				      GFP_KERNEL);
>  	else
>  		ptr = __alloc_remap_buffer(NULL, atomic_pool_size, gfp, prot,
>  					   &page, atomic_pool_init, true);
> @@ -594,14 +595,14 @@ static int __free_from_pool(void *start, size_t size)
>  static void *__alloc_from_contiguous(struct device *dev, size_t size,
>  				     pgprot_t prot, struct page **ret_page,
>  				     const void *caller, bool want_vaddr,
> -				     int coherent_flag)
> +				     int coherent_flag, gfp_t gfp)
>  {
>  	unsigned long order = get_order(size);
>  	size_t count = size >> PAGE_SHIFT;
>  	struct page *page;
>  	void *ptr = NULL;
>  
> -	page = dma_alloc_from_contiguous(dev, count, order);
> +	page = dma_alloc_from_contiguous(dev, count, order, gfp);
>  	if (!page)
>  		return NULL;
>  
> @@ -655,7 +656,7 @@ static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
>  #define __get_dma_pgprot(attrs, prot)				__pgprot(0)
>  #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv)	NULL
>  #define __alloc_from_pool(size, ret_page)			NULL
> -#define __alloc_from_contiguous(dev, size, prot, ret, c, wv, coherent_flag)	NULL
> +#define __alloc_from_contiguous(dev, size, prot, ret, c, wv, coherent_flag, gfp)	NULL
>  #define __free_from_pool(cpu_addr, size)			do { } while (0)
>  #define __free_from_contiguous(dev, page, cpu_addr, size, wv)	do { } while (0)
>  #define __dma_free_remap(cpu_addr, size)			do { } while (0)
> @@ -697,7 +698,8 @@ static void *cma_allocator_alloc(struct arm_dma_alloc_args *args,
>  {
>  	return __alloc_from_contiguous(args->dev, args->size, args->prot,
>  				       ret_page, args->caller,
> -				       args->want_vaddr, args->coherent_flag);
> +				       args->want_vaddr, args->coherent_flag,
> +				       args->gfp);
>  }
>  
>  static void cma_allocator_free(struct arm_dma_free_args *args)
> @@ -1293,7 +1295,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
>  		unsigned long order = get_order(size);
>  		struct page *page;
>  
> -		page = dma_alloc_from_contiguous(dev, count, order);
> +		page = dma_alloc_from_contiguous(dev, count, order, gfp);
>  		if (!page)
>  			goto error;
>  
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index e04082700bb1..b998f56e6a53 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -107,7 +107,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
>  		void *addr;
>  
>  		page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
> -							get_order(size));
> +						 get_order(size), flags);
>  		if (!page)
>  			return NULL;
>  
> @@ -379,7 +379,7 @@ static int __init atomic_pool_init(void)
>  
>  	if (dev_get_cma_area(NULL))
>  		page = dma_alloc_from_contiguous(NULL, nr_pages,
> -							pool_size_order);
> +						 pool_size_order, GFP_KERNEL);
>  	else
>  		page = alloc_pages(GFP_DMA, pool_size_order);
>  
> diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
> index a39c36af97ad..1895a692efd4 100644
> --- a/arch/mips/mm/dma-default.c
> +++ b/arch/mips/mm/dma-default.c
> @@ -148,8 +148,8 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
>  	gfp = massage_gfp_flags(dev, gfp);
>  
>  	if (IS_ENABLED(CONFIG_DMA_CMA) && gfpflags_allow_blocking(gfp))
> -		page = dma_alloc_from_contiguous(dev,
> -					count, get_order(size));
> +		page = dma_alloc_from_contiguous(dev, count, get_order(size),
> +						 gfp);
>  	if (!page)
>  		page = alloc_pages(gfp, get_order(size));
>  
> diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
> index d30c37750765..d5c223c9cf11 100644
> --- a/arch/x86/kernel/pci-dma.c
> +++ b/arch/x86/kernel/pci-dma.c
> @@ -91,7 +91,8 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
>  	page = NULL;
>  	/* CMA can be used only in the context which permits sleeping */
>  	if (gfpflags_allow_blocking(flag)) {
> -		page = dma_alloc_from_contiguous(dev, count, get_order(size));
> +		page = dma_alloc_from_contiguous(dev, count, get_order(size),
> +						 flag);
>  		if (page && page_to_phys(page) + size > dma_mask) {
>  			dma_release_from_contiguous(dev, page, count);
>  			page = NULL;
> diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
> index 70e362e6038e..34c1f9fa6acc 100644
> --- a/arch/xtensa/kernel/pci-dma.c
> +++ b/arch/xtensa/kernel/pci-dma.c
> @@ -158,7 +158,8 @@ static void *xtensa_dma_alloc(struct device *dev, size_t size,
>  		flag |= GFP_DMA;
>  
>  	if (gfpflags_allow_blocking(flag))
> -		page = dma_alloc_from_contiguous(dev, count, get_order(size));
> +		page = dma_alloc_from_contiguous(dev, count, get_order(size),
> +						 flag);
>  
>  	if (!page)
>  		page = alloc_pages(flag, get_order(size));
> diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
> index d1a9cbabc627..b55804cac4c4 100644
> --- a/drivers/base/dma-contiguous.c
> +++ b/drivers/base/dma-contiguous.c
> @@ -181,6 +181,7 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
>   * @dev:   Pointer to device for which the allocation is performed.
>   * @count: Requested number of pages.
>   * @align: Requested alignment of pages (in PAGE_SIZE order).
> + * @gfp_mask: GFP flags to use for this allocation.
>   *
>   * This function allocates memory buffer for specified device. It uses
>   * device specific contiguous memory area if available or the default
> @@ -188,12 +189,12 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
>   * function.
>   */
>  struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
> -				       unsigned int align)
> +				       unsigned int align, gfp_t gfp_mask)
>  {
>  	if (align > CONFIG_CMA_ALIGNMENT)
>  		align = CONFIG_CMA_ALIGNMENT;
>  
> -	return cma_alloc(dev_get_cma_area(dev), count, align, GFP_KERNEL);
> +	return cma_alloc(dev_get_cma_area(dev), count, align, gfp_mask);
>  }
>  
>  /**
> diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
> index 3ef0f42984f2..bd2e335cdf39 100644
> --- a/drivers/iommu/amd_iommu.c
> +++ b/drivers/iommu/amd_iommu.c
> @@ -2668,7 +2668,7 @@ static void *alloc_coherent(struct device *dev, size_t size,
>  			return NULL;
>  
>  		page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
> -						 get_order(size));
> +						 get_order(size), flag);
>  		if (!page)
>  			return NULL;
>  	}
> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> index 8a185250ae5a..3f804eb4299a 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -3827,7 +3827,7 @@ static void *intel_alloc_coherent(struct device *dev, size_t size,
>  	if (gfpflags_allow_blocking(flags)) {
>  		unsigned int count = size >> PAGE_SHIFT;
>  
> -		page = dma_alloc_from_contiguous(dev, count, order);
> +		page = dma_alloc_from_contiguous(dev, count, order, flags);
>  		if (page && iommu_no_mapping(dev) &&
>  		    page_to_phys(page) + size > dev->coherent_dma_mask) {
>  			dma_release_from_contiguous(dev, page, count);
> diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
> index fec734df1524..b67bf6ac907d 100644
> --- a/include/linux/dma-contiguous.h
> +++ b/include/linux/dma-contiguous.h
> @@ -112,7 +112,7 @@ static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size,
>  }
>  
>  struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
> -				       unsigned int order);
> +				       unsigned int order, gfp_t gfp_mask);
>  bool dma_release_from_contiguous(struct device *dev, struct page *pages,
>  				 int count);
>  
> @@ -145,7 +145,7 @@ int dma_declare_contiguous(struct device *dev, phys_addr_t size,
>  
>  static inline
>  struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
> -				       unsigned int order)
> +				       unsigned int order, gfp_t gfp_mask)
>  {
>  	return NULL;
>  }
> -- 
> 2.11.0
> 

-- 
Michal Hocko
SUSE Labs



More information about the linux-arm-kernel mailing list