[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190430105214.24628-16-hch@lst.de>
Date: Tue, 30 Apr 2019 06:52:04 -0400
From: Christoph Hellwig <hch@....de>
To: Robin Murphy <robin.murphy@....com>
Cc: Joerg Roedel <joro@...tes.org>,
Catalin Marinas <catalin.marinas@....com>,
Will Deacon <will.deacon@....com>,
Tom Lendacky <thomas.lendacky@....com>,
iommu@...ts.linux-foundation.org,
linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org
Subject: [PATCH 15/25] iommu/dma: Don't remap CMA unnecessarily
From: Robin Murphy <robin.murphy@....com>
Always remapping CMA allocations was largely a bodge to keep the freeing
logic manageable when it was split between here and an arch wrapper. Now
that it's all together and streamlined, we can relax that limitation.
Signed-off-by: Robin Murphy <robin.murphy@....com>
Signed-off-by: Christoph Hellwig <hch@....de>
---
drivers/iommu/dma-iommu.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 26f2d059873b..ccdd655bc03a 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -954,7 +954,6 @@ static void *iommu_dma_alloc(struct device *dev, size_t size,
{
bool coherent = dev_is_dma_coherent(dev);
int ioprot = dma_info_to_prot(DMA_BIDIRECTIONAL, coherent, attrs);
- pgprot_t prot = arch_dma_mmap_pgprot(dev, PAGE_KERNEL, attrs);
size_t iosize = size;
struct page *page;
void *addr;
@@ -1002,13 +1001,19 @@ static void *iommu_dma_alloc(struct device *dev, size_t size,
if (*handle == DMA_MAPPING_ERROR)
goto out_free_pages;
- addr = dma_common_contiguous_remap(page, size, VM_USERMAP, prot,
- __builtin_return_address(0));
- if (!addr)
- goto out_unmap;
+ if (!coherent || PageHighMem(page)) {
+ pgprot_t prot = arch_dma_mmap_pgprot(dev, PAGE_KERNEL, attrs);
- if (!coherent)
- arch_dma_prep_coherent(page, iosize);
+ addr = dma_common_contiguous_remap(page, size, VM_USERMAP, prot,
+ __builtin_return_address(0));
+ if (!addr)
+ goto out_unmap;
+
+ if (!coherent)
+ arch_dma_prep_coherent(page, iosize);
+ } else {
+ addr = page_address(page);
+ }
memset(addr, 0, size);
return addr;
out_unmap:
--
2.20.1
Powered by blists - more mailing lists