ia64/xen-unstable

changeset 5832:581902ddd16f

Merged by hand.
author maf46@burn.cl.cam.ac.uk
date Tue Jul 19 12:20:24 2005 +0000 (2005-07-19)
parents 390e4d63cdb1 2ecb91fb6cdb
children c316e464f7c2
files linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c xen/arch/x86/shadow.c xen/arch/x86/shadow32.c xen/arch/x86/time.c xen/include/asm-x86/shadow.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c	Tue Jul 19 10:40:26 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c	Tue Jul 19 12:20:24 2005 +0000
     1.3 @@ -227,9 +227,9 @@ static unsigned long get_usec_offset(str
     1.4  static void update_wallclock(void)
     1.5  {
     1.6  	shared_info_t *s = HYPERVISOR_shared_info;
     1.7 -	long wtm_nsec;
     1.8 -	time_t wtm_sec, sec;
     1.9 -	s64 nsec;
    1.10 +	long wtm_nsec, xtime_nsec;
    1.11 +	time_t wtm_sec, xtime_sec;
    1.12 +	u64 tmp, usec;
    1.13  
    1.14  	shadow_tv.tv_sec  = s->wc_sec;
    1.15  	shadow_tv.tv_usec = s->wc_usec;
    1.16 @@ -240,20 +240,22 @@ static void update_wallclock(void)
    1.17  	if ((time_status & STA_UNSYNC) != 0)
    1.18  		return;
    1.19  
    1.20 -	/* Adjust shadow for jiffies that haven't updated xtime yet. */
    1.21 -	shadow_tv.tv_usec -= 
    1.22 -		(jiffies - wall_jiffies) * (USEC_PER_SEC / HZ);
    1.23 -	HANDLE_USEC_UNDERFLOW(shadow_tv);
    1.24 +	/* Adjust wall-clock time base based on wall_jiffies ticks. */
    1.25 +	usec = processed_system_time;
    1.26 +	do_div(usec, 1000);
    1.27 +	usec += (u64)shadow_tv.tv_sec * 1000000ULL;
    1.28 +	usec += (u64)shadow_tv.tv_usec;
    1.29 +	usec -= (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ);
    1.30  
    1.31 -	/* Update our unsynchronised xtime appropriately. */
    1.32 -	sec = shadow_tv.tv_sec;
    1.33 -	nsec = shadow_tv.tv_usec * NSEC_PER_USEC;
    1.34 +	/* Split wallclock base into seconds and nanoseconds. */
    1.35 +	tmp = usec;
    1.36 +	xtime_nsec = do_div(tmp, 1000000) * 1000ULL;
    1.37 +	xtime_sec  = (time_t)tmp;
    1.38  
    1.39 -	__normalize_time(&sec, &nsec);
    1.40 -	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
    1.41 -	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
    1.42 +	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - xtime_sec);
    1.43 +	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - xtime_nsec);
    1.44  
    1.45 -	set_normalized_timespec(&xtime, sec, nsec);
    1.46 +	set_normalized_timespec(&xtime, xtime_sec, xtime_nsec);
    1.47  	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
    1.48  }
    1.49  
     4.1 --- a/xen/arch/x86/time.c	Tue Jul 19 10:40:26 2005 +0000
     4.2 +++ b/xen/arch/x86/time.c	Tue Jul 19 12:20:24 2005 +0000
     4.3 @@ -30,6 +30,8 @@
     4.4  #include <asm/div64.h>
     4.5  #include <io_ports.h>
     4.6  
     4.7 +#define EPOCH MILLISECS(1000)
     4.8 +
     4.9  unsigned long cpu_khz;  /* CPU clock frequency in kHz. */
    4.10  spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
    4.11  int timer_ack = 0;
    4.12 @@ -80,8 +82,8 @@ static inline u32 div_frac(u32 dividend,
    4.13  }
    4.14  
    4.15  /*
    4.16 - * 32-bit multiplication of integer multiplicand and fractional multiplier
    4.17 - * yielding 32-bit integer product.
    4.18 + * 32-bit multiplication of multiplicand and fractional multiplier
    4.19 + * yielding 32-bit product (radix point at same position as in multiplicand).
    4.20   */
    4.21  static inline u32 mul_frac(u32 multiplicand, u32 multiplier)
    4.22  {
    4.23 @@ -461,15 +463,23 @@ static void local_time_calibration(void 
    4.24  
    4.25      /*
    4.26       * System time and TSC ticks elapsed during the previous calibration
    4.27 -     * 'epoch'. Also the accumulated error in the local estimate. All these
    4.28 -     * values end up down-shifted to fit in 32 bits.
    4.29 +     * 'epoch'. These values are down-shifted to fit in 32 bits.
    4.30       */
    4.31 -    u64 stime_elapsed64, tsc_elapsed64, local_stime_error64;
    4.32 -    u32 stime_elapsed32, tsc_elapsed32, local_stime_error32;
    4.33 +    u64 stime_elapsed64, tsc_elapsed64;
    4.34 +    u32 stime_elapsed32, tsc_elapsed32;
    4.35 +
    4.36 +    /* The accumulated error in the local estimate. */
    4.37 +    u64 local_stime_err;
    4.38 +
    4.39 +    /* Error correction to slow down a fast local clock. */
    4.40 +    u32 error_factor = 0;
    4.41  
    4.42      /* Calculated TSC shift to ensure 32-bit scale multiplier. */
    4.43      int tsc_shift = 0;
    4.44  
    4.45 +    /* The overall calibration scale multiplier. */
    4.46 +    u32 calibration_mul_frac;
    4.47 +
    4.48      prev_tsc          = cpu_time[cpu].local_tsc_stamp;
    4.49      prev_local_stime  = cpu_time[cpu].stime_local_stamp;
    4.50      prev_master_stime = cpu_time[cpu].stime_master_stamp;
    4.51 @@ -497,13 +507,17 @@ static void local_time_calibration(void 
    4.52      tsc_elapsed64   = curr_tsc - prev_tsc;
    4.53  
    4.54      /*
    4.55 -     * Error in the local system time estimate. Clamp to epoch time period, or
    4.56 -     * we could end up with a negative scale factor (time going backwards!).
    4.57 -     * This effectively clamps the scale factor to >= 0.
    4.58 +     * Calculate error-correction factor. This only slows down a fast local
    4.59 +     * clock (slow clocks are warped forwards). The scale factor is clamped
    4.60 +     * to >= 0.5.
    4.61       */
    4.62 -    local_stime_error64 = curr_local_stime - curr_master_stime;
    4.63 -    if ( local_stime_error64 > stime_elapsed64 )
    4.64 -        local_stime_error64 = stime_elapsed64;
    4.65 +    if ( curr_local_stime != curr_master_stime )
    4.66 +    {
    4.67 +        local_stime_err = curr_local_stime - curr_master_stime;
    4.68 +        if ( local_stime_err > EPOCH )
    4.69 +            local_stime_err = EPOCH;
    4.70 +        error_factor = div_frac(EPOCH, EPOCH + (u32)local_stime_err);
    4.71 +    }
    4.72  
    4.73      /*
    4.74       * We require 0 < stime_elapsed < 2^31.
    4.75 @@ -513,14 +527,12 @@ static void local_time_calibration(void 
    4.76      while ( ((u32)stime_elapsed64 != stime_elapsed64) ||
    4.77              ((s32)stime_elapsed64 < 0) )
    4.78      {
    4.79 -        stime_elapsed64     >>= 1;
    4.80 -        tsc_elapsed64       >>= 1;
    4.81 -        local_stime_error64 >>= 1;
    4.82 +        stime_elapsed64 >>= 1;
    4.83 +        tsc_elapsed64   >>= 1;
    4.84      }
    4.85  
    4.86 -    /* stime_master_diff (and hence stime_error) now fit in a 32-bit word. */
    4.87 -    stime_elapsed32     = (u32)stime_elapsed64;
    4.88 -    local_stime_error32 = (u32)local_stime_error64;
    4.89 +    /* stime_master_diff now fits in a 32-bit word. */
    4.90 +    stime_elapsed32 = (u32)stime_elapsed64;
    4.91  
    4.92      /* tsc_elapsed <= 2*stime_elapsed */
    4.93      while ( tsc_elapsed64 > (stime_elapsed32 * 2) )
    4.94 @@ -541,21 +553,22 @@ static void local_time_calibration(void 
    4.95          tsc_shift++;
    4.96      }
    4.97  
    4.98 +    calibration_mul_frac = div_frac(stime_elapsed32, tsc_elapsed32);
    4.99 +    if ( error_factor != 0 )
   4.100 +        calibration_mul_frac = mul_frac(calibration_mul_frac, error_factor);
   4.101 +
   4.102  #if 0
   4.103 -    printk("---%d: %08x %d\n", cpu, 
   4.104 -           div_frac(stime_elapsed32 - local_stime_error32, tsc_elapsed32),
   4.105 -           tsc_shift);
   4.106 +    printk("---%d: %08x %d\n", cpu, calibration_mul_frac, tsc_shift);
   4.107  #endif
   4.108  
   4.109      /* Record new timestamp information. */
   4.110 -    cpu_time[cpu].tsc_scale.mul_frac = 
   4.111 -        div_frac(stime_elapsed32 - local_stime_error32, tsc_elapsed32);
   4.112 +    cpu_time[cpu].tsc_scale.mul_frac = calibration_mul_frac;
   4.113      cpu_time[cpu].tsc_scale.shift    = tsc_shift;
   4.114      cpu_time[cpu].local_tsc_stamp    = curr_tsc;
   4.115      cpu_time[cpu].stime_local_stamp  = curr_local_stime;
   4.116      cpu_time[cpu].stime_master_stamp = curr_master_stime;
   4.117  
   4.118 -    set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + MILLISECS(1000));
   4.119 +    set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
   4.120  
   4.121      if ( cpu == 0 )
   4.122          platform_time_calibration();
   4.123 @@ -577,7 +590,7 @@ void init_percpu_time(void)
   4.124  
   4.125      init_ac_timer(&cpu_time[cpu].calibration_timer,
   4.126                    local_time_calibration, NULL, cpu);
   4.127 -    set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + MILLISECS(1000));
   4.128 +    set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
   4.129  }
   4.130  
   4.131  /* Late init function (after all CPUs are booted). */