From 48ddbf4e22cdaefc8793e8408baccc4fbce57833 Mon Sep 17 00:00:00 2001 From: "kaf24@freefall.cl.cam.ac.uk" Date: Thu, 7 Oct 2004 10:18:27 +0000 Subject: [PATCH] bitkeeper revision 1.1159.1.213 (416517f3vAbY9ISDviAe0Gjenl6dKw) Take better care of over time consistency in XenLinux. Avoid spinning on serial line with interrupts disabled in Xen. --- .../arch/xen/kernel/time.c | 5 +++- .../arch/xen/i386/kernel/time.c | 5 +++- xen/drivers/char/serial.c | 24 ++++++++----------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/linux-2.4.27-xen-sparse/arch/xen/kernel/time.c b/linux-2.4.27-xen-sparse/arch/xen/kernel/time.c index 387c255222..01584bda33 100644 --- a/linux-2.4.27-xen-sparse/arch/xen/kernel/time.c +++ b/linux-2.4.27-xen-sparse/arch/xen/kernel/time.c @@ -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; } diff --git a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/time.c index 87503b673b..a57de375bc 100644 --- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/time.c @@ -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; } diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index 60e6b02c32..092bcaee03 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -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. */ -- 2.30.2