]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] serial: fix low-latency mode deadlock
authorMartin Kögler <e9925248@student.tuwien.ac.at>
Mon, 7 Feb 2005 13:32:21 +0000 (05:32 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 7 Feb 2005 13:32:21 +0000 (05:32 -0800)
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

index d4e7733dbeb810ad5975f36e43078e0bc94a4e90..ec620e33fcf6fd5ff1ea1be1706e10fecfc4f1f2 100644 (file)
@@ -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;
 }