direct-io.hg
changeset 1828:b18621623b26
bitkeeper revision 1.1108.3.1 (40fc449eExRZSW5dU1TAzdlOTRDqMQ)
Add HYPERVISOR_block support.
Not enabled yet since it adds a 5 seconds long delay during boot.
Add HYPERVISOR_block support.
Not enabled yet since it adds a 5 seconds long delay during boot.
author | cl349@freefall.cl.cam.ac.uk |
---|---|
date | Mon Jul 19 22:01:02 2004 +0000 (2004-07-19) |
parents | 1a488e40456a |
children | 1c630e7af56e |
files | linux-2.6.7-xen-sparse/arch/xen/Kconfig linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c linux-2.6.7-xen-sparse/arch/xen/kernel/process.c |
line diff
1.1 --- a/linux-2.6.7-xen-sparse/arch/xen/Kconfig Sun Jul 18 16:38:30 2004 +0000 1.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/Kconfig Mon Jul 19 22:01:02 2004 +0000 1.3 @@ -16,6 +16,10 @@ config ARCH_XEN 1.4 default y 1.5 1.6 1.7 +config NO_IDLE_HZ 1.8 + bool 1.9 + default y 1.10 + 1.11 source "init/Kconfig" 1.12 1.13 #config VT
2.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c Sun Jul 18 16:38:30 2004 +0000 2.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c Mon Jul 19 22:01:02 2004 +0000 2.3 @@ -87,6 +87,17 @@ EXPORT_SYMBOL(i8253_lock); 2.4 2.5 struct timer_opts *cur_timer = &timer_none; 2.6 2.7 +/* These are peridically updated in shared_info, and then copied here. */ 2.8 +static u32 shadow_tsc_stamp; 2.9 +static u64 shadow_system_time; 2.10 +static u32 shadow_time_version; 2.11 +static struct timeval shadow_tv; 2.12 + 2.13 +/* Keep track of last time we did processing/updating of jiffies and xtime. */ 2.14 +static u64 processed_system_time; /* System time (ns) at last processing. */ 2.15 + 2.16 +#define NS_PER_TICK (1000000000ULL/HZ) 2.17 + 2.18 /* 2.19 * This version of gettimeofday has microsecond resolution 2.20 * and better than microsecond precision on fast x86 machines with TSC. 2.21 @@ -204,12 +215,33 @@ EXPORT_SYMBOL(monotonic_clock); 2.22 2.23 2.24 /* 2.25 + * Reads a consistent set of time-base values from Xen, into a shadow data 2.26 + * area. Must be called with the xtime_lock held for writing. 2.27 + */ 2.28 +static void __get_time_values_from_xen(void) 2.29 +{ 2.30 + do { 2.31 + shadow_time_version = HYPERVISOR_shared_info->time_version2; 2.32 + rmb(); 2.33 + shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec; 2.34 + shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec; 2.35 + shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp.tsc_bits; 2.36 + shadow_system_time = HYPERVISOR_shared_info->system_time; 2.37 + rmb(); 2.38 + } 2.39 + while ( shadow_time_version != HYPERVISOR_shared_info->time_version1 ); 2.40 +} 2.41 + 2.42 +/* 2.43 * timer_interrupt() needs to keep up the real-time clock, 2.44 * as well as call the "do_timer()" routine every clocktick 2.45 */ 2.46 static inline void do_timer_interrupt(int irq, void *dev_id, 2.47 struct pt_regs *regs) 2.48 { 2.49 + s64 delta; 2.50 + unsigned long ticks = 0; 2.51 + 2.52 #ifdef CONFIG_X86_IO_APIC 2.53 if (timer_ack) { 2.54 /* 2.55 @@ -226,7 +258,23 @@ static inline void do_timer_interrupt(in 2.56 } 2.57 #endif 2.58 2.59 - do_timer_interrupt_hook(regs); 2.60 + __get_time_values_from_xen(); 2.61 + 2.62 + delta = (s64)(shadow_system_time - processed_system_time); 2.63 + if (delta < 0) { 2.64 + printk("Timer ISR: Time went backwards: %lld\n", delta); 2.65 + return; 2.66 + } 2.67 + 2.68 + /* Process elapsed jiffies since last call. */ 2.69 + while (delta >= NS_PER_TICK) { 2.70 + ticks++; 2.71 + delta -= NS_PER_TICK; 2.72 + processed_system_time += NS_PER_TICK; 2.73 + 2.74 + if (regs) 2.75 + do_timer_interrupt_hook(regs); 2.76 + } 2.77 2.78 #if 0 /* XEN PRIV */ 2.79 /* 2.80 @@ -288,8 +336,7 @@ irqreturn_t timer_interrupt(int irq, voi 2.81 2.82 cur_timer->mark_offset(); 2.83 2.84 - if (regs) /* XXXcl check regs in do_timer_interrupt */ 2.85 - do_timer_interrupt(irq, NULL, regs); 2.86 + do_timer_interrupt(irq, NULL, regs); 2.87 2.88 write_sequnlock(&xtime_lock); 2.89 return IRQ_HANDLED; 2.90 @@ -410,3 +457,51 @@ void __init time_init(void) 2.91 2.92 (void)setup_irq(time_irq, &irq_timer); 2.93 } 2.94 + 2.95 +/* Convert jiffies to system time. Call with xtime_lock held for reading. */ 2.96 +static inline u64 __jiffies_to_st(unsigned long j) 2.97 +{ 2.98 + return processed_system_time + ((j - jiffies) * NS_PER_TICK); 2.99 +} 2.100 + 2.101 +/* 2.102 + * This function works out when the the next timer function has to be 2.103 + * executed (by looking at the timer list) and sets the Xen one-shot 2.104 + * domain timer to the appropriate value. This is typically called in 2.105 + * cpu_idle() before the domain blocks. 2.106 + * 2.107 + * The function returns a non-0 value on error conditions. 2.108 + * 2.109 + * It must be called with interrupts disabled. 2.110 + */ 2.111 +extern spinlock_t timerlist_lock; 2.112 +int set_timeout_timer(void) 2.113 +{ 2.114 + struct timer_list *timer; 2.115 + u64 alarm = 0; 2.116 + int ret = 0; 2.117 + 2.118 + spin_lock(&timerlist_lock); 2.119 + 2.120 + /* 2.121 + * This is safe against long blocking (since calculations are not based on 2.122 + * TSC deltas). It is also safe against warped system time since 2.123 + * suspend-resume is cooperative and we would first get locked out. It is 2.124 + * safe against normal updates of jiffies since interrupts are off. 2.125 + */ 2.126 + alarm = __jiffies_to_st(next_timer_interrupt()); 2.127 + 2.128 +#if 0 2.129 + /* Tasks on the timer task queue expect to be executed on the next tick. */ 2.130 + if ( TQ_ACTIVE(tq_timer) ) 2.131 + alarm = __jiffies_to_st(jiffies + 1); 2.132 +#endif 2.133 + 2.134 + /* Failure is pretty bad, but we'd best soldier on. */ 2.135 + if ( HYPERVISOR_set_timer_op(alarm) != 0 ) 2.136 + ret = -1; 2.137 + 2.138 + spin_unlock(&timerlist_lock); 2.139 + 2.140 + return ret; 2.141 +}
3.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/process.c Sun Jul 18 16:38:30 2004 +0000 3.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/process.c Mon Jul 19 22:01:02 2004 +0000 3.3 @@ -10,11 +10,16 @@ 3.4 3.5 void xen_cpu_idle (void) 3.6 { 3.7 - // local_irq_disable(); 3.8 + local_irq_disable(); 3.9 if (need_resched()) { 3.10 - // local_irq_enable(); 3.11 + local_irq_enable(); 3.12 return; 3.13 } 3.14 - // local_irq_enable(); 3.15 + if (0 && set_timeout_timer() == 0) { 3.16 + /* NB. Blocking reenable events in a race-free manner. */ 3.17 + HYPERVISOR_block(); 3.18 + return; 3.19 + } 3.20 + local_irq_enable(); 3.21 HYPERVISOR_yield(); 3.22 }