Skip to content

Commit 5e5ff73

Browse files
Sai Prakash Ranjanarndb
authored andcommitted
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: 2100319 ("asm-generic/io: Add logging support for MMIO accessors") Signed-off-by: Sai Prakash Ranjan <[email protected]> Signed-off-by: Arnd Bergmann <[email protected]>
1 parent defbab2 commit 5e5ff73

File tree

3 files changed

+75
-64
lines changed

3 files changed

+75
-64
lines changed

include/asm-generic/io.h

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -80,24 +80,24 @@ DECLARE_TRACEPOINT(rwmmio_read);
8080
DECLARE_TRACEPOINT(rwmmio_post_read);
8181

8282
void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
83-
unsigned long caller_addr);
83+
unsigned long caller_addr, unsigned long caller_addr0);
8484
void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
85-
unsigned long caller_addr);
85+
unsigned long caller_addr, unsigned long caller_addr0);
8686
void log_read_mmio(u8 width, const volatile void __iomem *addr,
87-
unsigned long caller_addr);
87+
unsigned long caller_addr, unsigned long caller_addr0);
8888
void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
89-
unsigned long caller_addr);
89+
unsigned long caller_addr, unsigned long caller_addr0);
9090

9191
#else
9292

9393
static inline void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
94-
unsigned long caller_addr) {}
94+
unsigned long caller_addr, unsigned long caller_addr0) {}
9595
static inline void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
96-
unsigned long caller_addr) {}
96+
unsigned long caller_addr, unsigned long caller_addr0) {}
9797
static inline void log_read_mmio(u8 width, const volatile void __iomem *addr,
98-
unsigned long caller_addr) {}
98+
unsigned long caller_addr, unsigned long caller_addr0) {}
9999
static inline void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
100-
unsigned long caller_addr) {}
100+
unsigned long caller_addr, unsigned long caller_addr0) {}
101101

102102
#endif /* CONFIG_TRACE_MMIO_ACCESS */
103103

@@ -188,11 +188,11 @@ static inline u8 readb(const volatile void __iomem *addr)
188188
{
189189
u8 val;
190190

191-
log_read_mmio(8, addr, _THIS_IP_);
191+
log_read_mmio(8, addr, _THIS_IP_, _RET_IP_);
192192
__io_br();
193193
val = __raw_readb(addr);
194194
__io_ar(val);
195-
log_post_read_mmio(val, 8, addr, _THIS_IP_);
195+
log_post_read_mmio(val, 8, addr, _THIS_IP_, _RET_IP_);
196196
return val;
197197
}
198198
#endif
@@ -203,11 +203,11 @@ static inline u16 readw(const volatile void __iomem *addr)
203203
{
204204
u16 val;
205205

206-
log_read_mmio(16, addr, _THIS_IP_);
206+
log_read_mmio(16, addr, _THIS_IP_, _RET_IP_);
207207
__io_br();
208208
val = __le16_to_cpu((__le16 __force)__raw_readw(addr));
209209
__io_ar(val);
210-
log_post_read_mmio(val, 16, addr, _THIS_IP_);
210+
log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_);
211211
return val;
212212
}
213213
#endif
@@ -218,11 +218,11 @@ static inline u32 readl(const volatile void __iomem *addr)
218218
{
219219
u32 val;
220220

221-
log_read_mmio(32, addr, _THIS_IP_);
221+
log_read_mmio(32, addr, _THIS_IP_, _RET_IP_);
222222
__io_br();
223223
val = __le32_to_cpu((__le32 __force)__raw_readl(addr));
224224
__io_ar(val);
225-
log_post_read_mmio(val, 32, addr, _THIS_IP_);
225+
log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_);
226226
return val;
227227
}
228228
#endif
@@ -234,11 +234,11 @@ static inline u64 readq(const volatile void __iomem *addr)
234234
{
235235
u64 val;
236236

237-
log_read_mmio(64, addr, _THIS_IP_);
237+
log_read_mmio(64, addr, _THIS_IP_, _RET_IP_);
238238
__io_br();
239239
val = __le64_to_cpu(__raw_readq(addr));
240240
__io_ar(val);
241-
log_post_read_mmio(val, 64, addr, _THIS_IP_);
241+
log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_);
242242
return val;
243243
}
244244
#endif
@@ -248,35 +248,35 @@ static inline u64 readq(const volatile void __iomem *addr)
248248
#define writeb writeb
249249
static inline void writeb(u8 value, volatile void __iomem *addr)
250250
{
251-
log_write_mmio(value, 8, addr, _THIS_IP_);
251+
log_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_);
252252
__io_bw();
253253
__raw_writeb(value, addr);
254254
__io_aw();
255-
log_post_write_mmio(value, 8, addr, _THIS_IP_);
255+
log_post_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_);
256256
}
257257
#endif
258258

259259
#ifndef writew
260260
#define writew writew
261261
static inline void writew(u16 value, volatile void __iomem *addr)
262262
{
263-
log_write_mmio(value, 16, addr, _THIS_IP_);
263+
log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
264264
__io_bw();
265265
__raw_writew((u16 __force)cpu_to_le16(value), addr);
266266
__io_aw();
267-
log_post_write_mmio(value, 16, addr, _THIS_IP_);
267+
log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
268268
}
269269
#endif
270270

271271
#ifndef writel
272272
#define writel writel
273273
static inline void writel(u32 value, volatile void __iomem *addr)
274274
{
275-
log_write_mmio(value, 32, addr, _THIS_IP_);
275+
log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
276276
__io_bw();
277277
__raw_writel((u32 __force)__cpu_to_le32(value), addr);
278278
__io_aw();
279-
log_post_write_mmio(value, 32, addr, _THIS_IP_);
279+
log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
280280
}
281281
#endif
282282

@@ -285,11 +285,11 @@ static inline void writel(u32 value, volatile void __iomem *addr)
285285
#define writeq writeq
286286
static inline void writeq(u64 value, volatile void __iomem *addr)
287287
{
288-
log_write_mmio(value, 64, addr, _THIS_IP_);
288+
log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
289289
__io_bw();
290290
__raw_writeq(__cpu_to_le64(value), addr);
291291
__io_aw();
292-
log_post_write_mmio(value, 64, addr, _THIS_IP_);
292+
log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
293293
}
294294
#endif
295295
#endif /* CONFIG_64BIT */
@@ -305,9 +305,9 @@ static inline u8 readb_relaxed(const volatile void __iomem *addr)
305305
{
306306
u8 val;
307307

308-
log_read_mmio(8, addr, _THIS_IP_);
308+
log_read_mmio(8, addr, _THIS_IP_, _RET_IP_);
309309
val = __raw_readb(addr);
310-
log_post_read_mmio(val, 8, addr, _THIS_IP_);
310+
log_post_read_mmio(val, 8, addr, _THIS_IP_, _RET_IP_);
311311
return val;
312312
}
313313
#endif
@@ -318,9 +318,9 @@ static inline u16 readw_relaxed(const volatile void __iomem *addr)
318318
{
319319
u16 val;
320320

321-
log_read_mmio(16, addr, _THIS_IP_);
321+
log_read_mmio(16, addr, _THIS_IP_, _RET_IP_);
322322
val = __le16_to_cpu(__raw_readw(addr));
323-
log_post_read_mmio(val, 16, addr, _THIS_IP_);
323+
log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_);
324324
return val;
325325
}
326326
#endif
@@ -331,9 +331,9 @@ static inline u32 readl_relaxed(const volatile void __iomem *addr)
331331
{
332332
u32 val;
333333

334-
log_read_mmio(32, addr, _THIS_IP_);
334+
log_read_mmio(32, addr, _THIS_IP_, _RET_IP_);
335335
val = __le32_to_cpu(__raw_readl(addr));
336-
log_post_read_mmio(val, 32, addr, _THIS_IP_);
336+
log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_);
337337
return val;
338338
}
339339
#endif
@@ -344,9 +344,9 @@ static inline u64 readq_relaxed(const volatile void __iomem *addr)
344344
{
345345
u64 val;
346346

347-
log_read_mmio(64, addr, _THIS_IP_);
347+
log_read_mmio(64, addr, _THIS_IP_, _RET_IP_);
348348
val = __le64_to_cpu(__raw_readq(addr));
349-
log_post_read_mmio(val, 64, addr, _THIS_IP_);
349+
log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_);
350350
return val;
351351
}
352352
#endif
@@ -355,39 +355,39 @@ static inline u64 readq_relaxed(const volatile void __iomem *addr)
355355
#define writeb_relaxed writeb_relaxed
356356
static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
357357
{
358-
log_write_mmio(value, 8, addr, _THIS_IP_);
358+
log_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_);
359359
__raw_writeb(value, addr);
360-
log_post_write_mmio(value, 8, addr, _THIS_IP_);
360+
log_post_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_);
361361
}
362362
#endif
363363

