mbox series

[0/7] Provide and use generic_handle_irq_safe() where appropriate.

Message ID 20220127113303.3012207-1-bigeasy@linutronix.de
Headers show
Series Provide and use generic_handle_irq_safe() where appropriate. | expand

Message

Sebastian Andrzej Siewior Jan. 27, 2022, 11:32 a.m. UTC
generic_handle_irq() must be used from primary IRQ-handler (chain
handler/ interrupt controller entry). It is low level code and the
function expects that interrupts are disabled at entry point.

This isn't the case for invocations from tasklets, workqueues or the
primary interrupt handler on PREEMPT_RT. Once this gets noticed a
"local_irq_disable|safe()" is added. To avoid further confusion this
series adds generic_handle_irq_safe() which can be used from any context
and adds a few user.

Sebastian

Comments

Oleksandr Natalenko Jan. 27, 2022, 2:41 p.m. UTC | #1
Hello.

On čtvrtek 27. ledna 2022 12:32:58 CET Sebastian Andrzej Siewior wrote:
> The i2c-i801 driver invokes i2c_handle_smbus_host_notify() from his
> interrupt service routine. On PREEMPT_RT i2c-i801's handler is forced
> threaded with enabled interrupts which leads to a warning by
> handle_irq_event_percpu() assuming that irq_default_primary_handler()
> enabled interrupts.
> 
> i2c-i801's interrupt handler can't be made non-threaded because the
> interrupt line is shared with other devices.
> 
> Use generic_handle_irq_safe() which can invoked with disabled and enabled
> interrupts.
> 
> Reported-by: Michael Below <below@judiz.de>
> Link: https://bugs.debian.org/1002537
> Cc: Salvatore Bonaccorso <carnil@debian.org>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>  drivers/i2c/i2c-core-base.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index 2c59dd748a49f..3f9e5303b6163 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -1424,7 +1424,7 @@ int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr)
>  	if (irq <= 0)
>  		return -ENXIO;
>  
> -	generic_handle_irq(irq);
> +	generic_handle_irq_safe(irq);
>  
>  	return 0;
>  }
> 

Reviewed-by: Oleksandr Natalenko <oleksandr@natalenko.name>

Worth linking [1] [2] and [3] as well maybe?

[1] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1873673
[2] https://bugzilla.kernel.org/show_bug.cgi?id=202453
[3] https://lore.kernel.org/lkml/20201204201930.vtvitsq6xcftjj3o@spock.localdomain/
Wolfram Sang Jan. 27, 2022, 5:11 p.m. UTC | #2
On Thu, Jan 27, 2022 at 12:32:58PM +0100, Sebastian Andrzej Siewior wrote:
> The i2c-i801 driver invokes i2c_handle_smbus_host_notify() from his
> interrupt service routine. On PREEMPT_RT i2c-i801's handler is forced
> threaded with enabled interrupts which leads to a warning by
> handle_irq_event_percpu() assuming that irq_default_primary_handler()
> enabled interrupts.
> 
> i2c-i801's interrupt handler can't be made non-threaded because the
> interrupt line is shared with other devices.
> 
> Use generic_handle_irq_safe() which can invoked with disabled and enabled
> interrupts.
> 
> Reported-by: Michael Below <below@judiz.de>
> Link: https://bugs.debian.org/1002537
> Cc: Salvatore Bonaccorso <carnil@debian.org>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

I guess you want this to go together with patch 1, so:

Acked-by: Wolfram Sang <wsa@kernel.org>

I agree with adding the kernel bugzilla entry at least:

https://bugzilla.kernel.org/show_bug.cgi?id=202453

Probably the others which Oleksandr metioned, too.
Sergei Shtylyov Jan. 28, 2022, 10:23 a.m. UTC | #3
On 1/27/22 2:33 PM, Sebastian Andrzej Siewior wrote:

> generic_handle_irq() is invoked from a regular interrupt service
> routing. This handler will become a forced-threaded handler on

   s/routing/routine/?

> PREEMPT_RT and will be invoked with enabled interrupts. The
> generic_handle_irq() must be invoked with disabled interrupts in order
> to avoid deadlocks.
> 
> Instead of manually disabling interrupts before invoking use
> generic_handle_irq() which can be invoked with enabled and disabled
> interrupts.
> 
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
[...]

MBR, Sergey
Lee Jones Jan. 28, 2022, 1:33 p.m. UTC | #4
On Fri, 28 Jan 2022, Sergei Shtylyov wrote:

> On 1/27/22 2:33 PM, Sebastian Andrzej Siewior wrote:
> 
> > generic_handle_irq() is invoked from a regular interrupt service
> > routing. This handler will become a forced-threaded handler on
> 
>    s/routing/routine/?
> 
> > PREEMPT_RT and will be invoked with enabled interrupts. The
> > generic_handle_irq() must be invoked with disabled interrupts in order
> > to avoid deadlocks.
> > 
> > Instead of manually disabling interrupts before invoking use
> > generic_handle_irq() which can be invoked with enabled and disabled
> > interrupts.
> > 
> > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> [...]
> 
> MBR, Sergey

What does that mean?
Sergei Shtylyov Jan. 28, 2022, 3:28 p.m. UTC | #5
On 1/28/22 4:33 PM, Lee Jones wrote:

>>> generic_handle_irq() is invoked from a regular interrupt service
>>> routing. This handler will become a forced-threaded handler on
>>
>>    s/routing/routine/?
>>
>>> PREEMPT_RT and will be invoked with enabled interrupts. The
>>> generic_handle_irq() must be invoked with disabled interrupts in order
>>> to avoid deadlocks.
>>>
>>> Instead of manually disabling interrupts before invoking use
>>> generic_handle_irq() which can be invoked with enabled and disabled
>>> interrupts.
>>>
>>> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
>> [...]
>>
>> MBR, Sergey
> 
> What does that mean?

   That means that I think you had a typo in the word "routing".
The s/// comes from vim, I think --where it means search and replace.

MBR, Sergey
Sergei Shtylyov Jan. 28, 2022, 4:44 p.m. UTC | #6
On 1/28/22 4:33 PM, Lee Jones wrote:

>>> generic_handle_irq() is invoked from a regular interrupt service
>>> routing. This handler will become a forced-threaded handler on
>>
>>    s/routing/routine/?
>>
>>> PREEMPT_RT and will be invoked with enabled interrupts. The
>>> generic_handle_irq() must be invoked with disabled interrupts in order
>>> to avoid deadlocks.
>>>
>>> Instead of manually disabling interrupts before invoking use
>>> generic_handle_irq() which can be invoked with enabled and disabled
>>> interrupts.
>>>
>>> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
>> [...]
>>
>> MBR, Sergey
> 
> What does that mean?

   Ah, you were asking about MBR! My best regards then. :-)

MBR, Sergey
Lee Jones Jan. 28, 2022, 4:50 p.m. UTC | #7
On Fri, 28 Jan 2022, Sergei Shtylyov wrote:

> On 1/28/22 4:33 PM, Lee Jones wrote:
> 
> >>> generic_handle_irq() is invoked from a regular interrupt service
> >>> routing. This handler will become a forced-threaded handler on
> >>
> >>    s/routing/routine/?
> >>
> >>> PREEMPT_RT and will be invoked with enabled interrupts. The
> >>> generic_handle_irq() must be invoked with disabled interrupts in order
> >>> to avoid deadlocks.
> >>>
> >>> Instead of manually disabling interrupts before invoking use
> >>> generic_handle_irq() which can be invoked with enabled and disabled
> >>> interrupts.
> >>>
> >>> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> >> [...]
> >>
> >> MBR, Sergey
> > 
> > What does that mean?
> 
>    Ah, you were asking about MBR! My best regards then. :-)

Yes this.  It's okay, Dan was kind enough to enlighten me.

Every day is a school day on the list! :)
Sergei Shtylyov Jan. 28, 2022, 7:37 p.m. UTC | #8
On 1/28/22 7:50 PM, Lee Jones wrote:

[...]
>>>>> generic_handle_irq() is invoked from a regular interrupt service
>>>>> routing. This handler will become a forced-threaded handler on
>>>>
>>>>    s/routing/routine/?
>>>>
>>>>> PREEMPT_RT and will be invoked with enabled interrupts. The
>>>>> generic_handle_irq() must be invoked with disabled interrupts in order
>>>>> to avoid deadlocks.
>>>>>
>>>>> Instead of manually disabling interrupts before invoking use
>>>>> generic_handle_irq() which can be invoked with enabled and disabled
>>>>> interrupts.
>>>>>
>>>>> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
>>>> [...]
>>>>
>>>> MBR, Sergey
>>>
>>> What does that mean?
>>
>>    Ah, you were asking about MBR! My best regards then. :-)
> 
> Yes this.  It's okay, Dan was kind enough to enlighten me.
> 
> Every day is a school day on the list! :)

   It's not exactly a well known phrase, I like it mainly because it also stands
for the Master Boot Record. :-)

MBR, Sergey
Sebastian Andrzej Siewior Jan. 31, 2022, 11:07 a.m. UTC | #9
On 2022-01-27 18:11:16 [+0100], Wolfram Sang wrote:
> 
> I guess you want this to go together with patch 1, so:
> 
> Acked-by: Wolfram Sang <wsa@kernel.org>
> 
> I agree with adding the kernel bugzilla entry at least:
> 
> https://bugzilla.kernel.org/show_bug.cgi?id=202453
> 
> Probably the others which Oleksandr metioned, too.

No, they are not relevant because none of them can be reproduced on a
v5.12+ kernel or any of <v5.12 stable maintained trees.

They triggered in the past only with the `threadirqs' option on the
commandline and this has been fixed by commit
   81e2073c175b8 ("genirq: Disable interrupts for force threaded handlers")

Sebastian
Sebastian Andrzej Siewior Jan. 31, 2022, 11:09 a.m. UTC | #10
On 2022-01-27 15:41:24 [+0100], Oleksandr Natalenko wrote:
> Hello.
Hi,

> Reviewed-by: Oleksandr Natalenko <oleksandr@natalenko.name>
> 
> Worth linking [1] [2] and [3] as well maybe?

no, they are fixed since commit
   81e2073c175b8 ("genirq: Disable interrupts for force threaded handlers")

> [1] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1873673
> [2] https://bugzilla.kernel.org/show_bug.cgi?id=202453
> [3] https://lore.kernel.org/lkml/20201204201930.vtvitsq6xcftjj3o@spock.localdomain/

Sebastian
Sebastian Andrzej Siewior Jan. 31, 2022, 11:16 a.m. UTC | #11
On 2022-01-28 13:23:08 [+0300], Sergei Shtylyov wrote:
> On 1/27/22 2:33 PM, Sebastian Andrzej Siewior wrote:
> 
> > generic_handle_irq() is invoked from a regular interrupt service
> > routing. This handler will become a forced-threaded handler on
> 
>    s/routing/routine/?

Yes, thank you.

Sebastian