From 770b8453bdce523aaccf5845cfe8d3f9a6c9c07e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20K=C3=B6gler?= <e9925248@student.tuwien.ac.at>
Date: Mon, 7 Feb 2005 05:32:21 -0800
Subject: [PATCH] [PATCH] serial: fix low-latency mode deadlock

We presently deadlock in low-latency mode because the receive code holds
port.lock while calling into the tty code to perform echoing.  The tty code
calls back into the driver, which then takes port.lock.

Fix that by dropping the lock around the echo call.

Acked-by: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
 drivers/serial/8250.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index d4e7733dbeb8..ec620e33fcf6 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -987,8 +987,11 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
 		/* The following is not allowed by the tty layer and
 		   unsafe. It should be fixed ASAP */
 		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-			if(tty->low_latency)
+			if (tty->low_latency) {
+				spin_unlock(&up->port.lock);
 				tty_flip_buffer_push(tty);
+				spin_lock(&up->port.lock);
+			}
 			/* If this failed then we will throw away the
 			   bytes but must do so to clear interrupts */
 		}
@@ -1059,7 +1062,9 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
 	ignore_char:
 		lsr = serial_inp(up, UART_LSR);
 	} while ((lsr & UART_LSR_DR) && (max_count-- > 0));
+	spin_unlock(&up->port.lock);
 	tty_flip_buffer_push(tty);
+	spin_lock(&up->port.lock);
 	*status = lsr;
 }
 
-- 
2.30.9