linux/include/trace/events/rwmmio.h
Sai Prakash Ranjan 5e5ff73c2e asm-generic/io: Add _RET_IP_ to MMIO trace for more accurate debug info
Due to compiler optimizations like inlining, there are cases where
MMIO traces using _THIS_IP_ for caller information might not be
sufficient to provide accurate debug traces.

1) With optimizations (Seen with GCC):

In this case, _THIS_IP_ works fine and prints the caller information
since it will be inlined into the caller and we get the debug traces
on who made the MMIO access, for ex:

rwmmio_read: qcom_smmu_tlb_sync+0xe0/0x1b0 width=32 addr=0xffff8000087447f4
rwmmio_post_read: qcom_smmu_tlb_sync+0xe0/0x1b0 width=32 val=0x0 addr=0xffff8000087447f4

2) Without optimizations (Seen with Clang):

_THIS_IP_ will not be sufficient in this case as it will print only
the MMIO accessors itself which is of not much use since it is not
inlined as below for example:

rwmmio_read: readl+0x4/0x80 width=32 addr=0xffff8000087447f4
rwmmio_post_read: readl+0x48/0x80 width=32 val=0x4 addr=0xffff8000087447f4

So in order to handle this second case as well irrespective of the compiler
optimizations, add _RET_IP_ to MMIO trace to make it provide more accurate
debug information in all these scenarios.

Before:

rwmmio_read: readl+0x4/0x80 width=32 addr=0xffff8000087447f4
rwmmio_post_read: readl+0x48/0x80 width=32 val=0x4 addr=0xffff8000087447f4

After:

rwmmio_read: qcom_smmu_tlb_sync+0xe0/0x1b0 -> readl+0x4/0x80 width=32 addr=0xffff8000087447f4
rwmmio_post_read: qcom_smmu_tlb_sync+0xe0/0x1b0 -> readl+0x4/0x80 width=32 val=0x0 addr=0xffff8000087447f4

Fixes: 210031971c ("asm-generic/io: Add logging support for MMIO accessors")
Signed-off-by: Sai Prakash Ranjan <quic_saipraka@quicinc.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2022-11-21 22:02:10 +01:00

109 lines
2.7 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM rwmmio
#if !defined(_TRACE_RWMMIO_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_RWMMIO_H
#include <linux/tracepoint.h>
DECLARE_EVENT_CLASS(rwmmio_rw_template,
TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
volatile void __iomem *addr),
TP_ARGS(caller, caller0, val, width, addr),
TP_STRUCT__entry(
__field(unsigned long, caller)
__field(unsigned long, caller0)
__field(unsigned long, addr)
__field(u64, val)
__field(u8, width)
),
TP_fast_assign(
__entry->caller = caller;
__entry->caller0 = caller0;
__entry->val = val;
__entry->addr = (unsigned long)addr;
__entry->width = width;
),
TP_printk("%pS -> %pS width=%d val=%#llx addr=%#lx",
(void *)__entry->caller0, (void *)__entry->caller, __entry->width,
__entry->val, __entry->addr)
);
DEFINE_EVENT(rwmmio_rw_template, rwmmio_write,
TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
volatile void __iomem *addr),
TP_ARGS(caller, caller0, val, width, addr)
);
DEFINE_EVENT(rwmmio_rw_template, rwmmio_post_write,
TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
volatile void __iomem *addr),
TP_ARGS(caller, caller0, val, width, addr)
);
TRACE_EVENT(rwmmio_read,
TP_PROTO(unsigned long caller, unsigned long caller0, u8 width,
const volatile void __iomem *addr),
TP_ARGS(caller, caller0, width, addr),
TP_STRUCT__entry(
__field(unsigned long, caller)
__field(unsigned long, caller0)
__field(unsigned long, addr)
__field(u8, width)
),
TP_fast_assign(
__entry->caller = caller;
__entry->caller0 = caller0;
__entry->addr = (unsigned long)addr;
__entry->width = width;
),
TP_printk("%pS -> %pS width=%d addr=%#lx",
(void *)__entry->caller0, (void *)__entry->caller, __entry->width, __entry->addr)
);
TRACE_EVENT(rwmmio_post_read,
TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
const volatile void __iomem *addr),
TP_ARGS(caller, caller0, val, width, addr),
TP_STRUCT__entry(
__field(unsigned long, caller)
__field(unsigned long, caller0)
__field(unsigned long, addr)
__field(u64, val)
__field(u8, width)
),
TP_fast_assign(
__entry->caller = caller;
__entry->caller0 = caller0;
__entry->val = val;
__entry->addr = (unsigned long)addr;
__entry->width = width;
),
TP_printk("%pS -> %pS width=%d val=%#llx addr=%#lx",
(void *)__entry->caller0, (void *)__entry->caller, __entry->width,
__entry->val, __entry->addr)
);
#endif /* _TRACE_RWMMIO_H */
#include <trace/define_trace.h>