summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2019-08-20 11:45:49 +0900
committerChristoph Hellwig <hch@lst.de>2019-08-21 07:14:10 +0900
commit90ae409f9eb3bcaf38688f9ec22375816053a08e (patch)
tree9ab3713cac2e657fc87fa8108a9dfa2b67f4d439 /drivers
parent936376f88ff1845b384b3a82b9cd167e53039229 (diff)
downloadlinux-90ae409f9eb3bcaf38688f9ec22375816053a08e.tar.bz2
dma-direct: fix zone selection after an unaddressable CMA allocation
The new dma_alloc_contiguous hides if we allocate CMA or regular pages, and thus fails to retry a ZONE_NORMAL allocation if the CMA allocation succeeds but isn't addressable. That means we either fail outright or dip into a small zone that might not succeed either. Thanks to Hillf Danton for debugging this issue. Fixes: b1d2dc009dec ("dma-contiguous: add dma_{alloc,free}_contiguous() helpers") Reported-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de> Signed-off-by: Christoph Hellwig <hch@lst.de> Tested-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/dma-iommu.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index d991d40f797f..f68a62c3c32b 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -965,11 +965,14 @@ static void *iommu_dma_alloc_pages(struct device *dev, size_t size,
{
bool coherent = dev_is_dma_coherent(dev);
size_t alloc_size = PAGE_ALIGN(size);
+ int node = dev_to_node(dev);
struct page *page = NULL;
void *cpu_addr;
page = dma_alloc_contiguous(dev, alloc_size, gfp);
if (!page)
+ page = alloc_pages_node(node, gfp, get_order(alloc_size));
+ if (!page)
return NULL;
if (IS_ENABLED(CONFIG_DMA_REMAP) && (!coherent || PageHighMem(page))) {