[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] X86: Prefer TSC-deadline timer in Xen
# HG changeset patch # User Keir Fraser <keir@xxxxxxx> # Date 1288345214 -3600 # Node ID fb34514bf76bf575164ff83130b1cf9c8e3fea5a # Parent b48d8f27fca251c2df0222d195ffcb772d6a1128 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] =3D 1 as documented in the Intel Architecture 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> Signed-off-by: Keir Fraser <keir@xxxxxxx> --- xen/arch/x86/apic.c | 28 ++++++++++++++++++++++++++++ xen/arch/x86/time.c | 28 +++++++++++++++------------- xen/include/asm-x86/cpufeature.h | 1 + xen/include/asm-x86/msr-index.h | 2 ++ xen/include/asm-x86/time.h | 2 ++ xen/include/xen/time.h | 4 +++- 6 files changed, 51 insertions(+), 14 deletions(-) diff -r b48d8f27fca2 -r fb34514bf76b xen/arch/x86/apic.c --- a/xen/arch/x86/apic.c Fri Oct 29 10:29:14 2010 +0100 +++ b/xen/arch/x86/apic.c Fri Oct 29 10:40:14 2010 +0100 @@ -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 __read_mostly; +static int tdt_enable __initdata = 1; +boolean_param("tdt", tdt_enable); 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_enable && 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); @@ -1359,6 +1381,12 @@ int reprogram_timer(s_time_t timeout) /* No local APIC: timer list is polled via the PIT interrupt. */ if ( !cpu_has_apic ) return 1; + + if ( tdt_enabled ) + { + wrmsrl(MSR_IA32_TSC_DEADLINE, timeout ? stime2tsc(timeout) : 0); + return 1; + } if ( timeout && ((expire = timeout - NOW()) > 0) ) apic_tmict = min_t(u64, (bus_scale * expire) >> 18, UINT_MAX); diff -r b48d8f27fca2 -r fb34514bf76b xen/arch/x86/time.c --- a/xen/arch/x86/time.c Fri Oct 29 10:29:14 2010 +0100 +++ b/xen/arch/x86/time.c Fri Oct 29 10:40:14 2010 +0100 @@ -662,26 +662,28 @@ 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; - + + 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; + + return t->local_tsc_stamp + scale_delta(stime_delta, &sys_to_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 b48d8f27fca2 -r fb34514bf76b xen/include/asm-x86/cpufeature.h --- a/xen/include/asm-x86/cpufeature.h Fri Oct 29 10:29:14 2010 +0100 +++ b/xen/include/asm-x86/cpufeature.h Fri Oct 29 10:40:14 2010 +0100 @@ -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 b48d8f27fca2 -r fb34514bf76b xen/include/asm-x86/msr-index.h --- a/xen/include/asm-x86/msr-index.h Fri Oct 29 10:29:14 2010 +0100 +++ b/xen/include/asm-x86/msr-index.h Fri Oct 29 10:40:14 2010 +0100 @@ -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 b48d8f27fca2 -r fb34514bf76b xen/include/asm-x86/time.h --- a/xen/include/asm-x86/time.h Fri Oct 29 10:29:14 2010 +0100 +++ b/xen/include/asm-x86/time.h Fri Oct 29 10:40:14 2010 +0100 @@ -74,4 +74,6 @@ void cpuid_time_leaf(uint32_t sub_idx, u void cpuid_time_leaf(uint32_t sub_idx, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx); +u64 stime2tsc(s_time_t stime); + #endif /* __X86_TIME_H__ */ diff -r b48d8f27fca2 -r fb34514bf76b xen/include/xen/time.h --- a/xen/include/xen/time.h Fri Oct 29 10:29:14 2010 +0100 +++ b/xen/include/xen/time.h Fri Oct 29 10:40:14 2010 +0100 @@ -10,7 +10,6 @@ #include <xen/types.h> #include <public/xen.h> -#include <asm/time.h> extern int init_xen_time(void); extern void cstate_restore_tsc(void); @@ -18,6 +17,7 @@ extern unsigned long cpu_khz; extern unsigned long cpu_khz; struct domain; +struct vcpu; /* * System Time @@ -63,6 +63,8 @@ extern void send_timer_event(struct vcpu void domain_set_time_offset(struct domain *d, int32_t time_offset_seconds); +#include <asm/time.h> + #endif /* __XEN_TIME_H__ */ /* _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |