Skip to content

Commit

Permalink
mm: wire up GFP flag passing in dma_alloc_from_contiguous
Browse files Browse the repository at this point in the history
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.

Link: http://lkml.kernel.org/r/20170127172328.18574-3-l.stach@pengutronix.de
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: Radim Krcmar <rkrcmar@redhat.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Chris Zankel <chris@zankel.net>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Alexander Graf <agraf@suse.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Lucas Stach authored and Linus Torvalds committed Feb 25, 2017
1 parent e2f466e commit 712c604
Show file tree
Hide file tree
Showing 9 changed files with 24 additions and 19 deletions.
16 changes: 9 additions & 7 deletions arch/arm/mm/dma-mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1312,7 +1314,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;

Expand Down
4 changes: 2 additions & 2 deletions arch/arm64/mm/dma-mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -390,7 +390,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);

Expand Down
4 changes: 2 additions & 2 deletions arch/mips/mm/dma-default.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
3 changes: 2 additions & 1 deletion arch/x86/kernel/pci-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion arch/xtensa/kernel/pci-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
5 changes: 3 additions & 2 deletions drivers/base/dma-contiguous.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,19 +181,20 @@ 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
* global one. Requires architecture specific dev_get_cma_area() helper
* 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);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion drivers/iommu/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2672,7 +2672,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;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/iommu/intel-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -3829,7 +3829,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);
Expand Down
4 changes: 2 additions & 2 deletions include/linux/dma-contiguous.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 712c604

Please sign in to comment.