Re: [patch V5 03/38] nmi, tracing: Provide nmi_enter/exit_notrace()

Steven Rostedt
2020-05-15T01:32:36Z

On Tue, 12 May 2020 23:01:02 +0200
Thomas Gleixner <tglx@linutronix.de> wrote:

> To fully isolate #DB and #BP from instrumentable code it's necessary to
> avoid invoking the hardware latency tracer on nmi_enter/exit().
>
> Provide nmi_enter/exit() variants which are not invoking the hardware
> latency tracer. That allows to put calls explicitely into the call sites
> outside of the kprobe handling.

The only thing the hardware latency tracer is using this for is to
denote that something happened while it was timing "nothing" happening.

It's accounting only. Now it does use a per-cpu variable (which I see
in other patches can be an issue) and calls time_get().

Now if per-cpu nor time_get() can not be called in noinstr, then I'm
perfectly fine with this patch. But if they are allowed, I don't think
that this patch is necessary, and we could perhaps mark the hardware
latency hook as noinstr instead?

-- Steve

>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
> V5: New patch
> ---
> include/linux/hardirq.h | 18 ++++++++++++++----
> 1 file changed, 14 insertions(+), 4 deletions(-)
>
> --- a/include/linux/hardirq.h
> +++ b/include/linux/hardirq.h
> @@ -77,28 +77,38 @@ extern void irq_exit(void);
> /*
> * nmi_enter() can nest up to 15 times; see NMI_BITS.
> */
> -#define nmi_enter() \
> +#define nmi_enter_notrace() \
> do { \
> arch_nmi_enter(); \
> printk_nmi_enter(); \
> lockdep_off(); \
> - ftrace_nmi_enter(); \
> BUG_ON(in_nmi() == NMI_MASK); \
> __preempt_count_add(NMI_OFFSET + HARDIRQ_OFFSET); \
> rcu_nmi_enter(); \
> lockdep_hardirq_enter(); \
> } while (0)
>
> -#define nmi_exit() \
> +#define nmi_enter() \
> + do { \
> + nmi_enter_notrace(); \
> + ftrace_nmi_enter(); \
> + } while (0)
> +
> +#define nmi_exit_notrace() \
> do { \
> lockdep_hardirq_exit(); \
> rcu_nmi_exit(); \
> BUG_ON(!in_nmi()); \
> __preempt_count_sub(NMI_OFFSET + HARDIRQ_OFFSET); \
> - ftrace_nmi_exit(); \
> lockdep_on(); \
> printk_nmi_exit(); \
> arch_nmi_exit(); \
> } while (0)
>
> +#define nmi_exit() \
> + do { \
> + ftrace_nmi_exit(); \
> + nmi_exit_notrace(); \
> + } while (0)
> +
> #endif /* LINUX_HARDIRQ_H */