diff options
author | Keir Fraser <keir@xen.org> | 2010-10-29 10:40:14 +0100 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2010-10-29 10:40:14 +0100 |
commit | fd1291a826e17108d7c7f20c887847daba451ef4 (patch) | |
tree | 963f0da4548bc87d110ff0a4982f1b14f913be29 /xen/arch/x86/time.c | |
parent | 9dbd1007376011d99e6af1dd703c2cc437e7fda0 (diff) | |
download | xen-fd1291a826e17108d7c7f20c887847daba451ef4.tar.gz xen-fd1291a826e17108d7c7f20c887847daba451ef4.tar.bz2 xen-fd1291a826e17108d7c7f20c887847daba451ef4.zip |
X86: Prefer TSC-deadline timer in Xen
The new TSC Deadline Timer offers system software a low overhead
per-logical-thread deadline timer in TSC units.
The timer is implemented via a new architectural 64-bit register,
IA32_TSC_DEADLINE_MSR. Reads and writes of this MSR occur in program
order, but are non-serializing.
The support for this feature is indicated by
CPUID.01H:ECX.TSC_Deadline[bit 24] =3D 1 as documented in the Intel
Architecture Software Developer's Manual.
The LOCAL APIC on new processors has a mode where its underlying
hardware timer can now be accessed via the non-serializing
IA32_TSC_DEADLINE_MSR in TSC tick units.
If this mode is present, prefer it over the traditional LAPIC timer
mode. KERN_DEBUG dmesg will print "TSC deadline timer enabled" when
TDT is used.
Bootparam "tdt=off" is available to revert to LAPIC timer mode.
This patch is based on original work by Len Brown for Linux kernel.
cc: Len Brown <len.brown@intel.com>
Signed-off-by: Wei Gang <gang.wei@intel.com>
Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/time.c')
-rw-r--r-- | xen/arch/x86/time.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 0564c398b7..ad37cb3075 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -662,26 +662,28 @@ static void __init init_platform_timer(void) freq_string(pts->frequency), pts->name); } -void cstate_restore_tsc(void) +u64 stime2tsc(s_time_t stime) { struct cpu_time *t; struct time_scale sys_to_tsc; s_time_t stime_delta; - u64 new_tsc; - - if ( boot_cpu_has(X86_FEATURE_NONSTOP_TSC) ) - return; t = &this_cpu(cpu_time); sys_to_tsc = scale_reciprocal(t->tsc_scale); - stime_delta = read_platform_stime() - t->stime_master_stamp; + stime_delta = stime - t->stime_local_stamp; if ( stime_delta < 0 ) stime_delta = 0; - new_tsc = t->local_tsc_stamp + scale_delta(stime_delta, &sys_to_tsc); + return t->local_tsc_stamp + scale_delta(stime_delta, &sys_to_tsc); +} + +void cstate_restore_tsc(void) +{ + if ( boot_cpu_has(X86_FEATURE_NONSTOP_TSC) ) + return; - write_tsc(new_tsc); + write_tsc(stime2tsc(read_platform_stime())); } /*************************************************************************** |