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-changelog

[Xen-changelog] [xen-unstable] x86: Add TSC stop support for Deep C stat

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: Add TSC stop support for Deep C state
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 01 May 2008 03:00:26 -0700
Delivery-date: Thu, 01 May 2008 07:47:57 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86: Add TSC stop support for Deep C state, Xen patchbot-unstable <=