[PATCH v3 13/26] genirq: Factor-in percpu irqaction creation

Jinjie Ruan ruanjinjie at huawei.com
Thu Oct 9 20:59:59 PDT 2025



On 2025/9/22 16:28, Marc Zyngier wrote:
> Move the code creating a per-cpu irqaction into its own helper, so that
> future changes to this code can be kept localised.
> 
> At the same time, fix the documentation which appears to say the wrong
> thing when it comes to interrupts being automatically enabled
> (percpu_devid interrupts never are).
> 
> Reviewed-by: Jonathan Cameron <jonathan.cameron at huawei.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  kernel/irq/manage.c | 40 ++++++++++++++++++++++++----------------
>  1 file changed, 24 insertions(+), 16 deletions(-)
> 
> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
> index c94837382037e..d9ddc30678b5d 100644
> --- a/kernel/irq/manage.c
> +++ b/kernel/irq/manage.c
> @@ -2442,6 +2442,24 @@ int setup_percpu_irq(unsigned int irq, struct irqaction *act)
>  	return retval;
>  }
>  
> +static
> +struct irqaction *create_percpu_irqaction(irq_handler_t handler, unsigned long flags,
> +					  const char *devname, void __percpu *dev_id)
> +{
> +	struct irqaction *action;
> +
> +	action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
> +	if (!action)
> +		return NULL;
> +
> +	action->handler = handler;
> +	action->flags = flags | IRQF_PERCPU | IRQF_NO_SUSPEND;
> +	action->name = devname;
> +	action->percpu_dev_id = dev_id;
> +
> +	return action;
> +}

This helper could be more universal by consider by distinguishing dev_id
and percpu_dev_id, so we can use it in request_nmi() and
request_threaded_irq() .

> +
>  /**
>   * __request_percpu_irq - allocate a percpu interrupt line
>   * @irq:	Interrupt line to allocate
> @@ -2450,9 +2468,9 @@ int setup_percpu_irq(unsigned int irq, struct irqaction *act)
>   * @devname:	An ascii name for the claiming device
>   * @dev_id:	A percpu cookie passed back to the handler function
>   *
> - * This call allocates interrupt resources and enables the interrupt on the
> - * local CPU. If the interrupt is supposed to be enabled on other CPUs, it
> - * has to be done on each CPU using enable_percpu_irq().
> + * This call allocates interrupt resources, but doesn't enable the interrupt
> + * on any CPU, as all percpu-devid interrupts are flagged with IRQ_NOAUTOEN.
> + * It has to be done on each CPU using enable_percpu_irq().
>   *
>   * @dev_id must be globally unique. It is a per-cpu variable, and
>   * the handler gets called with the interrupted CPU's instance of
> @@ -2477,15 +2495,10 @@ int __request_percpu_irq(unsigned int irq, irq_handler_t handler,
>  	if (flags && flags != IRQF_TIMER)
>  		return -EINVAL;
>  
> -	action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
> +	action = create_percpu_irqaction(handler, flags, devname, dev_id);
>  	if (!action)
>  		return -ENOMEM;
>  
> -	action->handler = handler;
> -	action->flags = flags | IRQF_PERCPU | IRQF_NO_SUSPEND;
> -	action->name = devname;
> -	action->percpu_dev_id = dev_id;
> -
>  	retval = irq_chip_pm_get(&desc->irq_data);
>  	if (retval < 0) {
>  		kfree(action);
> @@ -2546,16 +2559,11 @@ int request_percpu_nmi(unsigned int irq, irq_handler_t handler,
>  	if (irq_is_nmi(desc))
>  		return -EINVAL;
>  
> -	action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
> +	action = create_percpu_irqaction(handler, IRQF_NO_THREAD | IRQF_NOBALANCING,
> +					 name, dev_id);
>  	if (!action)
>  		return -ENOMEM;
>  
> -	action->handler = handler;
> -	action->flags = IRQF_PERCPU | IRQF_NO_SUSPEND | IRQF_NO_THREAD
> -		| IRQF_NOBALANCING;
> -	action->name = name;
> -	action->percpu_dev_id = dev_id;
> -
>  	retval = irq_chip_pm_get(&desc->irq_data);
>  	if (retval < 0)
>  		goto err_out;



More information about the linux-arm-kernel mailing list