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

Jinjie Ruan
2025-10-10T04:00:06Z

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@huawei.com>
> Signed-off-by: Marc Zyngier <maz@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;