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] [PATCH] X86: Prefer TSC-deadline timer in Xen

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] X86: Prefer TSC-deadline timer in Xen
From: "Wei, Gang" <gang.wei@xxxxxxxxx>
Date: Thu, 28 Oct 2010 13:45:32 +0800
Accept-language: zh-CN, en-US
Acceptlanguage: zh-CN, en-US
Cc: "Brown, Len" <len.brown@xxxxxxxxx>, Keir Fraser <keir.fraser@xxxxxxxxxxxxx>, "Wei, Gang" <gang.wei@xxxxxxxxx>
Delivery-date: Wed, 27 Oct 2010 22:46:46 -0700
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>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: Act2Y1XzoXFwqtIOSSaqXp+DLguJhw==
Thread-topic: [PATCH] X86: Prefer TSC-deadline timer in Xen
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] = 1 as documented in the Intel Architectures
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@xxxxxxxxx>
Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx>

diff -r 00b92112b055 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Wed Oct 20 17:26:51 2010 +0100
+++ b/xen/arch/x86/apic.c       Fri Oct 29 19:24:56 2010 +0800
@@ -37,6 +37,15 @@
 #include <asm/asm_defns.h> /* for BUILD_SMP_INTERRUPT */
 #include <mach_apic.h>
 #include <io_ports.h>
+
+#define APIC_TIMER_MODE_ONESHOT         (0 << 17)
+#define APIC_TIMER_MODE_PERIODIC        (1 << 17)
+#define APIC_TIMER_MODE_TSC_DEADLINE    (2 << 17)
+#define APIC_TIMER_MODE_MASK            (3 << 17)
+
+static int tdt_enabled;
+static int tdt_disable;
+boolean_param("tdt_off", tdt_disable);
 
 static struct {
     int active;
@@ -1198,6 +1207,13 @@ static void __setup_APIC_LVTT(unsigned i
     lvtt_value = /*APIC_LVT_TIMER_PERIODIC |*/ LOCAL_TIMER_VECTOR;
     if (!APIC_INTEGRATED(ver))
         lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV);
+
+    if (tdt_enabled)
+    {
+        lvtt_value &= (~APIC_TIMER_MODE_MASK);
+        lvtt_value |= APIC_TIMER_MODE_TSC_DEADLINE;
+    }
+
     apic_write_around(APIC_LVTT, lvtt_value);
 
     tmp_value = apic_read(APIC_TDCR);
@@ -1311,6 +1327,12 @@ void __init setup_boot_APIC_clock(void)
 
     calibrate_APIC_clock();
 
+    if (!tdt_disable && boot_cpu_has(X86_FEATURE_TSC_DEADLINE))
+    {
+        printk(KERN_DEBUG "TSC deadline timer enabled\n");
+        tdt_enabled = 1;
+    }
+
     setup_APIC_timer();
     
     local_irq_restore(flags);
@@ -1360,12 +1382,24 @@ int reprogram_timer(s_time_t timeout)
     if ( !cpu_has_apic )
         return 1;
 
-    if ( timeout && ((expire = timeout - NOW()) > 0) )
-        apic_tmict = min_t(u64, (bus_scale * expire) >> 18, UINT_MAX);
-
-    apic_write(APIC_TMICT, (unsigned long)apic_tmict);
-
-    return apic_tmict || !timeout;
+    if ( tdt_enabled )
+    {
+        u64 tsc = 0;
+
+        if ( timeout )
+            tsc = stime2tsc(timeout);
+
+        wrmsrl(MSR_IA32_TSC_DEADLINE, tsc);
+    }
+    else
+    {
+        if ( timeout && ((expire = timeout - NOW()) > 0) )
+            apic_tmict = min_t(u64, (bus_scale * expire) >> 18, UINT_MAX);
+
+        apic_write(APIC_TMICT, (unsigned long)apic_tmict);
+    }
+
+    return apic_tmict || !timeout || tdt_enabled;
 }
 
 fastcall void smp_apic_timer_interrupt(struct cpu_user_regs * regs)
diff -r 00b92112b055 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Wed Oct 20 17:26:51 2010 +0100
+++ b/xen/arch/x86/time.c       Fri Oct 29 19:28:07 2010 +0800
@@ -662,26 +662,31 @@ static void __init init_platform_timer(v
            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;
-
+    u64 tsc;
+
+    t = &this_cpu(cpu_time);
+    sys_to_tsc = scale_reciprocal(t->tsc_scale);
+
+    stime_delta = stime - t->stime_local_stamp;
+    if ( stime_delta < 0 )
+        stime_delta = 0;
+
+    tsc = t->local_tsc_stamp + scale_delta(stime_delta, &sys_to_tsc);
+
+    return tsc;
+}
+
+void cstate_restore_tsc(void)
+{
     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;
-    if ( stime_delta < 0 )
-        stime_delta = 0;
-
-    new_tsc = t->local_tsc_stamp + scale_delta(stime_delta, &sys_to_tsc);
-
-    write_tsc(new_tsc);
+    write_tsc(stime2tsc(read_platform_stime()));
 }
 
 /***************************************************************************
diff -r 00b92112b055 xen/include/asm-x86/cpufeature.h
--- a/xen/include/asm-x86/cpufeature.h  Wed Oct 20 17:26:51 2010 +0100
+++ b/xen/include/asm-x86/cpufeature.h  Fri Oct 29 19:21:36 2010 +0800
@@ -99,6 +99,7 @@
 #define X86_FEATURE_SSE4_2     (4*32+20) /* Streaming SIMD Extensions 4.2 */
 #define X86_FEATURE_X2APIC     (4*32+21) /* Extended xAPIC */
 #define X86_FEATURE_POPCNT     (4*32+23) /* POPCNT instruction */
+#define X86_FEATURE_TSC_DEADLINE (4*32+24) /* "tdt" TSC Deadline Timer */
 #define X86_FEATURE_XSAVE      (4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
 #define X86_FEATURE_OSXSAVE    (4*32+27) /* OSXSAVE */
 #define X86_FEATURE_HYPERVISOR (4*32+31) /* Running under some hypervisor */
diff -r 00b92112b055 xen/include/asm-x86/msr-index.h
--- a/xen/include/asm-x86/msr-index.h   Wed Oct 20 17:26:51 2010 +0100
+++ b/xen/include/asm-x86/msr-index.h   Fri Oct 29 19:21:36 2010 +0800
@@ -327,6 +327,8 @@
 #define MSR_IA32_MISC_ENABLE_MONITOR_ENABLE (1<<18)
 #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID  (1<<22)
 #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1<<23)
+
+#define MSR_IA32_TSC_DEADLINE          0x000006E0
 
 /* Intel Model 6 */
 #define MSR_P6_EVNTSEL0                        0x00000186
diff -r 00b92112b055 xen/include/xen/time.h
--- a/xen/include/xen/time.h    Wed Oct 20 17:26:51 2010 +0100
+++ b/xen/include/xen/time.h    Fri Oct 29 19:21:36 2010 +0800
@@ -31,6 +31,7 @@ typedef s64 s_time_t;
 typedef s64 s_time_t;
 
 s_time_t get_s_time(void);
+u64 stime2tsc(s_time_t stime);
 unsigned long get_localtime(struct domain *d);
 
 struct tm {

Attachment: tdt-host-support.patch
Description: tdt-host-support.patch

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