[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <322ac9e0-9567-8e7c-e2af-e9e1107717bf@oracle.com>
Date: Fri, 3 Apr 2020 10:34:56 +0200
From: Alexandre Chartre <alexandre.chartre@...cle.com>
To: Thomas Gleixner <tglx@...utronix.de>,
LKML <linux-kernel@...r.kernel.org>
Cc: x86@...nel.org, Paul McKenney <paulmck@...nel.org>,
Josh Poimboeuf <jpoimboe@...hat.com>,
"Joel Fernandes (Google)" <joel@...lfernandes.org>,
"Steven Rostedt (VMware)" <rostedt@...dmis.org>,
Masami Hiramatsu <mhiramat@...nel.org>,
Alexei Starovoitov <ast@...nel.org>,
Frederic Weisbecker <frederic@...nel.org>,
Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
Brian Gerst <brgerst@...il.com>,
Juergen Gross <jgross@...e.com>,
Peter Zijlstra <peterz@...radead.org>,
Tom Lendacky <thomas.lendacky@....com>,
Paolo Bonzini <pbonzini@...hat.com>, kvm@...r.kernel.org
Subject: Re: [RESEND][patch V3 05/23] tracing: Provide lockdep less
trace_hardirqs_on/off() variants
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@...utronix.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)) {
>
Powered by blists - more mailing lists