Skip to content

Commit 61868dc

Browse files
committed
dma-mapping: add DMA_ATTR_CPU_CACHE_CLEAN
When multiple small DMA_FROM_DEVICE or DMA_BIDIRECTIONAL buffers share a cacheline, and DMA_API_DEBUG is enabled, we get this warning: cacheline tracking EEXIST, overlapping mappings aren't supported. This is because when one of the mappings is removed, while another one is active, CPU might write into the buffer. Add an attribute for the driver to promise not to do this, making the overlapping safe, and suppressing the warning. Message-ID: <2d5d091f9d84b68ea96abd545b365dd1d00bbf48.1767601130.git.mst@redhat.com> Reviewed-by: Petr Tesarik <ptesarik@suse.com> Acked-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
1 parent 1e8b5d8 commit 61868dc

2 files changed

Lines changed: 9 additions & 1 deletion

File tree

include/linux/dma-mapping.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@
7979
*/
8080
#define DMA_ATTR_MMIO (1UL << 10)
8181

82+
/*
83+
* DMA_ATTR_CPU_CACHE_CLEAN: Indicates the CPU will not dirty any cacheline
84+
* overlapping this buffer while it is mapped for DMA. All mappings sharing
85+
* a cacheline must have this attribute for this to be considered safe.
86+
*/
87+
#define DMA_ATTR_CPU_CACHE_CLEAN (1UL << 11)
88+
8289
/*
8390
* A dma_addr_t can hold any valid DMA or bus address for the platform. It can
8491
* be given to a device to use as a DMA source or target. It is specific to a

kernel/dma/debug.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,8 @@ static void add_dma_entry(struct dma_debug_entry *entry, unsigned long attrs)
595595
if (rc == -ENOMEM) {
596596
pr_err_once("cacheline tracking ENOMEM, dma-debug disabled\n");
597597
global_disable = true;
598-
} else if (rc == -EEXIST && !(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
598+
} else if (rc == -EEXIST &&
599+
!(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_CPU_CACHE_CLEAN)) &&
599600
!(IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) &&
600601
is_swiotlb_active(entry->dev))) {
601602
err_printk(entry->dev, entry,

0 commit comments

Comments
 (0)