[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <87h9ol2r4y.fsf@linutronix.de>
Date: Fri, 31 Jul 2015 00:54:21 +0200
From: John Ogness <john.ogness@...utronix.de>
To: linux-kernel@...r.kernel.org
Cc: linux-serial@...r.kernel.org
Subject: [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
Signed-off-by: John Ogness <john.ogness@...utronix.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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists