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