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

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

 



On 03/11/2015 10:29 AM, Tim Kryger wrote:
> 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.

Why?

The initial port line settings come from the console line settings
and the h/w was already initialized when the console was registered,
so ISTM the worst that could happen there is UART_TX is written with
the value intended for UART_DLL.

> The driver knows there is a problem and should try to inform the user.

Feel free to submit an alternative.

A week has gone by since the initial report without any other fixes
forthcoming, so I wanted to make sure at least _something_ addressed
it in -rc4.

Regards,
Peter Hurley
--
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