Skip to content

Commit 9aedeae

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
tracing, hardirq: No moar _rcuidle() tracing
Robot reported that trace_hardirqs_{on,off}() tickle the forbidden _rcuidle() tracepoint through local_irq_{en,dis}able(). For 'sane' configs, these calls will only happen with RCU enabled and as such can use the regular tracepoint. This also means it's possible to trace them from NMI context again. Reported-by: kernel test robot <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 408b961 commit 9aedeae

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

kernel/trace/trace_preemptirq.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@
1919
/* Per-cpu variable to prevent redundant calls when IRQs already off */
2020
static DEFINE_PER_CPU(int, tracing_irq_cpu);
2121

22+
/*
23+
* Use regular trace points on architectures that implement noinstr
24+
* tooling: these calls will only happen with RCU enabled, which can
25+
* use a regular tracepoint.
26+
*
27+
* On older architectures, use the rcuidle tracing methods (which
28+
* aren't NMI-safe - so exclude NMI contexts):
29+
*/
30+
#ifdef CONFIG_ARCH_WANTS_NO_INSTR
31+
#define trace(point) trace_##point
32+
#else
33+
#define trace(point) if (!in_nmi()) trace_##point##_rcuidle
34+
#endif
35+
2236
/*
2337
* Like trace_hardirqs_on() but without the lockdep invocation. This is
2438
* used in the low level entry code where the ordering vs. RCU is important
@@ -28,8 +42,7 @@ static DEFINE_PER_CPU(int, tracing_irq_cpu);
2842
void trace_hardirqs_on_prepare(void)
2943
{
3044
if (this_cpu_read(tracing_irq_cpu)) {
31-
if (!in_nmi())
32-
trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1);
45+
trace(irq_enable)(CALLER_ADDR0, CALLER_ADDR1);
3346
tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
3447
this_cpu_write(tracing_irq_cpu, 0);
3548
}
@@ -40,8 +53,7 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_prepare);
4053
void trace_hardirqs_on(void)
4154
{
4255
if (this_cpu_read(tracing_irq_cpu)) {
43-
if (!in_nmi())
44-
trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
56+
trace(irq_enable)(CALLER_ADDR0, CALLER_ADDR1);
4557
tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
4658
this_cpu_write(tracing_irq_cpu, 0);
4759
}
@@ -63,8 +75,7 @@ void trace_hardirqs_off_finish(void)
6375
if (!this_cpu_read(tracing_irq_cpu)) {
6476
this_cpu_write(tracing_irq_cpu, 1);
6577
tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
66-
if (!in_nmi())
67-
trace_irq_disable(CALLER_ADDR0, CALLER_ADDR1);
78+
trace(irq_disable)(CALLER_ADDR0, CALLER_ADDR1);
6879
}
6980

7081
}
@@ -78,8 +89,7 @@ void trace_hardirqs_off(void)
7889
if (!this_cpu_read(tracing_irq_cpu)) {
7990
this_cpu_write(tracing_irq_cpu, 1);
8091
tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
81-
if (!in_nmi())
82-
trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
92+
trace(irq_disable)(CALLER_ADDR0, CALLER_ADDR1);
8393
}
8494
}
8595
EXPORT_SYMBOL(trace_hardirqs_off);

0 commit comments

Comments
 (0)