bitkeeper revision 1.1159.1.213 (416517f3vAbY9ISDviAe0Gjenl6dKw)
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Thu, 7 Oct 2004 10:18:27 +0000 (10:18 +0000)
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Thu, 7 Oct 2004 10:18:27 +0000 (10:18 +0000)
Take better care of over time consistency in XenLinux.
Avoid spinning on serial line with interrupts disabled in Xen.

linux-2.4.27-xen-sparse/arch/xen/kernel/time.c
linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/time.c
xen/drivers/char/serial.c

index 387c25522208bc14bba2b9f2dfbd8176f407325b..01584bda33892f46534a2f22270dcd3af8537ca9 100644 (file)
@@ -224,7 +224,7 @@ static void __get_time_values_from_xen(void)
 }
 
 #define TIME_VALUES_UP_TO_DATE \
   (shadow_time_version == HYPERVISOR_shared_info->time_version2)
({ rmb(); (shadow_time_version == HYPERVISOR_shared_info->time_version2); })
 
 
 /*
@@ -393,11 +393,14 @@ static inline void do_timer_interrupt(int irq, void *dev_id,
     unsigned long ticks = 0;
     long sec_diff;
 
+ retry:
     __get_time_values_from_xen();
 
     if ( (delta = (s64)(shadow_system_time + __get_time_delta_usecs() * 1000 -
                                                processed_system_time)) < 0 )
     {
+               if (!TIME_VALUES_UP_TO_DATE)
+                       goto retry;
         printk("Timer ISR: Time went backwards: %lld\n", delta);
         return;
     }
index 87503b673b23b2a5f37335ab0b6c34643be26030..a57de375bc02073dec3ccf5ee5baca4ccc7c4762 100644 (file)
@@ -172,7 +172,7 @@ static void __get_time_values_from_xen(void)
 }
 
 #define TIME_VALUES_UP_TO_DATE \
      (shadow_time_version == HYPERVISOR_shared_info->time_version2)
({ rmb(); (shadow_time_version == HYPERVISOR_shared_info->time_version2); })
 
 /*
  * This version of gettimeofday has microsecond resolution
@@ -367,12 +367,15 @@ static inline void do_timer_interrupt(int irq, void *dev_id,
        s64 delta, nsec;
        long sec_diff, wtm_nsec;
 
+ retry:
        __get_time_values_from_xen();
 
        delta = (s64)(shadow_system_time +
                      (cur_timer->get_offset() * NSEC_PER_USEC) -
                      processed_system_time);
        if (delta < 0) {
+               if (!TIME_VALUES_UP_TO_DATE)
+                       goto retry;
                printk("Timer ISR: Time went backwards: %lld\n", delta);
                return;
        }
index 60e6b02c321782f21845c462cb0bba150f6bc001..092bcaee03dcb9fb805a2b5f2820f56ba6844819 100644 (file)
@@ -132,6 +132,9 @@ static void serial_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static inline void __serial_putc(uart_t *uart, int handle, unsigned char c)
 {
+    unsigned long flags;
+    int space;
+
     if ( (c == '\n') && (handle & SERHND_COOKED) )
         __serial_putc(uart, handle, '\r');
 
@@ -140,10 +143,13 @@ static inline void __serial_putc(uart_t *uart, int handle, unsigned char c)
     else if ( handle & SERHND_LO )
         c &= 0x7f;
 
-    while ( !(inb(uart->io_base + LSR) & LSR_THRE) )
-        barrier();
-
-    outb(c, uart->io_base + THR);
+    do { 
+        spin_lock_irqsave(&uart->lock, flags);
+        if ( (space = (inb(uart->io_base + LSR) & LSR_THRE)) )
+            outb(c, uart->io_base + THR);
+        spin_unlock_irqrestore(&uart->lock, flags);
+    }
+    while ( !space );
 }
 
 #define PARSE_ERR(_f, _a...)                 \
@@ -376,32 +382,22 @@ void serial_set_rx_handler(int handle, serial_rx_fn fn)
 void serial_putc(int handle, unsigned char c)
 {
     uart_t *uart = &com[handle & SERHND_IDX];
-    unsigned long flags;
 
     if ( handle == -1 )
         return;
 
-    spin_lock_irqsave(&uart->lock, flags);
-
     __serial_putc(uart, handle, c);
-
-    spin_unlock_irqrestore(&uart->lock, flags);
 }
 
 void serial_puts(int handle, const unsigned char *s)
 {
     uart_t *uart = &com[handle & SERHND_IDX];
-    unsigned long flags;
 
     if ( handle == -1 )
         return;
 
-    spin_lock_irqsave(&uart->lock, flags);
-
     while ( *s != '\0' )
         __serial_putc(uart, handle, *s++);
-
-    spin_unlock_irqrestore(&uart->lock, flags);
 }
 
 /* Returns TRUE if given character (*pc) matches the serial handle. */