Commit c61e9637 authored by Christoph Hellwig's avatar Christoph Hellwig

dma-direct: add support for allocation from ZONE_DMA and ZONE_DMA32

This allows to dip into zones for lower memory if they are available.
If one of the zones is not available the corresponding GFP_* flag
will evaluate to 0 so they won't change anything.  We provide an
arch tunable for those architectures that do not use GFP_DMA for
the lowest 24-bits, given that there are a few.

Roughly based on the x86 code.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 21f237e4
...@@ -12,6 +12,14 @@ ...@@ -12,6 +12,14 @@
#define DIRECT_MAPPING_ERROR 0 #define DIRECT_MAPPING_ERROR 0
/*
* Most architectures use ZONE_DMA for the first 16 Megabytes, but
* some use it for entirely different regions:
*/
#ifndef ARCH_ZONE_DMA_BITS
#define ARCH_ZONE_DMA_BITS 24
#endif
static bool static bool
check_addr(struct device *dev, dma_addr_t dma_addr, size_t size, check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
const char *caller) const char *caller)
...@@ -34,6 +42,12 @@ static void *dma_direct_alloc(struct device *dev, size_t size, ...@@ -34,6 +42,12 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
int page_order = get_order(size); int page_order = get_order(size);
struct page *page = NULL; struct page *page = NULL;
/* GFP_DMA32 and GFP_DMA are no ops without the corresponding zones: */
if (dev->coherent_dma_mask <= DMA_BIT_MASK(ARCH_ZONE_DMA_BITS))
gfp |= GFP_DMA;
if (dev->coherent_dma_mask <= DMA_BIT_MASK(32) && !(gfp & GFP_DMA))
gfp |= GFP_DMA32;
/* CMA can be used only in the context which permits sleeping */ /* CMA can be used only in the context which permits sleeping */
if (gfpflags_allow_blocking(gfp)) if (gfpflags_allow_blocking(gfp))
page = dma_alloc_from_contiguous(dev, count, page_order, gfp); page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment