direct-io.hg

changeset 1829:1c630e7af56e

bitkeeper revision 1.1108.2.3 (40fc44e2_QPjU_36U-DOo3CgN8jbnw)

Merge freefall.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into freefall.cl.cam.ac.uk:/local/scratch/cl349/xeno.bk-prist
author cl349@freefall.cl.cam.ac.uk
date Mon Jul 19 22:02:10 2004 +0000 (2004-07-19)
parents 6c3bbbf7e1cf b18621623b26
children 4d2b5836d0d7
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	Mon Jul 19 16:20:46 2004 +0000
     1.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/Kconfig	Mon Jul 19 22:02:10 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	Mon Jul 19 16:20:46 2004 +0000
     2.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c	Mon Jul 19 22:02:10 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	Mon Jul 19 16:20:46 2004 +0000
     3.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/process.c	Mon Jul 19 22:02:10 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  }