[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] cpuidle: revise tsc-save/restore to reduce tsc skew between cpus
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1228482224 0 # Node ID eed39afde7dd52d623d8c1a0f659507ac630d9fc # Parent 5e066dc410ac872c8976ae4db17891ed1dc5e00e cpuidle: revise tsc-save/restore to reduce tsc skew between cpus Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/acpi/cpu_idle.c | 2 -- xen/arch/x86/time.c | 43 ++++++++++++++++++++++++------------------- xen/include/xen/time.h | 1 - 3 files changed, 24 insertions(+), 22 deletions(-) diff -r 5e066dc410ac -r eed39afde7dd xen/arch/x86/acpi/cpu_idle.c --- a/xen/arch/x86/acpi/cpu_idle.c Fri Dec 05 11:37:20 2008 +0000 +++ b/xen/arch/x86/acpi/cpu_idle.c Fri Dec 05 13:03:44 2008 +0000 @@ -317,8 +317,6 @@ 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. */ - /* preparing TSC stop */ - cstate_save_tsc(); /* preparing APIC stop */ lapic_timer_off(); diff -r 5e066dc410ac -r eed39afde7dd xen/arch/x86/time.c --- a/xen/arch/x86/time.c Fri Dec 05 11:37:20 2008 +0000 +++ b/xen/arch/x86/time.c Fri Dec 05 13:03:44 2008 +0000 @@ -48,11 +48,9 @@ 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; - u64 cstate_plt_count_stamp; }; struct platform_timesource { @@ -151,6 +149,19 @@ static inline u64 scale_delta(u64 delta, return product; } +/* Compute the reciprocal of the given time_scale. */ +static inline struct time_scale scale_reciprocal(struct time_scale scale) +{ + u32 q, r; + + asm ( + "divl %4" + : "=a" (q), "=d" (r) + : "0" (1), "1" (0), "r" (scale.mul_frac) ); + + return (struct time_scale) { .shift = -scale.shift, .mul_frac = q }; +} + /* * cpu_mask that denotes the CPUs that needs timer interrupt coming in as * IPIs in place of local APIC timers @@ -644,29 +655,23 @@ static void init_platform_timer(void) freq_string(pts->frequency), pts->name); } -void cstate_save_tsc(void) +void cstate_restore_tsc(void) { struct cpu_time *t = &this_cpu(cpu_time); + struct time_scale sys_to_tsc = scale_reciprocal(t->tsc_scale); + s_time_t stime_delta; + u64 tsc_delta; if ( tsc_invariant ) return; - t->cstate_plt_count_stamp = plt_src.read_counter(); - rdtscll(t->cstate_tsc_stamp); -} - -void cstate_restore_tsc(void) -{ - struct cpu_time *t = &this_cpu(cpu_time); - u64 plt_count_delta, tsc_delta; - - if ( tsc_invariant ) - return; - - 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); + stime_delta = read_platform_stime() - t->stime_master_stamp; + if ( stime_delta < 0 ) + stime_delta = 0; + + tsc_delta = scale_delta(stime_delta, &sys_to_tsc); + + wrmsrl(MSR_IA32_TSC, t->local_tsc_stamp + tsc_delta); } /*************************************************************************** diff -r 5e066dc410ac -r eed39afde7dd xen/include/xen/time.h --- a/xen/include/xen/time.h Fri Dec 05 11:37:20 2008 +0000 +++ b/xen/include/xen/time.h Fri Dec 05 13:03:44 2008 +0000 @@ -13,7 +13,6 @@ #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 |