Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dma-mapping: Introduce DMA require coherency attribute

The mapping buffers which carry this attribute require DMA coherent system.
This means that they can't take SWIOTLB path, can perform CPU cache overlap
and doesn't perform cache flushing.

Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20260316-dma-debug-overlap-v3-4-1dde90a7f08b@nvidia.com

authored by

Leon Romanovsky and committed by
Marek Szyprowski
e6a58fa2 9bb0a4d6

+33 -2
+16
Documentation/core-api/dma-attributes.rst
··· 163 163 164 164 All mappings that share a cache line must set this attribute to suppress DMA 165 165 debug warnings about overlapping mappings. 166 + 167 + DMA_ATTR_REQUIRE_COHERENT 168 + ------------------------- 169 + 170 + DMA mapping requests with the DMA_ATTR_REQUIRE_COHERENT fail on any 171 + system where SWIOTLB or cache management is required. This should only 172 + be used to support uAPI designs that require continuous HW DMA 173 + coherence with userspace processes, for example RDMA and DRM. At a 174 + minimum the memory being mapped must be userspace memory from 175 + pin_user_pages() or similar. 176 + 177 + Drivers should consider using dma_mmap_pages() instead of this 178 + interface when building their uAPIs, when possible. 179 + 180 + It must never be used in an in-kernel driver that only works with 181 + kernel memory.
+7
include/linux/dma-mapping.h
··· 87 87 #define DMA_ATTR_DEBUGGING_IGNORE_CACHELINES (1UL << 11) 88 88 89 89 /* 90 + * DMA_ATTR_REQUIRE_COHERENT: Indicates that DMA coherency is required. 91 + * All mappings that carry this attribute can't work with SWIOTLB and cache 92 + * flushing. 93 + */ 94 + #define DMA_ATTR_REQUIRE_COHERENT (1UL << 12) 95 + 96 + /* 90 97 * A dma_addr_t can hold any valid DMA or bus address for the platform. It can 91 98 * be given to a device to use as a DMA source or target. It is specific to a 92 99 * given device and there may be a translation between the CPU physical address
+2 -1
include/trace/events/dma.h
··· 33 33 { DMA_ATTR_NO_WARN, "NO_WARN" }, \ 34 34 { DMA_ATTR_PRIVILEGED, "PRIVILEGED" }, \ 35 35 { DMA_ATTR_MMIO, "MMIO" }, \ 36 - { DMA_ATTR_DEBUGGING_IGNORE_CACHELINES, "CACHELINES_OVERLAP" }) 36 + { DMA_ATTR_DEBUGGING_IGNORE_CACHELINES, "CACHELINES_OVERLAP" }, \ 37 + { DMA_ATTR_REQUIRE_COHERENT, "REQUIRE_COHERENT" }) 37 38 38 39 DECLARE_EVENT_CLASS(dma_map, 39 40 TP_PROTO(struct device *dev, phys_addr_t phys_addr, dma_addr_t dma_addr,
+2 -1
kernel/dma/debug.c
··· 601 601 unsigned long flags; 602 602 int rc; 603 603 604 - entry->is_cache_clean = attrs & DMA_ATTR_DEBUGGING_IGNORE_CACHELINES; 604 + entry->is_cache_clean = attrs & (DMA_ATTR_DEBUGGING_IGNORE_CACHELINES | 605 + DMA_ATTR_REQUIRE_COHERENT); 605 606 606 607 bucket = get_hash_bucket(entry, &flags); 607 608 hash_bucket_add(bucket, entry);
+6
kernel/dma/mapping.c
··· 164 164 if (WARN_ON_ONCE(!dev->dma_mask)) 165 165 return DMA_MAPPING_ERROR; 166 166 167 + if (!dev_is_dma_coherent(dev) && (attrs & DMA_ATTR_REQUIRE_COHERENT)) 168 + return DMA_MAPPING_ERROR; 169 + 167 170 if (dma_map_direct(dev, ops) || 168 171 (!is_mmio && arch_dma_map_phys_direct(dev, phys + size))) 169 172 addr = dma_direct_map_phys(dev, phys, size, dir, attrs); ··· 237 234 int ents; 238 235 239 236 BUG_ON(!valid_dma_direction(dir)); 237 + 238 + if (!dev_is_dma_coherent(dev) && (attrs & DMA_ATTR_REQUIRE_COHERENT)) 239 + return -EOPNOTSUPP; 240 240 241 241 if (WARN_ON_ONCE(!dev->dma_mask)) 242 242 return 0;