diff options
Diffstat (limited to 'arch/x86/kernel/pci-dma.c')
| -rw-r--r-- | arch/x86/kernel/pci-dma.c | 13 | 
1 files changed, 10 insertions, 3 deletions
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 872079a67e4..a25e202bb31 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -97,11 +97,18 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,  	dma_mask = dma_alloc_coherent_mask(dev, flag); -	flag |= __GFP_ZERO; +	flag &= ~__GFP_ZERO;  again:  	page = NULL; -	if (!(flag & GFP_ATOMIC)) +	/* CMA can be used only in the context which permits sleeping */ +	if (flag & __GFP_WAIT) {  		page = dma_alloc_from_contiguous(dev, count, get_order(size)); +		if (page && page_to_phys(page) + size > dma_mask) { +			dma_release_from_contiguous(dev, page, count); +			page = NULL; +		} +	} +	/* fallback */  	if (!page)  		page = alloc_pages_node(dev_to_node(dev), flag, get_order(size));  	if (!page) @@ -118,7 +125,7 @@ again:  		return NULL;  	} - +	memset(page_address(page), 0, size);  	*dma_addr = addr;  	return page_address(page);  }  | 
