On Fri, Feb 20, 2026 at 5:28 PM Jisheng Zhang <[email protected]> wrote:
>
> Currently, on GENERIC_IRQ_MULTI_HANDLER platforms, the handle_arch_irq
> is a pointer which is set during booting, and every irq processing needs
> to access it, so it sits in hot code path. We can use the
> runtime constant mechanism which was introduced by Linus to speed up
> its accessing.
>
> Tested on Sipeed Lichee Pi 4A (riscv64) board, the perf sched benchmark is
> improved by ~5.8%
Thx for the work. It's a visible improvement.

Compared to the original handler pointer approach, this solution
introduces no observable drawbacks. Since the static_call alternative
requires further analysis and consensus, adopting this implementation
serves as a pragmatic interim step.

So, I give:
Reviewed-by: Guo Ren (Alibaba Damo Academy) <[email protected]>

>
> Signed-off-by: Jisheng Zhang <[email protected]>
> ---
>  include/linux/irq.h | 4 +++-
>  kernel/irq/handle.c | 8 +++++---
>  2 files changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/irq.h b/include/linux/irq.h
> index 951acbdb9f84..2ba4a8afb71e 100644
> --- a/include/linux/irq.h
> +++ b/include/linux/irq.h
> @@ -1274,6 +1274,7 @@ void ipi_mux_process(void);
>  int ipi_mux_create(unsigned int nr_ipi, void (*mux_send)(unsigned int cpu));
>
>  #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
> +#include <asm/runtime-const.h>
>  /*
>   * Registers a generic IRQ handling function as the top-level IRQ handler in
>   * the system, which is generally the first C code called from an assembly
> @@ -1288,7 +1289,8 @@ int __init set_handle_irq(void (*handle_irq)(struct 
> pt_regs *));
>   * Allows interrupt handlers to find the irqchip that's been registered as 
> the
>   * top-level IRQ handler.
>   */
> -extern void (*handle_arch_irq)(struct pt_regs *) __ro_after_init;
> +extern void (*_handle_arch_irq)(struct pt_regs *) __ro_after_init;
> +#define handle_arch_irq runtime_const_ptr(_handle_arch_irq)
>  asmlinkage void generic_handle_arch_irq(struct pt_regs *regs);
>  #else
>  #ifndef set_handle_irq
> diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
> index b7d52821837b..aac9e7b1301e 100644
> --- a/kernel/irq/handle.c
> +++ b/kernel/irq/handle.c
> @@ -15,13 +15,14 @@
>  #include <linux/kernel_stat.h>
>
>  #include <asm/irq_regs.h>
> +#include <asm/runtime-const.h>
>
>  #include <trace/events/irq.h>
>
>  #include "internals.h"
>
>  #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
> -void (*handle_arch_irq)(struct pt_regs *) __ro_after_init;
> +void (*_handle_arch_irq)(struct pt_regs *) __ro_after_init;
>  #endif
>
>  /**
> @@ -270,10 +271,11 @@ irqreturn_t handle_irq_event(struct irq_desc *desc)
>  #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
>  int __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
>  {
> -       if (handle_arch_irq)
> +       if (_handle_arch_irq)
>                 return -EBUSY;
>
> -       handle_arch_irq = handle_irq;
> +       _handle_arch_irq = handle_irq;
> +       runtime_const_init(ptr, _handle_arch_irq);
>         return 0;
>  }
>
> --
> 2.51.0
>


-- 
Best Regards
 Guo Ren

Reply via email to