aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2007-04-23 17:41:21 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-24 11:23:09 -0400
commit4bf3631cdb012591667ab927fcd7719d92837833 (patch)
tree25976c75042f3aa557a7bc8ece781ea4901acc62
parentc5408b88ecb8b7127334a34c55d4e0174434f4ec (diff)
8250: fix possible deadlock between serial8250_handle_port() and serial8250_interrupt()
Commit 40b36daa introduced possibility that serial8250_backup_timeout() -> serial8250_handle_port() locks port.lock without disabling irqs, thus allowing deadlock against interrupt handler (port.lock is acquired in serial8250_interrupt()). Spotted by lockdep. Signed-off-by: Jiri Kosina <jkosina@suse.cz> Cc: Dave Jones <davej@codemonkey.org.uk> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Alex Williamson <alex.williamson@hp.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/serial/8250.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index c0c472ac5311..90621c3312bc 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1334,8 +1334,9 @@ static inline void
1334serial8250_handle_port(struct uart_8250_port *up) 1334serial8250_handle_port(struct uart_8250_port *up)
1335{ 1335{
1336 unsigned int status; 1336 unsigned int status;
1337 unsigned long flags;
1337 1338
1338 spin_lock(&up->port.lock); 1339 spin_lock_irqsave(&up->port.lock, flags);
1339 1340
1340 status = serial_inp(up, UART_LSR); 1341 status = serial_inp(up, UART_LSR);
1341 1342
@@ -1347,7 +1348,7 @@ serial8250_handle_port(struct uart_8250_port *up)
1347 if (status & UART_LSR_THRE) 1348 if (status & UART_LSR_THRE)
1348 transmit_chars(up); 1349 transmit_chars(up);
1349 1350
1350 spin_unlock(&up->port.lock); 1351 spin_unlock_irqrestore(&up->port.lock, flags);
1351} 1352}
1352 1353
1353/* 1354/*