53 lines
2.0 KiB
Diff
53 lines
2.0 KiB
Diff
# HG changeset patch
|
|
# User Keir Fraser <keir.fraser@citrix.com>
|
|
# Date 1209631544 -3600
|
|
# Node ID 013a47065e8c4e815e3b1aba0883341c19238e82
|
|
# Parent 483d006cc60765357dcdb66ab0fc43c955ecd8fe
|
|
x86 time: Read platform time before locally-extrapolated time during
|
|
calibration and frequency changes. This places the variable delay
|
|
(acquiring the platform_timer_lock) safely as the very first thing we
|
|
do, avoiding a variable delay /between/ computing the two timestamps.
|
|
|
|
Problem diagnosed by Dave Winchell <dwinchell@virtualiron.com>
|
|
|
|
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
|
|
|
|
Index: xen-3.2.1-testing/xen/arch/x86/time.c
|
|
===================================================================
|
|
--- xen-3.2.1-testing.orig/xen/arch/x86/time.c
|
|
+++ xen-3.2.1-testing/xen/arch/x86/time.c
|
|
@@ -738,12 +738,13 @@ int cpu_frequency_change(u64 freq)
|
|
}
|
|
|
|
local_irq_disable();
|
|
- rdtscll(curr_tsc);
|
|
- t->local_tsc_stamp = curr_tsc;
|
|
+ /* Platform time /first/, as we may be delayed by platform_timer_lock. */
|
|
t->stime_master_stamp = read_platform_stime();
|
|
/* TSC-extrapolated time may be bogus after frequency change. */
|
|
/*t->stime_local_stamp = get_s_time();*/
|
|
t->stime_local_stamp = t->stime_master_stamp;
|
|
+ rdtscll(curr_tsc);
|
|
+ t->local_tsc_stamp = curr_tsc;
|
|
set_time_scale(&t->tsc_scale, freq);
|
|
local_irq_enable();
|
|
|
|
@@ -813,11 +814,14 @@ static void local_time_calibration(void
|
|
prev_local_stime = t->stime_local_stamp;
|
|
prev_master_stime = t->stime_master_stamp;
|
|
|
|
- /* Disable IRQs to get 'instantaneous' current timestamps. */
|
|
+ /*
|
|
+ * Disable IRQs to get 'instantaneous' current timestamps. We read platform
|
|
+ * time first, as we may be delayed when acquiring platform_timer_lock.
|
|
+ */
|
|
local_irq_disable();
|
|
- rdtscll(curr_tsc);
|
|
- curr_local_stime = get_s_time();
|
|
curr_master_stime = read_platform_stime();
|
|
+ curr_local_stime = get_s_time();
|
|
+ rdtscll(curr_tsc);
|
|
local_irq_enable();
|
|
|
|
#if 0
|