]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
serial 8250: sysrq deadlock fix
authorAndrew Morton <akpm@osdl.org>
Fri, 7 Jul 2006 06:59:50 +0000 (23:59 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 25 Jul 2006 03:35:28 +0000 (20:35 -0700)
Fix http://bugzilla.kernel.org/show_bug.cgi?id=6716

Doing a sysrq over a serial line into an SMP machine presently deadlocks.

Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/serial/8250.c

index bbf78aaf9e01f074d15bf6db21042feb9dec5591..3863eba67984dfa1802136850661e67fa4b5d69c 100644 (file)
@@ -2241,10 +2241,14 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
 
        touch_nmi_watchdog();
 
-       if (oops_in_progress) {
-               locked = spin_trylock_irqsave(&up->port.lock, flags);
+       local_irq_save(flags);
+       if (up->port.sysrq) {
+               /* serial8250_handle_port() already took the lock */
+               locked = 0;
+       } else if (oops_in_progress) {
+               locked = spin_trylock(&up->port.lock);
        } else
-               spin_lock_irqsave(&up->port.lock, flags);
+               spin_lock(&up->port.lock);
 
        /*
         *      First save the IER then disable the interrupts
@@ -2266,7 +2270,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
        serial_out(up, UART_IER, ier);
 
        if (locked)
-               spin_unlock_irqrestore(&up->port.lock, flags);
+               spin_unlock(&up->port.lock);
+       local_irq_restore(flags);
 }
 
 static int serial8250_console_setup(struct console *co, char *options)