Messages in this thread | | | Subject | Re: [RESEND][patch V3 05/23] tracing: Provide lockdep less trace_hardirqs_on/off() variants | From | Alexandre Chartre <> | Date | Fri, 3 Apr 2020 10:34:56 +0200 |
| |
On 3/20/20 7:00 PM, Thomas Gleixner wrote: > trace_hardirqs_on/off() is only partially safe vs. RCU idle. The tracer > core itself is safe, but the resulting tracepoints can be utilized by > e.g. BPF which is unsafe. > > Provide variants which do not contain the lockdep invocation so the lockdep > and tracer invocations can be split at the call site and placed properly. > > The new variants also do not use rcuidle as they are going to be called > from entry code after/before context tracking. > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> > --- > V2: New patch > --- > include/linux/irqflags.h | 4 ++++ > kernel/trace/trace_preemptirq.c | 23 +++++++++++++++++++++++ > 2 files changed, 27 insertions(+) > > --- a/include/linux/irqflags.h > +++ b/include/linux/irqflags.h > @@ -29,6 +29,8 @@ > #endif > > #ifdef CONFIG_TRACE_IRQFLAGS > + extern void __trace_hardirqs_on(void); > + extern void __trace_hardirqs_off(void); > extern void trace_hardirqs_on(void); > extern void trace_hardirqs_off(void); > # define trace_hardirq_context(p) ((p)->hardirq_context) > @@ -52,6 +54,8 @@ do { \ > current->softirq_context--; \ > } while (0) > #else > +# define __trace_hardirqs_on() do { } while (0) > +# define __trace_hardirqs_off() do { } while (0) > # define trace_hardirqs_on() do { } while (0) > # define trace_hardirqs_off() do { } while (0) > # define trace_hardirq_context(p) 0 > --- a/kernel/trace/trace_preemptirq.c > +++ b/kernel/trace/trace_preemptirq.c > @@ -19,6 +19,17 @@ > /* Per-cpu variable to prevent redundant calls when IRQs already off */ > static DEFINE_PER_CPU(int, tracing_irq_cpu); > > +void __trace_hardirqs_on(void) > +{ > + if (this_cpu_read(tracing_irq_cpu)) { > + if (!in_nmi()) > + trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1); > + tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1); > + this_cpu_write(tracing_irq_cpu, 0); > + } > +} > +NOKPROBE_SYMBOL(__trace_hardirqs_on); > +
It would be good to have a comment which highlights the difference between __trace_hardirqs_on/off and trace_hardirqs_on/off because the code difference is not obvious and the function names are so similar.
alex.
> void trace_hardirqs_on(void) > { > if (this_cpu_read(tracing_irq_cpu)) { > @@ -33,6 +44,18 @@ void trace_hardirqs_on(void) > EXPORT_SYMBOL(trace_hardirqs_on); > NOKPROBE_SYMBOL(trace_hardirqs_on); > > +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(CALLER_ADDR0, CALLER_ADDR1); > + } > + > +} > +NOKPROBE_SYMBOL(__trace_hardirqs_off); > + > void trace_hardirqs_off(void) > { > if (!this_cpu_read(tracing_irq_cpu)) { >
| |