watchdog/crash: Always disable watchdog in console_force_unlock()
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 13 Aug 2013 12:31:01 +0000 (14:31 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 13 Aug 2013 12:31:01 +0000 (14:31 +0200)
Depending on the state of the conring and serial_tx_buffer,
console_force_unlock() can be a long running operation, usually because of
serial_start_sync()

XenServer testing has found a reliable case where console_force_unlock() on
one PCPU takes long enough for another PCPU to timeout due to the watchdog
(such as waiting for a tlb flush callin).

The watchdog timeout causes the second PCPU to repeat the
console_force_unlock(), at which point the first PCPU typically fails an
assertion in spin_unlock_irqrestore(&port->tx_lock) (because the tx_lock has
been unlocked behind itself).

console_force_unlock() is only on emergency paths, so one way or another the
host is going down.  Disable the watchdog before forcing the console lock to
help prevent having pcpus completing with each other to bring the host down.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Keir Fraser <keir@xen.org>
xen/arch/x86/x86_64/traps.c
xen/drivers/char/console.c

index ea2ffb644b9081fd3358c9c0172473aa32405c56..1cc977c757f69ec132a93c728a7f25f4f6d26e84 100644 (file)
@@ -227,8 +227,6 @@ void do_double_fault(struct cpu_user_regs *regs)
     unsigned int cpu;
     unsigned long crs[8];
 
-    watchdog_disable();
-
     console_force_unlock();
 
     asm ( "lsll %1, %0" : "=r" (cpu) : "rm" (PER_CPU_GDT_ENTRY << 3) );
index 52ffa70ec2c2ea097d14cfdcabec38ca4b173d53..e47ddf21cce504686924da5251907275515e36e2 100644 (file)
@@ -737,6 +737,7 @@ void console_end_log_everything(void)
 
 void console_force_unlock(void)
 {
+    watchdog_disable();
     spin_lock_init(&console_lock);
     serial_force_unlock(sercon_handle);
     console_locks_busted = 1;