serial: 8250: unlock port for uart_write_wakeup()
PATCH 1/3 serial: 8250: unlock port for uart_write_wakeup()
uart_write_wakeup() should be called without holding the port lock. Otherwise a possible recursive spinlock issue can occur, such as the following callchain:
8250_core.c:serial8250_tx_chars() - called with port locked
serial_core.c:uart_write_wakeup()
tty_io.c:tty_wakeup()
st_core.c:st_tty_wakeup()
st_core.c:st_tx_wakeup()
st_core.c:st_int_write()
serial_core.c:uart_write() - locks port--- drivers/tty/serial/8250/8250_core.c | 6 +++++- drivers/tty/serial/8250/8250_omap.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-)
drivers/tty/serial/8250/8250_core.c +5 -1
@@ -1559,8 +1559,12 @@ void serial8250_tx_chars(struct uart_8250_port *up) } }while (--count >0 ); -if (uart_circ_chars_pending (xmit) <WAKEUP_CHARS ) +if (uart_circ_chars_pending (xmit) <WAKEUP_CHARS ) { +/* do not hold lock for call to uart_write_wakeup() */ +spin_unlock (&port->lock);uart_write_wakeup (port); +spin_lock (&port->lock); + }DEBUG_INTR ("THRE..." );
drivers/tty/serial/8250/8250_omap.c +5 -1
@@ -861,8 +861,12 @@ static void omap_8250_dma_tx_complete(void *param)omap8250_restore_regs (p); } -if (uart_circ_chars_pending (xmit) <WAKEUP_CHARS ) +if (uart_circ_chars_pending (xmit) <WAKEUP_CHARS ) { +/* do not hold lock for call to uart_write_wakeup() */ +spin_unlock (&p->port.lock);uart_write_wakeup (&p->port); +spin_lock (&p->port.lock); + }if (!uart_circ_empty (xmit) && !uart_tx_stopped (&p->port)) {int ret;
Signature · 1 line
1.7.10.4
Peter Hurley
NAKQuoted 11 lines · John Ogness
uart_write_wakeup()should be called without holding the port lock. Otherwise a possible recursive spinlock issue can occur, such as the following callchain:8250_core.c:serial8250_tx_chars() - called with port locked
serial_core.c:uart_write_wakeup()
tty_io.c:tty_wakeup()
st_core.c:st_tty_wakeup()st_core.c:st_tx_wakeup() st_core.c:st_int_write() serial_core.c:uart_write() - locks port
NAK.
This is a bug in the N_TI_WL line discipline, specifically in the st_tx_wakeup() function, which cannot perform the write synchronously.
This is a common line discipline bug, and typically fixed by performing the wakeup operations from a kworker instead.
Regards,
Peter Hurley
Quoted 13 lines · Peter Hurley
Quoted 11 lines · John Ogness
uart_write_wakeup()should be called without holding the port lock. Otherwise a possible recursive spinlock issue can occur, such as the following callchain:8250_core.c:serial8250_tx_chars() - called with port locked
serial_core.c:uart_write_wakeup()
tty_io.c:tty_wakeup()
st_core.c:st_tty_wakeup()st_core.c:st_tx_wakeup() st_core.c:st_int_write() serial_core.c:uart_write() - locks port
Quoted 7 lines
NAK.
This is a bug in the
N_TI_WLline discipline, specifically in thest_tx_wakeup()function, which cannot perform the write synchronously.This is a common line discipline bug, and typically fixed by performing the wakeup operations from a kworker instead.
Also, seriously consider if you want to use that TI line discipline at all.
If you're using it only for bluetooth w/ kernel bluetooth stack, you don't need btwilink + st_drv anyway.
Regards,
Peter Hurley