[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Add TSC stop support for Deep C state
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1209635409 -3600 # Node ID becd9b77f951fe66bb68616426ef13a2894d0191 # Parent 4aec1797720f3691a54988b2b7e02683fb6cdf89 x86: Add TSC stop support for Deep C state TSC may stop at deep C state (C3/C4...) entry/exit. this patch add the logic that save and restore TSC during deep C state entry/exit, by using platform timer (PIT/HPET) Signed-off-by: Yu Ke <ke.yu@xxxxxxxxx> Signed-off-by: Tian Kevin <kevin.tian@xxxxxxxxx> Signed-off-by: Wei Gang<gang.wei@xxxxxxxxx> --- xen/arch/x86/acpi/cpu_idle.c | 7 ++++--- xen/arch/x86/time.c | 39 +++++++++++++++++++++++++++++++++++++++ xen/include/xen/time.h | 2 ++ 3 files changed, 45 insertions(+), 3 deletions(-) diff -r 4aec1797720f -r becd9b77f951 xen/arch/x86/acpi/cpu_idle.c --- a/xen/arch/x86/acpi/cpu_idle.c Thu May 01 10:49:38 2008 +0100 +++ b/xen/arch/x86/acpi/cpu_idle.c Thu May 01 10:50:09 2008 +0100 @@ -442,8 +442,8 @@ static void acpi_processor_idle(void) * stopped by H/W. Without carefully handling of TSC/APIC stop issues, * deep C state can't work correctly. */ - /* placeholder for preparing TSC stop */ - + /* preparing TSC stop */ + cstate_save_tsc(); /* placeholder for preparing APIC stop */ /* Invoke C3 */ @@ -451,7 +451,8 @@ static void acpi_processor_idle(void) /* placeholder for recovering APIC */ - /* placeholder for recovering TSC */ + /* recovering TSC */ + cstate_restore_tsc(); /* Get end time (ticks) */ t2 = inl(pmtmr_ioport); diff -r 4aec1797720f -r becd9b77f951 xen/arch/x86/time.c --- a/xen/arch/x86/time.c Thu May 01 10:49:38 2008 +0100 +++ b/xen/arch/x86/time.c Thu May 01 10:50:09 2008 +0100 @@ -51,9 +51,11 @@ struct time_scale { struct cpu_time { u64 local_tsc_stamp; + u64 cstate_tsc_stamp; s_time_t stime_local_stamp; s_time_t stime_master_stamp; struct time_scale tsc_scale; + u32 cstate_plt_count_stamp; struct timer calibration_timer; }; @@ -65,6 +67,8 @@ struct platform_timesource { }; static DEFINE_PER_CPU(struct cpu_time, cpu_time); + +static u8 tsc_invariant=0; /* TSC is invariant upon C state entry */ /* * We simulate a 32-bit platform timer from the 16-bit PIT ch2 counter. @@ -594,6 +598,36 @@ static void init_platform_timer(void) freq_string(pts->frequency), pts->name); } +void cstate_save_tsc(void) +{ + struct cpu_time *t = &this_cpu(cpu_time); + + if (!tsc_invariant){ + t->cstate_plt_count_stamp = plt_src.read_counter(); + rdtscll(t->cstate_tsc_stamp); + } +} + +void cstate_restore_tsc(void) +{ + struct cpu_time *t; + u32 plt_count_delta; + u64 tsc_delta; + + if (!tsc_invariant){ + t = &this_cpu(cpu_time); + + /* if platform counter overflow happens, interrupt will bring CPU from + C state to working state, so the platform counter won't wrap the + cstate_plt_count_stamp, and the 32 bit unsigned platform counter + is enough for delta calculation + */ + plt_count_delta = + (plt_src.read_counter() - t->cstate_plt_count_stamp) & plt_mask; + tsc_delta = scale_delta(plt_count_delta, &plt_scale)*cpu_khz/1000000UL; + wrmsrl(MSR_IA32_TSC, t->cstate_tsc_stamp + tsc_delta); + } +} /*************************************************************************** * CMOS Timer functions @@ -972,6 +1006,11 @@ int __init init_xen_time(void) stime_platform_stamp = 0; init_platform_timer(); + + /* check if TSC is invariant during deep C state + this is a new feature introduced by Nehalem*/ + if ( cpuid_edx(0x80000007) & (1U<<8) ) + tsc_invariant = 1; local_irq_enable(); diff -r 4aec1797720f -r becd9b77f951 xen/include/xen/time.h --- a/xen/include/xen/time.h Thu May 01 10:49:38 2008 +0100 +++ b/xen/include/xen/time.h Thu May 01 10:50:09 2008 +0100 @@ -13,6 +13,8 @@ #include <asm/time.h> extern int init_xen_time(void); +extern void cstate_save_tsc(void); +extern void cstate_restore_tsc(void); extern unsigned long cpu_khz; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |