lkml.org 
[lkml]   [2020]   [Apr]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [RESEND][patch V3 05/23] tracing: Provide lockdep less trace_hardirqs_on/off() variants
From
Date

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)) {
>

\
 
 \ /
  Last update: 2020-04-03 10:31    [W:0.319 / U:0.984 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site