WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] RE: [PATCH] CPUIDLE: revise tsc-save/restore to avoid big ts

To: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
Subject: [Xen-devel] RE: [PATCH] CPUIDLE: revise tsc-save/restore to avoid big tsc skew between cpus
From: "Wei, Gang" <gang.wei@xxxxxxxxx>
Date: Fri, 5 Dec 2008 19:30:03 +0800
Accept-language: en-US
Acceptlanguage: en-US
Cc: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Fri, 05 Dec 2008 03:30:47 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <8FED46E8A9CA574792FC7AACAC38FE7701C589A53D@xxxxxxxxxxxxxxxxxxxxxxxxxxxx> <C55E9C9D.1FE03%keir.fraser@xxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: AclWoeM2xc+X6mj6QOaQHsyxDmpzagAFRoNpAACb7OAABH8KUA==
Thread-topic: [PATCH] CPUIDLE: revise tsc-save/restore to avoid big tsc skew between cpus
> I tried extrapolating from t->stime_local_stamp, cpu_khz, and
> t->local_tsc_stamp before I got into the current solution. It would still
> bring accumulating skew, but in a slower increasing speed. I would like to
> try it again with  t->tsc_scale instead of cpu_khz. If it is works, it would
> really be simpler. Allow me some time.    

Below patch should be what you expected. It will still bring continuously 
increasing tsc skew. If I pin all domains' vcpus on 1 pcpu, the skew is 
increasing faster. 

diff -r 1b173394f815 xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c      Thu Dec 04 16:36:43 2008 +0000
+++ b/xen/arch/x86/acpi/cpu_idle.c      Fri Dec 05 19:06:06 2008 +0800
@@ -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 1b173394f815 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Thu Dec 04 16:36:43 2008 +0000
+++ b/xen/arch/x86/time.c       Fri Dec 05 19:06:06 2008 +0800
@@ -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 {
@@ -149,6 +147,32 @@ static inline u64 scale_delta(u64 delta,
 #endif
 
     return product;
+}
+
+/*
+ * Scale a 32-bit time delta to delta by dividing a 32-bit fraction & scaling,
+ * yielding a 64-bit result.
+ */
+static inline u64 scale_time(u32 time_delta, struct time_scale *scale)
+{
+    u64 td64 = time_delta;
+    u64 quotient, remainder;
+
+    td64 <<= 32;
+
+    quotient = td64 / scale->mul_frac;
+    remainder = td64 % scale->mul_frac;
+
+    if ( scale->shift < 0 )
+    {
+        quotient <<= -scale->shift;
+        remainder <<= -scale->shift;
+        quotient += remainder / scale->mul_frac;
+    }
+    else
+        quotient >>= scale->shift;
+
+    return quotient;
 }
 
 /*
@@ -644,29 +668,19 @@ 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);
+    u64 tsc_delta;
+    s_time_t stime_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_local_stamp;
+    ASSERT(stime_delta < 0x100000000UL);
+    tsc_delta = scale_time((u32)stime_delta, &t->tsc_scale);
+    wrmsrl(MSR_IA32_TSC, t->local_tsc_stamp + tsc_delta);
 }
 
 /***************************************************************************
diff -r 1b173394f815 xen/include/xen/time.h
--- a/xen/include/xen/time.h    Thu Dec 04 16:36:43 2008 +0000
+++ b/xen/include/xen/time.h    Fri Dec 05 19:06:06 2008 +0800
@@ -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;

Jimmy
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>