Re: [PATCH v5 12/14] serial: liteuart: add IRQ support for the RX path

From: Jiri Slaby
Date: Tue Nov 22 2022 - 02:45:01 EST


On 21. 11. 22, 19:50, Gabriel L. Somlo wrote:
static void liteuart_timer(struct timer_list *t)
{
struct liteuart_port *uart = from_timer(uart, t, timer);
struct uart_port *port = &uart->port;
- liteuart_rx_chars(port);
-
+ liteuart_interrupt(0, port);

Are you sure spin_lock() is safe from this path? I assume so, but have you
thought about it?

I checked and at that point `in_serving_softirq()` is true.

*However*, after studying spin_lock() and friends for a while, I'm
not quite clear on whether that unequivocally translates
to "yes, we're safe" :)

Depends whether some hard irq context is grabbing the port lock too. If it does, it will spin forever waiting for this soft irq to finish (never happens as it was interrupted).

As such, I'm inclined to switch to `spin_lock_irqsave()` and
`spin_unlock_irqrestore()` even in the interrupt handler, which is
explicitly stated to be "safe from any context":
https://www.kernel.org/doc/html/v4.15/kernel-hacking/locking.html#cheat-sheet-for-locking



The alternative could be to set `TIMER_IRQSAFE` in `timer_setup()`,
but no other tty driver seems to be doing that, so I'd be a bit off
the beaten path there... :)

Ah, no.

Please do let me know what you think about this, particularly if you
consider going the spin_lock_irqsave-everywhere-just-to-be-safe route
overkill... :)

If you are unsure about the other contexts, irqsave/restore is the way to go. It can be lifted later, if someone investigates harder.

thanks,
--
js