364364
#ifndef writew_relaxed
365365
#define writew_relaxed writew_relaxed
366366
static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
367367
{
368-
log_write_mmio(value, 16, addr, _THIS_IP_);
368+
log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
369369
__raw_writew(cpu_to_le16(value), addr);
370-
log_post_write_mmio(value, 16, addr, _THIS_IP_);
370+
log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
371371
}
372372
#endif
373373

374374
#ifndef writel_relaxed
375375
#define writel_relaxed writel_relaxed
376376
static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
377377
{
378-
log_write_mmio(value, 32, addr, _THIS_IP_);
378+
log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
379379
__raw_writel(__cpu_to_le32(value), addr);
380-
log_post_write_mmio(value, 32, addr, _THIS_IP_);
380+
log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
381381
}
382382
#endif
383383

384384
#if defined(writeq) && !defined(writeq_relaxed)
385385
#define writeq_relaxed writeq_relaxed
386386
static inline void writeq_relaxed(u64 value, volatile void __iomem *addr)
387387
{
388-
log_write_mmio(value, 64, addr, _THIS_IP_);
388+
log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
389389
__raw_writeq(__cpu_to_le64(value), addr);
390-
log_post_write_mmio(value, 64, addr, _THIS_IP_);
390+
log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
391391
}
392392
#endif
393393

include/trace/events/rwmmio.h

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,83 +12,94 @@
1212

1313
DECLARE_EVENT_CLASS(rwmmio_rw_template,
1414

15-
TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
15+
TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
16+
volatile void __iomem *addr),
1617

17-
TP_ARGS(caller, val, width, addr),
18+
TP_ARGS(caller, caller0, val, width, addr),
1819

1920
TP_STRUCT__entry(
2021
__field(unsigned long, caller)
22+
__field(unsigned long, caller0)
2123
__field(unsigned long, addr)
2224
__field(u64, val)
2325
__field(u8, width)
2426
),
2527

2628
TP_fast_assign(
2729
__entry->caller = caller;
30+
__entry->caller0 = caller0;
2831
__entry->val = val;
2932
__entry->addr = (unsigned long)addr;
3033
__entry->width = width;
3134
),
3235

33-
TP_printk("%pS width=%d val=%#llx addr=%#lx",
34-
(void *)__entry->caller, __entry->width,
36+
TP_printk("%pS -> %pS width=%d val=%#llx addr=%#lx",
37+
(void *)__entry->caller0, (void *)__entry->caller, __entry->width,
3538
__entry->val, __entry->addr)
3639
);
3740

3841
DEFINE_EVENT(rwmmio_rw_template, rwmmio_write,
39-
TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
40-
TP_ARGS(caller, val, width, addr)
42+
TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
43+
volatile void __iomem *addr),
44+
TP_ARGS(caller, caller0, val, width, addr)
4145
);
4246

4347
DEFINE_EVENT(rwmmio_rw_template, rwmmio_post_write,
44-
TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
45-
TP_ARGS(caller, val, width, addr)
48+
TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
49+
volatile void __iomem *addr),
50+
TP_ARGS(caller, caller0, val, width, addr)
4651
);
4752

