diff options
Diffstat (limited to 'kernel/trace/trace_preemptirq.c')
| -rw-r--r-- | kernel/trace/trace_preemptirq.c | 61 | 
1 files changed, 20 insertions, 41 deletions
diff --git a/kernel/trace/trace_preemptirq.c b/kernel/trace/trace_preemptirq.c index 1e130da1b742..e37446f7916e 100644 --- a/kernel/trace/trace_preemptirq.c +++ b/kernel/trace/trace_preemptirq.c @@ -15,6 +15,20 @@  #define CREATE_TRACE_POINTS  #include <trace/events/preemptirq.h> +/* + * 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 +  #ifdef CONFIG_TRACE_IRQFLAGS  /* Per-cpu variable to prevent redundant calls when IRQs already off */  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)  {  	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);  		this_cpu_write(tracing_irq_cpu, 0);  	} @@ -40,8 +53,7 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_prepare);  void trace_hardirqs_on(void)  {  	if (this_cpu_read(tracing_irq_cpu)) { -		if (!in_nmi()) -			trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1); +		trace(irq_enable)(CALLER_ADDR0, CALLER_ADDR1);  		tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);  		this_cpu_write(tracing_irq_cpu, 0);  	} @@ -63,8 +75,7 @@ void trace_hardirqs_off_finish(void)  	if (!this_cpu_read(tracing_irq_cpu)) {  		this_cpu_write(tracing_irq_cpu, 1);  		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,56 +89,24 @@ void trace_hardirqs_off(void)  	if (!this_cpu_read(tracing_irq_cpu)) {  		this_cpu_write(tracing_irq_cpu, 1);  		tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1); -		if (!in_nmi()) -			trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1); +		trace(irq_disable)(CALLER_ADDR0, CALLER_ADDR1);  	}  }  EXPORT_SYMBOL(trace_hardirqs_off);  NOKPROBE_SYMBOL(trace_hardirqs_off); - -__visible void trace_hardirqs_on_caller(unsigned long caller_addr) -{ -	if (this_cpu_read(tracing_irq_cpu)) { -		if (!in_nmi()) -			trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr); -		tracer_hardirqs_on(CALLER_ADDR0, caller_addr); -		this_cpu_write(tracing_irq_cpu, 0); -	} - -	lockdep_hardirqs_on_prepare(); -	lockdep_hardirqs_on(caller_addr); -} -EXPORT_SYMBOL(trace_hardirqs_on_caller); -NOKPROBE_SYMBOL(trace_hardirqs_on_caller); - -__visible void trace_hardirqs_off_caller(unsigned long caller_addr) -{ -	lockdep_hardirqs_off(caller_addr); - -	if (!this_cpu_read(tracing_irq_cpu)) { -		this_cpu_write(tracing_irq_cpu, 1); -		tracer_hardirqs_off(CALLER_ADDR0, caller_addr); -		if (!in_nmi()) -			trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr); -	} -} -EXPORT_SYMBOL(trace_hardirqs_off_caller); -NOKPROBE_SYMBOL(trace_hardirqs_off_caller);  #endif /* CONFIG_TRACE_IRQFLAGS */  #ifdef CONFIG_TRACE_PREEMPT_TOGGLE  void trace_preempt_on(unsigned long a0, unsigned long a1)  { -	if (!in_nmi()) -		trace_preempt_enable_rcuidle(a0, a1); +	trace(preempt_enable)(a0, a1);  	tracer_preempt_on(a0, a1);  }  void trace_preempt_off(unsigned long a0, unsigned long a1)  { -	if (!in_nmi()) -		trace_preempt_disable_rcuidle(a0, a1); +	trace(preempt_disable)(a0, a1);  	tracer_preempt_off(a0, a1);  }  #endif  |