[PATCHv3 3/3] dynamic_debug: Add a flag for dynamic event tracing

From: Sai Prakash Ranjan
Date: Tue Nov 09 2021 - 07:09:38 EST


Debugging a specific driver or subsystem can be a lot easier if we can
trace events specific to that driver or subsystem. This type of
filtering can be achieved using existing dynamic debug library which
provides a way to filter based on files, functions and modules.

Using this, provide an additional flag 'e' to filter event tracing to
specified input.

For example, tracing all MMIO read/write can be overwhelming and of no
use when debugging a specific driver or a subsystem. So switch to
dynamic event tracing for register accesses.

Example: Tracing register accesses for all drivers in drivers/soc/qcom/*
and the trace output is given below:

# dyndbg="file drivers/soc/qcom/* +e" trace_event=rwmmio
or
# echo "file drivers/soc/qcom/* +e" > /sys/kernel/debug/dynamic_debug/control
# cat /sys/kernel/debug/tracing/trace
rwmmio_read: rpmh_rsc_probe+0x35c/0x410 readl addr=0xffff80001071000c
rwmmio_read: rpmh_rsc_probe+0x3d0/0x410 readl addr=0xffff800010710004
rwmmio_write: rpmh_rsc_probe+0x3b0/0x410 writel addr=0xffff800010710d00 val=0x3
rwmmio_write: write_tcs_cmd+0x6c/0x78 writel addr=0xffff800010710d30 val=0x10108

Cc: Jason Baron <jbaron@xxxxxxxxxx>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka@xxxxxxxxxxx>
---
include/linux/dynamic_debug.h | 1 +
include/linux/mmio-instrumented.h | 29 +++++++++++++++++++++++++++--
lib/dynamic_debug.c | 1 +
3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index dce631e678dd..80a1ae234a3b 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -32,6 +32,7 @@ struct _ddebug {
#define _DPRINTK_FLAGS_INCL_FUNCNAME (1<<2)
#define _DPRINTK_FLAGS_INCL_LINENO (1<<3)
#define _DPRINTK_FLAGS_INCL_TID (1<<4)
+#define _DPRINTK_FLAGS_EVENT (1<<5)

#define _DPRINTK_FLAGS_INCL_ANY \
(_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
diff --git a/include/linux/mmio-instrumented.h b/include/linux/mmio-instrumented.h
index 4304224f3be4..4ff5af4bbee8 100644
--- a/include/linux/mmio-instrumented.h
+++ b/include/linux/mmio-instrumented.h
@@ -6,6 +6,7 @@
#ifndef _LINUX_MMIO_INSTRUMENTED_H
#define _LINUX_MMIO_INSTRUMENTED_H

+#include <linux/dynamic_debug.h>
#include <linux/tracepoint-defs.h>

/*
@@ -25,7 +26,7 @@ void log_read_mmio(const char *width, const volatile void __iomem *addr);
#define __raw_write(v, a, _l) ({ \
volatile void __iomem *_a = (a); \
if (tracepoint_enabled(rwmmio_write)) \
- log_write_mmio(__stringify(write##_l), v, _a); \
+ dynamic_log_write_mmio(__stringify(write##_l), v, _a);\
arch_raw_write##_l((v), _a); \
})

@@ -38,7 +39,7 @@ void log_read_mmio(const char *width, const volatile void __iomem *addr);
_t __a; \
const volatile void __iomem *_a = (a); \
if (tracepoint_enabled(rwmmio_read)) \
- log_read_mmio(__stringify(read##_l), _a); \
+ dynamic_log_read_mmio(__stringify(read##_l), _a);\
__a = arch_raw_read##_l(_a); \
__a; \
})
@@ -48,6 +49,26 @@ void log_read_mmio(const char *width, const volatile void __iomem *addr);
#define __raw_readl(a) __raw_read((a), l, u32)
#define __raw_readq(a) __raw_read((a), q, u64)

+#if defined(CONFIG_DYNAMIC_DEBUG)
+#define dynamic_log_write_mmio(width, value, addr) \
+do { \
+ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, width); \
+ if (unlikely(descriptor.flags & _DPRINTK_FLAGS_EVENT)) \
+ log_write_mmio(width, value, addr); \
+} while (0)
+
+#define dynamic_log_read_mmio(width, addr) \
+do { \
+ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, width); \
+ if (unlikely(descriptor.flags & _DPRINTK_FLAGS_EVENT)) \
+ log_read_mmio(width, addr); \
+} while (0)
+
+#else
+#define dynamic_log_write_mmio(width, val, addr) log_write_mmio(width, val, addr)
+#define dynamic_log_read_mmio(width, addr) log_read_mmio(width, addr)
+#endif /* CONFIG_DYNAMIC_DEBUG */
+
#else

#define __raw_writeb(v, a) arch_raw_writeb(v, a)
@@ -64,6 +85,10 @@ static inline void log_write_mmio(const char *width, u64 val,
volatile void __iomem *addr) {}
static inline void log_read_mmio(const char *width,
const volatile void __iomem *addr) {}
+static inline void dynamic_log_write_mmio(const char *width, u64 val,
+ volatile void __iomem *addr) {}
+static inline void dynamic_log_read_mmio(const char *width,
+ const volatile void __iomem *addr) {}

#endif /* CONFIG_TRACE_MMIO_ACCESS */

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index dd7f56af9aed..a852073089d9 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -87,6 +87,7 @@ static inline const char *trim_prefix(const char *path)

static struct { unsigned flag:8; char opt_char; } opt_array[] = {
{ _DPRINTK_FLAGS_PRINT, 'p' },
+ { _DPRINTK_FLAGS_EVENT, 'e' },
{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
--
2.29.0