x86: Roughly synchronise calls to local_time_calibration().
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 28 Jul 2008 10:33:28 +0000 (11:33 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 28 Jul 2008 10:33:28 +0000 (11:33 +0100)
This results in reduced skew; both max and average skew are reduced by
between a factor of 2 and 3.  Note that timers still fire at slightly
different times because the next "round epoch" is still relative to
local stime which still has some inter-processor skew.

Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>
xen/arch/x86/time.c

index 72f1c4a6c1f1b1268acdeb59beda1b4dc8fb116d..570a6308849372e92cd7ff0c4d3bc48462bb2183 100644 (file)
@@ -35,7 +35,8 @@
 static char opt_clocksource[10];
 string_param("clocksource", opt_clocksource);
 
-#define EPOCH MILLISECS(1000)
+#define EPOCH (1ULL << 30) /* one second, rounded up to a power of two */
+#define NEXT_EPOCH(now) (((now) + (EPOCH+(EPOCH/2))) & ~(EPOCH-1))
 
 unsigned long cpu_khz;  /* CPU clock frequency in kHz. */
 DEFINE_SPINLOCK(rtc_lock);
@@ -1021,7 +1022,7 @@ static void local_time_calibration(void *unused)
     update_vcpu_system_time(current);
 
  out:
-    set_timer(&t->calibration_timer, NOW() + EPOCH);
+    set_timer(&t->calibration_timer, NEXT_EPOCH(curr_local_stime));
 
     if ( smp_processor_id() == 0 )
         platform_time_calibration();
@@ -1050,7 +1051,7 @@ void init_percpu_time(void)
  out:
     init_timer(&t->calibration_timer, local_time_calibration,
                NULL, smp_processor_id());
-    set_timer(&t->calibration_timer, NOW() + EPOCH);
+    set_timer(&t->calibration_timer, NEXT_EPOCH(NOW()));
 }
 
 /* Late init function (after all CPUs are booted). */