diff options
author | Jiri Kosina <jkosina@suse.cz> | 2007-04-23 17:41:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-24 11:23:09 -0400 |
commit | 4bf3631cdb012591667ab927fcd7719d92837833 (patch) | |
tree | 25976c75042f3aa557a7bc8ece781ea4901acc62 /drivers/serial/8250.c | |
parent | c5408b88ecb8b7127334a34c55d4e0174434f4ec (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>
Diffstat (limited to 'drivers/serial/8250.c')
-rw-r--r-- | drivers/serial/8250.c | 5 |
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 | |||
1334 | serial8250_handle_port(struct uart_8250_port *up) | 1334 | serial8250_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 | /* |