Message ID | 20180508085509.31384-1-wagi@monom.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, May 8, 2018 at 10:55 AM, Daniel Wagner <wagi@monom.org> wrote: > From: Daniel Wagner <daniel.wagner@siemens.com> > > Commit 40f70c03e33a ("serial: sh-sci: add locking to console write > function to avoid SMP lockup") copied the strategy to avoid locking > problems in conjuncture with the console from the UART8250 > driver. Instead using directly spin_{try}lock_irqsave(), > local_irq_save() followed by spin_{try}lock() was used. While this is > correct on mainline, for -rt it is a problem. spin_{try}lock() will > check if it is running in a valid context. Since the local_irq_save() > has already been executed, the context has changed and > spin_{try}lock() will complain. The reason why spin_{try}lock() > complains is that on -rt the spin locks are turned into mutexes and > therefore can sleep. Sleeping with interrupts disabled is not valid. [...] > Cc: Geert Uytterhoeven <geert@linux-m68k.org> > Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> > Signed-off-by: Daniel Wagner <daniel.wagner@siemens.com> > --- > changes since v2: > - dropped the local_irq_save() it's wrong as Sebastian pointed out > > changes since v1: > - Ported to current mainline (initial version was against v4.4.y) > - Left local_irq_save() in place when spinlocks are not used as suggested > by Geert. Thanks for the update! Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Gr{oetje,eeting}s, Geert
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index fdbbff547106..8c8dcced1c25 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2890,16 +2890,15 @@ static void serial_console_write(struct console *co, const char *s, unsigned long flags; int locked = 1; - local_irq_save(flags); #if defined(SUPPORT_SYSRQ) if (port->sysrq) locked = 0; else #endif if (oops_in_progress) - locked = spin_trylock(&port->lock); + locked = spin_trylock_irqsave(&port->lock, flags); else - spin_lock(&port->lock); + spin_lock_irqsave(&port->lock, flags); /* first save SCSCR then disable interrupts, keep clock source */ ctrl = serial_port_in(port, SCSCR); @@ -2919,8 +2918,7 @@ static void serial_console_write(struct console *co, const char *s, serial_port_out(port, SCSCR, ctrl); if (locked) - spin_unlock(&port->lock); - local_irq_restore(flags); + spin_unlock_irqrestore(&port->lock, flags); } static int serial_console_setup(struct console *co, char *options)