Re: [patch V2 12/45] genirq/chip: Rework handle_nested_irq()

Marek Szyprowski
2025-05-08T20:56:37Z

On 29.04.2025 08:55, Thomas Gleixner wrote:
> Use the new helpers to decide whether the interrupt should be handled and
> switch the descriptor locking to guard().
>
> Fixup the kernel doc comment while at it.
>
> No functional change.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>
> ---
> kernel/irq/chip.c | 78 ++++++++++++++++++++++++------------------------------
> 1 file changed, 36 insertions(+), 42 deletions(-)
>
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -450,48 +450,6 @@ void unmask_threaded_irq(struct irq_desc
> unmask_irq(desc);
> }
>
> -/*
> - * handle_nested_irq - Handle a nested irq from a irq thread
> - * @irq: the interrupt number
> - *
> - * Handle interrupts which are nested into a threaded interrupt
> - * handler. The handler function is called inside the calling
> - * threads context.
> - */
> -void handle_nested_irq(unsigned int irq)
> -{
> - struct irq_desc *desc = irq_to_desc(irq);
> - struct irqaction *action;
> - irqreturn_t action_ret;
> -
> - might_sleep();
> -
> - raw_spin_lock_irq(&desc->lock);
> -
> - desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
> -
> - action = desc->action;
> - if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) {
> - desc->istate |= IRQS_PENDING;
> - raw_spin_unlock_irq(&desc->lock);
> - return;
> - }
> -
> - kstat_incr_irqs_this_cpu(desc);
> - atomic_inc(&desc->threads_active);
> - raw_spin_unlock_irq(&desc->lock);
> -
> - action_ret = IRQ_NONE;
> - for_each_action_of_desc(desc, action)
> - action_ret |= action->thread_fn(action->irq, action->dev_id);
> -
> - if (!irq_settings_no_debug(desc))
> - note_interrupt(desc, action_ret);
> -
> - wake_threads_waitq(desc);
> -}
> -EXPORT_SYMBOL_GPL(handle_nested_irq);
> -
> static bool irq_check_poll(struct irq_desc *desc)
> {
> if (!(desc->istate & IRQS_POLL_INPROGRESS))
> @@ -544,6 +502,42 @@ static inline bool irq_can_handle(struct
> }
>
> /**
> + * handle_nested_irq - Handle a nested irq from a irq thread
> + * @irq: the interrupt number
> + *
> + * Handle interrupts which are nested into a threaded interrupt
> + * handler. The handler function is called inside the calling threads
> + * context.
> + */
> +void handle_nested_irq(unsigned int irq)
> +{
> + struct irq_desc *desc = irq_to_desc(irq);
> + struct irqaction *action;
> + irqreturn_t action_ret;
> +
> + might_sleep();
> +
> + scoped_guard(raw_spinlock_irq, &desc->lock) {
> + if (irq_can_handle_actions(desc))

This should be "if (!irq_can_handle_actions(desc))" to fix nested irqs handling in today's linux-next.

> + return;
> +
> + action = desc->action;
> + kstat_incr_irqs_this_cpu(desc);
> + atomic_inc(&desc->threads_active);
> + }
> +
> + action_ret = IRQ_NONE;
> + for_each_action_of_desc(desc, action)
> + action_ret |= action->thread_fn(action->irq, action->dev_id);
> +
> + if (!irq_settings_no_debug(desc))
> + note_interrupt(desc, action_ret);
> +
> + wake_threads_waitq(desc);
> +}
> +EXPORT_SYMBOL_GPL(handle_nested_irq);
> +
> +/**
> * handle_simple_irq - Simple and software-decoded IRQs.
> * @desc: the interrupt description structure for this irq
> *
>
>
>
>
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland