Re: [PATCH] locking: Revert switching guards to _irq_{disable,enable}()

From: Boqun Feng

Date: Sat Aug 29 2026 - 19:37:47 EST


On Sat, Aug 29, 2026 at 01:11:56AM +0200, Thomas Gleixner wrote:
[...]
> +static __always_inline unsigned long __raw_local_irq_save(void)
> +{
> + unsigned int cnt = preempt_count() & HARDIRQ_DISABLE_MASK;
> +
> + debug_assert(cnt != HARDIRQ_DISABLE_MASK);
> +
> + if (!cnt)
> + arch_local_irq_disable();
> + __preempt_count_add(HARDIRQ_DISABLE_OFFSET);
> +
> + return cnt;
> +}
> +
> +static __always_inline void __raw_local_irq_restore(unsigned long cnt)
> +{
> + debug_assert((preempt_count() & HARDIRQ_DISABLE_MASK) == (cnt + HARDIRQ_DISABLE_OFFSET));
> +
> + if (!(__preempt_count_sub_return(HARDIRQ_DISABLE_OFFSET) & HARDIRQ_DISABLE_MASK))
> + arch_local_irq_enable();
> +}

And while we are at, we can just introduce a
raw_local_irq_restore_auto() (definitely needs a better name), which
doesn't need a cnt:

static __always_inline void __raw_local_irq_restore_auto(void)
{
debug_assert((preempt_count() & HARDIRQ_DISABLE_MASK));

if (!(__preempt_count_sub_return(HARDIRQ_DISABLE_OFFSET) & HARDIRQ_DISABLE_MASK))
arch_local_irq_enable();
}

And we can slowly convert irq_restore() users to use it?

Regards,
Boqun

> +
> +static __always_inline unsigned long __raw_local_save_flags(void)
> +{
> + return preempt_count() & HARDIRQ_DISABLE_MASK;
> +}
> +
> +static __always_inline bool __raw_irqs_disabled_flags(unsigned long cnt)
> +{
> + return !!cnt;
> +}
> +
> +static __always_inline bool raw_irqs_disabled(void)
> +{
> + return preempt_count() & HARDIRQ_DISABLE_MASK;
> +}
> +
> +static __always_inline void raw_safe_halt(void)
> +{
> + debug_assert((preempt_count() & HARDIRQ_DISABLE_MASK) == HARDIRQ_DISABLE_OFFSET);
> + __preempt_count_sub(HARDIRQ_DISABLE_OFFSET);
> + arch_safe_halt();
> +}
> +
> +#else
[..]