提交 9aedeaed 编写于 作者: P Peter Zijlstra 提交者: Ingo Molnar

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: Nkernel test robot <lkp@intel.com>
Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: NIngo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20230112195541.477416709@infradead.org
上级 408b9611
...@@ -19,6 +19,20 @@ ...@@ -19,6 +19,20 @@
/* Per-cpu variable to prevent redundant calls when IRQs already off */ /* Per-cpu variable to prevent redundant calls when IRQs already off */
static DEFINE_PER_CPU(int, tracing_irq_cpu); static DEFINE_PER_CPU(int, tracing_irq_cpu);
/*
* Use regular trace points on architectures that implement noinstr
* tooling: these calls will only happen with RCU enabled, which can
* use a regular tracepoint.
*
* On older architectures, use the rcuidle tracing methods (which
* aren't NMI-safe - so exclude NMI contexts):
*/
#ifdef CONFIG_ARCH_WANTS_NO_INSTR
#define trace(point) trace_##point
#else
#define trace(point) if (!in_nmi()) trace_##point##_rcuidle
#endif
/* /*
* Like trace_hardirqs_on() but without the lockdep invocation. This is * Like trace_hardirqs_on() but without the lockdep invocation. This is
* used in the low level entry code where the ordering vs. RCU is important * 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); ...@@ -28,8 +42,7 @@ static DEFINE_PER_CPU(int, tracing_irq_cpu);
void trace_hardirqs_on_prepare(void) void trace_hardirqs_on_prepare(void)
{ {
if (this_cpu_read(tracing_irq_cpu)) { if (this_cpu_read(tracing_irq_cpu)) {
if (!in_nmi()) trace(irq_enable)(CALLER_ADDR0, CALLER_ADDR1);
trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1);
tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1); tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
this_cpu_write(tracing_irq_cpu, 0); this_cpu_write(tracing_irq_cpu, 0);
} }
...@@ -40,8 +53,7 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_prepare); ...@@ -40,8 +53,7 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_prepare);
void trace_hardirqs_on(void) void trace_hardirqs_on(void)
{ {
if (this_cpu_read(tracing_irq_cpu)) { if (this_cpu_read(tracing_irq_cpu)) {
if (!in_nmi()) trace(irq_enable)(CALLER_ADDR0, CALLER_ADDR1);
trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1); tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
this_cpu_write(tracing_irq_cpu, 0); this_cpu_write(tracing_irq_cpu, 0);
} }
...@@ -63,8 +75,7 @@ void trace_hardirqs_off_finish(void) ...@@ -63,8 +75,7 @@ void trace_hardirqs_off_finish(void)
if (!this_cpu_read(tracing_irq_cpu)) { if (!this_cpu_read(tracing_irq_cpu)) {
this_cpu_write(tracing_irq_cpu, 1); this_cpu_write(tracing_irq_cpu, 1);
tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1); tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
if (!in_nmi()) trace(irq_disable)(CALLER_ADDR0, CALLER_ADDR1);
trace_irq_disable(CALLER_ADDR0, CALLER_ADDR1);
} }
} }
...@@ -78,8 +89,7 @@ void trace_hardirqs_off(void) ...@@ -78,8 +89,7 @@ void trace_hardirqs_off(void)
if (!this_cpu_read(tracing_irq_cpu)) { if (!this_cpu_read(tracing_irq_cpu)) {
this_cpu_write(tracing_irq_cpu, 1); this_cpu_write(tracing_irq_cpu, 1);
tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1); tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
if (!in_nmi()) trace(irq_disable)(CALLER_ADDR0, CALLER_ADDR1);
trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
} }
} }
EXPORT_SYMBOL(trace_hardirqs_off); EXPORT_SYMBOL(trace_hardirqs_off);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册