Re: [PATCH] serial: 8250_dw: Fix deadlock in LCR workaround

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux