From: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
To: m.szyprowski@samsung.com
Cc: hch@lst.de, robin.murphy@arm.com, djbw@kernel.org,
akpm@linux-foundation.org, catalin.marinas@arm.com,
harry@kernel.org, ming.lei@redhat.com, leon@kernel.org,
iommu@lists.linux.dev, linux-kernel@vger.kernel.org,
Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Subject: [PATCH] dma-debug: skip cacheline overlap tracking on cache-coherent architectures
Date: Mon, 18 May 2026 16:32:51 +0500 [thread overview]
Message-ID: <20260518113251.64844-1-mikhail.v.gavrilov@gmail.com> (raw)
The dma-debug cacheline overlap tracking emits two distinct warnings
when multiple DMA mappings share a cacheline:
1. add_dma_entry() calls err_printk("cacheline tracking EEXIST,
overlapping mappings aren't supported\n") on every -EEXIST from
active_cacheline_insert().
2. active_cacheline_inc_overlap() calls WARN_ONCE("exceeded %d
overlapping mappings of cacheline %pa\n", ...) when the 3-bit
per-cacheline overlap counter in the dma_active_cacheline radix
tree would saturate past ACTIVE_CACHELINE_MAX_OVERLAP (= 7).
Commit 3d48c9fd78dd ("dma-debug: suppress cacheline overlap warning
when arch has no DMA alignment requirement") suppressed (1) on
architectures where hardware bus snooping makes cacheline-overlapping
DMA mappings safe. The same reasoning applies to (2): the tracking is
pure overhead on those architectures, and (2) still fires under real
workloads, e.g. heavy NVMe block I/O on x86_64:
DMA-API: exceeded 7 overlapping mappings of cacheline 0x...
WARNING: kernel/dma/debug.c:465 at add_dma_entry+0x394/0x410
Call Trace:
add_dma_entry+...
debug_dma_map_phys+...
dma_map_phys+...
blk_dma_map_iter_start+...
nvme_map_data+...
The block layer routinely produces nine or more concurrent in-flight
mappings whose buffers share a single cacheline. On hardware-coherent
systems this is harmless, but it saturates the tag-based overlap
counter and produces a splat indistinguishable from a real driver bug.
Extend the gate to skip the cacheline overlap tracking entirely on
cache-coherent architectures, mirroring the DMA_TO_DEVICE early-return
that already exists for the same "tracking is unnecessary" reason. The
helper dma_debug_cacheline_tracking_needed() captures the condition and
is symmetric to the existing add_dma_entry() check.
The same DMA_BOUNCE_UNALIGNED_KMALLOC + SWIOTLB suppression that
commit 03521c892bb8 ("dma-debug: don't report false positives with
DMA_BOUNCE_UNALIGNED_KMALLOC") added to (1) applies here for the same
reason: unaligned kmalloc buffers are bounced through aligned swiotlb
buffers, so the original cacheline overlap never reaches DMA. The
helper preserves both suppression conditions.
Reproducer (out-of-tree module): map a single 8-byte buffer with
dma_map_single(..., DMA_BIDIRECTIONAL) nine times in a row. The 9th
call deterministically fires the WARN_ONCE on an unfixed kernel; with
this patch applied no warning is emitted regardless of the number of
overlapping mappings.
Without this patch (n_maps=9):
DMA-API: exceeded 7 overlapping mappings of cacheline 0x00000000071d7dbe
WARNING: kernel/dma/debug.c:465 at add_dma_entry+0x39e/0x410
[...]
With this patch (n_maps=1000):
dma_debug_overlap_repro: 1000/1000 mappings active
[no warning]
Link: https://lore.kernel.org/all/ZwxzdWmYcBK27mUs@fedora/
Fixes: 3b7a6418c749 ("dma debug: account for cachelines and read-only mappings in overlap tracking")
Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
---
kernel/dma/debug.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c
index 1a725edbbbf6..2d1609b9d362 100644
--- a/kernel/dma/debug.c
+++ b/kernel/dma/debug.c
@@ -474,6 +474,35 @@ static int active_cacheline_dec_overlap(phys_addr_t cln)
return active_cacheline_set_overlap(cln, --overlap);
}
+/*
+ * Whether cacheline-overlap tracking is meaningful for @dev.
+ *
+ * Mirrors the suppression conditions add_dma_entry() already applies to
+ * the sibling "cacheline tracking EEXIST" err_printk:
+ *
+ * - On architectures with hardware DMA cache coherence
+ * (dma_get_cache_alignment() < L1_CACHE_BYTES, e.g. x86_64) bus
+ * snooping makes overlapping cacheline mappings safe.
+ *
+ * - With CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC and an active SWIOTLB,
+ * unaligned kmalloc buffers are bounced through aligned swiotlb
+ * buffers, so the original cacheline overlap never reaches DMA.
+ * See commit 03521c892bb8 ("dma-debug: don't report false positives
+ * with DMA_BOUNCE_UNALIGNED_KMALLOC").
+ *
+ * In both cases tracking is pure overhead and produces false-positive
+ * WARN_ONCEs.
+ */
+static bool dma_debug_cacheline_tracking_needed(struct device *dev)
+{
+ if (dma_get_cache_alignment() < L1_CACHE_BYTES)
+ return false;
+ if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) &&
+ is_swiotlb_active(dev))
+ return false;
+ return true;
+}
+
static int active_cacheline_insert(struct dma_debug_entry *entry,
bool *overlap_cache_clean)
{
@@ -490,6 +519,9 @@ static int active_cacheline_insert(struct dma_debug_entry *entry,
if (entry->direction == DMA_TO_DEVICE)
return 0;
+ if (!dma_debug_cacheline_tracking_needed(entry->dev))
+ return 0;
+
spin_lock_irqsave(&radix_lock, flags);
rc = radix_tree_insert(&dma_active_cacheline, cln, entry);
if (rc == -EEXIST) {
@@ -516,6 +548,9 @@ static void active_cacheline_remove(struct dma_debug_entry *entry)
if (entry->direction == DMA_TO_DEVICE)
return;
+ if (!dma_debug_cacheline_tracking_needed(entry->dev))
+ return;
+
spin_lock_irqsave(&radix_lock, flags);
/* since we are counting overlaps the final put of the
* cacheline will occur when the overlap count is 0.
--
2.54.0
next reply other threads:[~2026-05-18 11:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-18 11:32 Mikhail Gavrilov [this message]
2026-05-18 12:10 ` Leon Romanovsky
2026-05-18 12:23 ` Mikhail Gavrilov
2026-05-18 12:53 ` Leon Romanovsky
2026-05-18 13:29 ` Mikhail Gavrilov
2026-05-19 7:17 ` Christoph Hellwig
2026-05-19 8:03 ` Mikhail Gavrilov
2026-05-19 9:28 ` Christoph Hellwig
2026-05-19 9:57 ` Mikhail Gavrilov
2026-05-19 11:49 ` Christoph Hellwig
2026-05-19 9:06 ` David Laight
2026-05-19 9:18 ` Mikhail Gavrilov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260518113251.64844-1-mikhail.v.gavrilov@gmail.com \
--to=mikhail.v.gavrilov@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=catalin.marinas@arm.com \
--cc=djbw@kernel.org \
--cc=harry@kernel.org \
--cc=hch@lst.de \
--cc=iommu@lists.linux.dev \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=m.szyprowski@samsung.com \
--cc=ming.lei@redhat.com \
--cc=robin.murphy@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®