On Wed, Mar 11, 2015 at 6:19 AM, Peter Hurley <peter@xxxxxxxxxxxxxxxxxx> wrote: > Trying to write console output from within the serial console driver > while the port->lock is held causes recursive deadlock: > > CPU 0 > spin_lock_irqsave(&port->lock) > printk() > console_unlock() > call_console_drivers() > serial8250_console_write() > spin_lock_irqsave(&port->lock) > ** DEADLOCK ** > > The 8250_dw i/o accessors try to write a console error message if the > LCR workaround was unsuccessful. When the port->lock is already held > (eg., when called from serial8250_set_termios()), this deadlocks. > > Make the error message a FIXME until a general solution is devised. > > Cc: Tim Kryger <tim.kryger@xxxxxxxxx> > Reported-by: Zhang Zhen <zhenzhang.zhang@xxxxxxxxxx> > Signed-off-by: Peter Hurley <peter@xxxxxxxxxxxxxxxxxx> > --- > drivers/tty/serial/8250/8250_dw.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c > index f7f5371..48a8bef 100644 > --- a/drivers/tty/serial/8250/8250_dw.c > +++ b/drivers/tty/serial/8250/8250_dw.c > @@ -119,7 +119,10 @@ static void dw8250_serial_out(struct uart_port *p, int offset, int value) > dw8250_force_idle(p); > writeb(value, p->membase + (UART_LCR << p->regshift)); > } > - dev_err(p->dev, "Couldn't set LCR to %d\n", value); > + /* > + * FIXME: this deadlocks if port->lock is already held > + * dev_err(p->dev, "Couldn't set LCR to %d\n", value); > + */ > } > } > > @@ -163,7 +166,10 @@ static void dw8250_serial_outq(struct uart_port *p, int offset, int value) > __raw_writeq(value & 0xff, > p->membase + (UART_LCR << p->regshift)); > } > - dev_err(p->dev, "Couldn't set LCR to %d\n", value); > + /* > + * FIXME: this deadlocks if port->lock is already held > + * dev_err(p->dev, "Couldn't set LCR to %d\n", value); > + */ > } > } > #endif /* CONFIG_64BIT */ > @@ -187,7 +193,10 @@ static void dw8250_serial_out32(struct uart_port *p, int offset, int value) > dw8250_force_idle(p); > writel(value, p->membase + (UART_LCR << p->regshift)); > } > - dev_err(p->dev, "Couldn't set LCR to %d\n", value); > + /* > + * FIXME: this deadlocks if port->lock is already held > + * dev_err(p->dev, "Couldn't set LCR to %d\n", value); > + */ > } > } > > -- > 2.3.2 > Why hide this valuable message when the uart port is not the console? In cases where it prints, the uart has likely become non-functional. The driver knows there is a problem and should try to inform the user. -Tim -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html