Re: [PATCH] gpio: siox: indicate exclusive support of threaded IRQs

From: Thomas Gleixner
Date: Thu Aug 06 2020 - 14:51:02 EST


Linus Walleij <linus.walleij@xxxxxxxxxx> writes:
> On Thu, Aug 6, 2020 at 12:20 PM Thomas Gleixner <tglx@xxxxxxxxxxxxx> wrote:
>
>> So the solution for this driver is either to make the dispatch handler
>> threaded or use the hard interrupt variant of dispatching the
>> demultiplexed GPIO interrupts.
>
> The struct gpio_irq_chip .threaded bool that the patch
> sets just instructs the gpio core to issue
> irq_set_nested_thread(irq, 1) on the child IRQ.
>
> This is a driver of type "struct siox_driver" handling the
> IRQ through the special .get_data callback supplied in the
> driver struct and it calls handle_nested_irq(irq) so with
> this fix it percolated up to the parent as intended.
>
> So far so good. So I think the patch should be applied.
>
> But what is behind this .get_data() callback for siox drivers?
>
> The siox driver framework in drivers/siox dispatches calls
> to .get_data() from a polling thread which is just some ordinary
> kthread. It looks like this because the SIOX (I think) needs
> to do polled I/O. (drivers/siox/siox-core.c)
>
> So this is a thread but it is not an irq thread from the irq core,
> however it is treated like such by the driver, and in a way what
> happens is events, just polled by a thread.

As Uwe just explained.

> So when we call handle_nested_irq() ... we are not really
> calling that from an irq handler.
>
> I don't know if the IRQ core even sees a difference between which
> thread it gets interfaced with. I suppose it does? :/

handle_nested_irq() does not care. It cares about thread context,
external reentrancy protection for the same nested interrupt and that
the nested interrupt has a thread handler.

The latter is what goes belly up because w/o that threaded bit set the
GPIO core fails to set nested thread. So if a consumer requests an
interrupt with request_any_context_irq() then that fails to select
thread mode which means the threaded handler is not set causing
handle_nested_irq() to fail.

The polling kthread is a slight but clever abomination, but it just
works because it provides thread context and cannot run concurrently.

So Ahmad's patch is correct, just the changelog needs polishing.

Thanks,

tglx