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
> +
> +
[...]