On Tue, May 26, 2026 at 08:21:46AM -0700, Boqun Feng wrote:
[...]
> +#ifdef CONFIG_HAS_SEPARATE_PREEMPT_RESCHED_BITS
> +static __always_inline void __preempt_count_nmi_enter(void)
> +{
> +     __preempt_count_add(NMI_OFFSET + HARDIRQ_OFFSET);
> +}
> +
> +static __always_inline void __preempt_count_nmi_exit(void)
> +{
> +     __preempt_count_sub(NMI_OFFSET + HARDIRQ_OFFSET);
> +}
> +#else
> +DECLARE_PER_CPU(unsigned int, nmi_nesting);
> +
> +#define __preempt_count_nmi_enter()                          \
> +     do {                                                    \
> +             unsigned int _o = NMI_MASK + HARDIRQ_OFFSET;    \
> +             /* Maximum NMI nesting is 15. */                \
> +             BUG_ON(__this_cpu_read(nmi_nesting) >= 15);     \
> +             __this_cpu_inc(nmi_nesting);                    \
> +             _o -= (preempt_count() & NMI_MASK);             \
> +             __preempt_count_add(_o);                        \
> +     } while (0)
> +
> +#define __preempt_count_nmi_exit()                           \
> +     do {                                                    \
> +             unsigned int _o = HARDIRQ_OFFSET;               \
> +             if (!__this_cpu_dec_return(nmi_nesting))        \
> +                     _o += NMI_MASK;                         \
> +             __preempt_count_sub(_o);                        \
> +     } while (0)

This needs to be:

#define __preempt_count_nmi_exit()                              \
        do {                                                    \
                __preempt_count_sub(HARDIRQ_OFFSET);            \
                if (!__this_cpu_dec_return(nmi_nesting))        \
                        preempt_count_set(preempt_count() & ~NMI_MASK); \
        } while (0)

otherwise we would have an underflow issue if an NMI happen between
the "if" being true and __preempt_count_sub(_o);

Regards,
Boqun

> +
> +#endif
> +
> +
[...]

Reply via email to