4853
TRACE_EVENT(rwmmio_read,
4954

50-
TP_PROTO(unsigned long caller, u8 width, const volatile void __iomem *addr),
55+
TP_PROTO(unsigned long caller, unsigned long caller0, u8 width,
56+
const volatile void __iomem *addr),
5157

52-
TP_ARGS(caller, width, addr),
58+
TP_ARGS(caller, caller0, width, addr),
5359

5460
TP_STRUCT__entry(
5561
__field(unsigned long, caller)
62+
__field(unsigned long, caller0)
5663
__field(unsigned long, addr)
5764
__field(u8, width)
5865
),
5966

6067
TP_fast_assign(
6168
__entry->caller = caller;
69+
__entry->caller0 = caller0;
6270
__entry->addr = (unsigned long)addr;
6371
__entry->width = width;
6472
),
6573

66-
TP_printk("%pS width=%d addr=%#lx",
67-
(void *)__entry->caller, __entry->width, __entry->addr)
74+
TP_printk("%pS -> %pS width=%d addr=%#lx",
75+
(void *)__entry->caller0, (void *)__entry->caller, __entry->width, __entry->addr)
6876
);
6977

7078
TRACE_EVENT(rwmmio_post_read,
7179

72-
TP_PROTO(unsigned long caller, u64 val, u8 width, const volatile void __iomem *addr),
80+
TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
81+
const volatile void __iomem *addr),
7382

74-
TP_ARGS(caller, val, width, addr),
83+
TP_ARGS(caller, caller0, val, width, addr),
7584

7685
TP_STRUCT__entry(
7786
__field(unsigned long, caller)
87+
__field(unsigned long, caller0)
7888
__field(unsigned long, addr)
7989
__field(u64, val)
8090
__field(u8, width)
8191
),
8292

8393
TP_fast_assign(
8494
__entry->caller = caller;
95+
__entry->caller0 = caller0;
8596
__entry->val = val;
8697
__entry->addr = (unsigned long)addr;
8798
__entry->width = width;
8899
),
89100

90-
TP_printk("%pS width=%d val=%#llx addr=%#lx",
91-
(void *)__entry->caller, __entry->width,
101+
TP_printk("%pS -> %pS width=%d val=%#llx addr=%#lx",
102+
(void *)__entry->caller0, (void *)__entry->caller, __entry->width,
92103
__entry->val, __entry->addr)
93104
);
94105

lib/trace_readwrite.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,33 @@
1414

1515
#ifdef CONFIG_TRACE_MMIO_ACCESS
1616
void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
17-
unsigned long caller_addr)
17+
unsigned long caller_addr, unsigned long caller_addr0)
1818
{
19-
trace_rwmmio_write(caller_addr, val, width, addr);
19+
trace_rwmmio_write(caller_addr, caller_addr0, val, width, addr);
2020
}
2121
EXPORT_SYMBOL_GPL(log_write_mmio);
2222
EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_write);
2323

2424
void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
25-
unsigned long caller_addr)
25+
unsigned long caller_addr, unsigned long caller_addr0)
2626
{
27-
trace_rwmmio_post_write(caller_addr, val, width, addr);
27+
trace_rwmmio_post_write(caller_addr, caller_addr0, val, width, addr);
2828
}
2929
EXPORT_SYMBOL_GPL(log_post_write_mmio);
3030
EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_write);
3131

3232
void log_read_mmio(u8 width, const volatile void __iomem *addr,
33-
unsigned long caller_addr)
33+
unsigned long caller_addr, unsigned long caller_addr0)
3434
{
35-
trace_rwmmio_read(caller_addr, width, addr);
35+
trace_rwmmio_read(caller_addr, caller_addr0, width, addr);
3636
}
3737
EXPORT_SYMBOL_GPL(log_read_mmio);
3838
EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_read);
3939

4040
void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
41-
unsigned long caller_addr)
41+
unsigned long caller_addr, unsigned long caller_addr0)
4242
{
43-
trace_rwmmio_post_read(caller_addr, val, width, addr);
43+
trace_rwmmio_post_read(caller_addr, caller_addr0, val, width, addr);
4444
}
4545
EXPORT_SYMBOL_GPL(log_post_read_mmio);
4646
EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_read);

0 commit comments

Comments
 (0)