[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IOEMU] Fix Linux smp guest hangs with complaint "BUG: soft lock detected on CPU#0"



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID f516774cbb27d63aeaeb65085a73bb016e10c037
# Parent  b1d436f094faa1a681f94497ddf6a84b15e7d493
[IOEMU] Fix Linux smp guest hangs with complaint "BUG: soft lock detected on 
CPU#0"

When console=ttyS0 in guest grub configuration and serial='pty' in vmx
configure file. The root cause to this bug is the characteristic of
PTY emulator in Qemu. PTY has write/read end with some buffer. Write
to a buffer will be failed after the buffer is full until read end
reads the data from buffer.

Previous to changeset 12026, write to serial port would fail quietly
when buffer for pty is full. With changeset 12026, write to serial
port would retry 3 times in 300ms if failed, even without notifying
guest using serial irq. Smp guest will hang, waiting for an
interrupt. For SMP guest, a watchdog thread should be executed
periodically, otherwise soft lockup is detected. With this patch, an
upper threshold of total consecutive retries is added and serial
interrupt would be sent after retry 3 times for each write request,
even if failed.

Signed-off-by: Xinmei Huang <xinmei.huang@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/ioemu/hw/serial.c |   26 ++++++++++++++++++++------
 1 files changed, 20 insertions(+), 6 deletions(-)

diff -r b1d436f094fa -r f516774cbb27 tools/ioemu/hw/serial.c
--- a/tools/ioemu/hw/serial.c   Sat Nov 11 01:40:16 2006 +0000
+++ b/tools/ioemu/hw/serial.c   Mon Nov 13 09:46:05 2006 +0000
@@ -73,6 +73,11 @@
 #define UART_LSR_OE    0x02    /* Overrun error indicator */
 #define UART_LSR_DR    0x01    /* Receiver data ready */
 
+/* Maximum retries for a single byte transmit. */
+#define WRITE_MAX_SINGLE_RETRIES 3
+/* Maximum retries for a sequence of back-to-back unsuccessful transmits. */
+#define WRITE_MAX_TOTAL_RETRIES 10
+
 struct SerialState {
     uint8_t divider;
     uint8_t rbr; /* receive register */
@@ -98,8 +103,12 @@ struct SerialState {
      * If a character transmitted via UART cannot be written to its
      * destination immediately we remember it here and retry a few times via
      * a polling timer.
+     *  - write_single_retries: Number of write retries for current byte.
+     *  - write_total_retries:  Number of write retries for back-to-back
+     *                          unsuccessful transmits.
      */
-    int write_retries;
+    int write_single_retries;
+    int write_total_retries;
     char write_chr;
     QEMUTimer *write_retry_timer;
 };
@@ -217,16 +226,21 @@ static void serial_chr_write(void *opaqu
 {
     SerialState *s = opaque;
 
+    /* Cancel any outstanding retry if this is a new byte. */
     qemu_del_timer(s->write_retry_timer);
 
     /* Retry every 100ms for 300ms total. */
     if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) {
-        if (s->write_retries++ >= 3)
-            printf("serial: write error\n");
-        else
+        s->write_total_retries++; 
+        if (s->write_single_retries++ >= WRITE_MAX_SINGLE_RETRIES)
+            fprintf(stderr, "serial: write error\n");
+        else if (s->write_total_retries <= WRITE_MAX_TOTAL_RETRIES) {
             qemu_mod_timer(s->write_retry_timer,
                            qemu_get_clock(vm_clock) + ticks_per_sec / 10);
-        return;
+            return;
+        }
+    } else {
+        s->write_total_retries = 0;  /* if successful then reset counter */
     }
 
     /* Success: Notify guest that THR is empty. */
@@ -255,7 +269,7 @@ static void serial_ioport_write(void *op
             s->lsr &= ~UART_LSR_THRE;
             serial_update_irq(s);
             s->write_chr = val;
-            s->write_retries = 0;
+            s->write_single_retries = 0;
             serial_chr_write(s);
         }
         break;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.