public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] dma: Trace dma_map/unmap_page
@ 2024-08-12 20:43 Sean Anderson
  2024-08-22  4:20 ` Christoph Hellwig
  0 siblings, 1 reply; 2+ messages in thread
From: Sean Anderson @ 2024-08-12 20:43 UTC (permalink / raw)
  To: Christoph Hellwig, Marek Szyprowski, Robin Murphy, iommu
  Cc: linux-kernel, Sean Anderson

When debugging drivers, it can often be useful to trace when memory gets
(un)mapped for DMA (and can be accessed by the device). Add some
tracepoints for this purpose. While there are many other interesting DMA
functions, this is a useful start for simpler drivers.

Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
---

 include/trace/events/dma.h | 103 +++++++++++++++++++++++++++++++++++++
 kernel/dma/mapping.c       |   5 ++
 2 files changed, 108 insertions(+)
 create mode 100644 include/trace/events/dma.h

diff --git a/include/trace/events/dma.h b/include/trace/events/dma.h
new file mode 100644
index 000000000000..bc32e4302fde
--- /dev/null
+++ b/include/trace/events/dma.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM dma
+
+#if !defined(_TRACE_DMA_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_DMA_H
+
+#include <linux/tracepoint.h>
+#include <linux/dma-direction.h>
+#include <linux/dma-mapping.h>
+
+TRACE_DEFINE_ENUM(DMA_BIDIRECTIONAL);
+TRACE_DEFINE_ENUM(DMA_TO_DEVICE);
+TRACE_DEFINE_ENUM(DMA_FROM_DEVICE);
+TRACE_DEFINE_ENUM(DMA_NONE);
+
+#define decode_dma_data_direction(dir) \
+	__print_symbolic(dir, \
+		{ DMA_BIDIRECTIONAL, "BIDIRECTIONAL" }, \
+		{ DMA_TO_DEVICE, "TO_DEVICE" }, \
+		{ DMA_FROM_DEVICE, "FROM_DEVICE" }, \
+		{ DMA_NONE, "NONE" })
+
+#define decode_dma_attrs(attrs) \
+	__print_flags(attrs, "|", \
+		{ DMA_ATTR_WEAK_ORDERING, "WEAK_ORDERING" }, \
+		{ DMA_ATTR_WRITE_COMBINE, "WRITE_COMBINE" }, \
+		{ DMA_ATTR_NO_KERNEL_MAPPING, "NO_KERNEL_MAPPING" }, \
+		{ DMA_ATTR_SKIP_CPU_SYNC, "SKIP_CPU_SYNC" }, \
+		{ DMA_ATTR_FORCE_CONTIGUOUS, "FORCE_CONTIGUOUS" }, \
+		{ DMA_ATTR_ALLOC_SINGLE_PAGES, "ALLOC_SINGLE_PAGES" }, \
+		{ DMA_ATTR_NO_WARN, "NO_WARN" }, \
+		{ DMA_ATTR_PRIVILEGED, "PRIVILEGED" })
+
+TRACE_EVENT(dma_map_page,
+	TP_PROTO(struct device *dev, const struct page *page, size_t offset,
+		 size_t size, enum dma_data_direction dir, dma_addr_t addr,
+		 unsigned long attrs),
+	TP_ARGS(dev, page, offset, size, dir, addr, attrs),
+
+	TP_STRUCT__entry(
+		__string(device, dev_name(dev))
+		__field(const struct page *, page)
+		__field(size_t, offset)
+		__field(size_t, size)
+		__field(enum dma_data_direction, dir)
+		__field(dma_addr_t, addr)
+		__field(unsigned long, attrs)
+	),
+
+	TP_fast_assign(
+		__assign_str(device);
+		__entry->page = page;
+		__entry->offset = offset;
+		__entry->size = size;
+		__entry->dir = dir;
+		__entry->addr = addr;
+		__entry->attrs = attrs;
+	),
+
+	TP_printk("%s page=%p offset=%zu size=%zu dir=%s addr=%llx attrs=%s",
+		__get_str(device),
+		__entry->page,
+		__entry->offset,
+		__entry->size,
+		decode_dma_data_direction(__entry->dir),
+		(unsigned long long)__entry->addr,
+		decode_dma_attrs(__entry->attrs))
+);
+
+TRACE_EVENT(dma_unmap_page,
+	TP_PROTO(struct device *dev, dma_addr_t addr, size_t size,
+		 enum dma_data_direction dir, unsigned long attrs),
+	TP_ARGS(dev, addr, size, dir, attrs),
+
+	TP_STRUCT__entry(
+		__string(device, dev_name(dev))
+		__field(dma_addr_t, addr)
+		__field(size_t, size)
+		__field(enum dma_data_direction, dir)
+		__field(unsigned long, attrs)
+	),
+
+	TP_fast_assign(
+		__assign_str(device);
+		__entry->addr = addr;
+		__entry->size = size;
+		__entry->dir = dir;
+		__entry->attrs = attrs;
+	),
+
+	TP_printk("%s addr=%llx size=%zu dir=%s attrs=%s",
+		__get_str(device),
+		(unsigned long long)__entry->addr,
+		__entry->size,
+		decode_dma_data_direction(__entry->dir),
+		decode_dma_attrs(__entry->attrs))
+);
+
+#endif /*  _TRACE_DMA_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index b1c18058d55f..fb4c77f6f7cc 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -17,6 +17,9 @@
 #include "debug.h"
 #include "direct.h"
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/dma.h>
+
 #if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
 	defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
 	defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
@@ -162,6 +165,7 @@ dma_addr_t dma_map_page_attrs(struct device *dev, struct page *page,
 	else
 		addr = ops->map_page(dev, page, offset, size, dir, attrs);
 	kmsan_handle_dma(page, offset, size, dir);
+	trace_dma_map_page(dev, page, offset, size, dir, addr, attrs);
 	debug_dma_map_page(dev, page, offset, size, dir, addr, attrs);
 
 	return addr;
@@ -179,6 +183,7 @@ void dma_unmap_page_attrs(struct device *dev, dma_addr_t addr, size_t size,
 		dma_direct_unmap_page(dev, addr, size, dir, attrs);
 	else if (ops->unmap_page)
 		ops->unmap_page(dev, addr, size, dir, attrs);
+	trace_dma_unmap_page(dev, addr, size, dir, attrs);
 	debug_dma_unmap_page(dev, addr, size, dir);
 }
 EXPORT_SYMBOL(dma_unmap_page_attrs);
-- 
2.35.1.1320.gc452695387.dirty


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] dma: Trace dma_map/unmap_page
  2024-08-12 20:43 [PATCH] dma: Trace dma_map/unmap_page Sean Anderson
@ 2024-08-22  4:20 ` Christoph Hellwig
  0 siblings, 0 replies; 2+ messages in thread
From: Christoph Hellwig @ 2024-08-22  4:20 UTC (permalink / raw)
  To: Sean Anderson
  Cc: Christoph Hellwig, Marek Szyprowski, Robin Murphy, iommu,
	linux-kernel

On Mon, Aug 12, 2024 at 04:43:57PM -0400, Sean Anderson wrote:
> When debugging drivers, it can often be useful to trace when memory gets
> (un)mapped for DMA (and can be accessed by the device). Add some
> tracepoints for this purpose. While there are many other interesting DMA
> functions, this is a useful start for simpler drivers.

Just dma_map/unmap_page seems a bit too limited and asymmetric.  Can
you please also add tracing for ->map/unmap_sg and ->map/unmap_resoure
so that we at least cover all the dyanmic DMA mapping interfaces?


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-08-22  4:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-12 20:43 [PATCH] dma: Trace dma_map/unmap_page Sean Anderson
2024-08-22  4:20 ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox