OSDN Git Service

arm64: dma: Drop cache invalidation from arch_dma_prep_coherent()
authorWill Deacon <will@kernel.org>
Tue, 23 Aug 2022 12:21:11 +0000 (13:21 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Thu, 22 Sep 2022 14:09:31 +0000 (15:09 +0100)
arch_dma_prep_coherent() is called when preparing a non-cacheable region
for a consistent DMA buffer allocation. Since the buffer pages may
previously have been written via a cacheable mapping and consequently
allocated as dirty cachelines, the purpose of this function is to remove
these dirty lines from the cache, writing them back so that the
non-coherent device is able to see them.

On arm64, this operation can be achieved with a clean to the point of
coherency; a subsequent invalidation is not required and serves little
purpose in the presence of a cacheable alias (e.g. the linear map),
since clean lines can be speculatively fetched back into the cache after
the invalidation operation has completed.

Relax the cache maintenance in arch_dma_prep_coherent() so that only a
clean, and not a clean-and-invalidate operation is performed.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20220823122111.17439-1-will@kernel.org
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/mm/dma-mapping.c

index 599cf81..83a512a 100644 (file)
@@ -36,7 +36,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 {
        unsigned long start = (unsigned long)page_address(page);
 
-       dcache_clean_inval_poc(start, start + size);
+       dcache_clean_poc(start, start + size);
 }
 
 #ifdef CONFIG_IOMMU_DMA