* [PATCH 1/3] serial: 8250: unlock port for uart_write_wakeup()
@ 2015-07-30 22:54 John Ogness
2015-07-30 23:15 ` Peter Hurley
0 siblings, 1 reply; 3+ messages in thread
From: John Ogness @ 2015-07-30 22:54 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, Tony Lindgren, Peter Hurley,
Sebastian Andrzej Siewior, linux-omap, nsekhar
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
Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
drivers/tty/serial/8250/8250_core.c | 6 +++++-
drivers/tty/serial/8250/8250_omap.c | 6 +++++-
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 37fff12..5ac2425 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -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...");
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index d75a66c..5b39892 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -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;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 1/3] serial: 8250: unlock port for uart_write_wakeup()
2015-07-30 22:54 [PATCH 1/3] serial: 8250: unlock port for uart_write_wakeup() John Ogness
@ 2015-07-30 23:15 ` Peter Hurley
2015-07-30 23:53 ` Peter Hurley
0 siblings, 1 reply; 3+ messages in thread
From: Peter Hurley @ 2015-07-30 23:15 UTC (permalink / raw)
To: John Ogness, linux-kernel
Cc: Greg Kroah-Hartman, Tony Lindgren, Sebastian Andrzej Siewior,
linux-omap, nsekhar, nm, linux-serial
On 07/30/2015 06:54 PM, John Ogness wrote:
> 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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 1/3] serial: 8250: unlock port for uart_write_wakeup()
2015-07-30 23:15 ` Peter Hurley
@ 2015-07-30 23:53 ` Peter Hurley
0 siblings, 0 replies; 3+ messages in thread
From: Peter Hurley @ 2015-07-30 23:53 UTC (permalink / raw)
To: John Ogness
Cc: linux-kernel, Greg Kroah-Hartman, Tony Lindgren,
Sebastian Andrzej Siewior, linux-omap, nsekhar, nm, linux-serial
On 07/30/2015 07:15 PM, Peter Hurley wrote:
> On 07/30/2015 06:54 PM, John Ogness wrote:
>> 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.
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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-07-30 23:53 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-30 22:54 [PATCH 1/3] serial: 8250: unlock port for uart_write_wakeup() John Ogness
2015-07-30 23:15 ` Peter Hurley
2015-07-30 23:53 ` Peter Hurley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).