[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Xen-devel] [PATCH] X86: Prefer TSC-deadline timer in Xen



The change to cstate_restore_tsc reminds me...

TSC should never be written if it is being used to
generate system time, and I think cstate_restore_tsc
is only used on systems where another clocksource
is used to generate system time.   (And it generates
a rather poor approximation of TSC.)  Are there any
machines where cstate_restore_tsc might get executed
but TSC_Deadline is in use?  If so, might there be
a race condition here?  Also, are there any
issues with using TSC Deadline on a system with
the potential for hot-add physical CPUs?

I suspect cstate_restore_tsc doesn't get executed
if TSC is reliable, and the TSC Deadline feature
is probably only available on systems where TSC
is reliable, but am not sure.

Thanks,
Dan

> -----Original Message-----
> From: Wei, Gang [mailto:gang.wei@xxxxxxxxx]
> Sent: Thursday, October 28, 2010 9:14 AM
> To: Keir Fraser; Tim Deegan
> Cc: Brown, Len; xen-devel@xxxxxxxxxxxxxxxxxxx; Wei, Gang; Jan Beulich
> Subject: RE: [Xen-devel] [PATCH] X86: Prefer TSC-deadline timer in Xen
> 
> Resend.
> 
> Jimmy
> ---------------------------------------------------------
> 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 0dc0bc411035 xen/arch/x86/apic.c
> --- a/xen/arch/x86/apic.c     Thu Oct 21 18:51:36 2010 +0100
> +++ b/xen/arch/x86/apic.c     Sat Oct 30 05:09:41 2010 +0800
> @@ -37,6 +37,14 @@
>  #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 = 1;
> +boolean_param("tdt", tdt_enabled);
> 
>  static struct {
>      int active;
> @@ -1198,6 +1206,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);
> @@ -1309,7 +1324,15 @@ void __init setup_boot_APIC_clock(void)
> 
>      local_irq_save(flags);
> 
> -    calibrate_APIC_clock();
> +    if ( tdt_enabled && boot_cpu_has(X86_FEATURE_TSC_DEADLINE) )
> +    {
> +        printk(KERN_DEBUG "TSC deadline timer enabled\n");
> +    }
> +    else
> +    {
> +        tdt_enabled = 0;
> +        calibrate_APIC_clock();
> +    }
> 
>      setup_APIC_timer();
> 
> @@ -1359,6 +1382,18 @@ 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 )
> +    {
> +        u64 tsc = 0;
> +
> +        if ( timeout )
> +            tsc = stime2tsc(timeout);
> +
> +        wrmsrl(MSR_IA32_TSC_DEADLINE, tsc);
> +
> +        return 1;
> +    }
> 
>      if ( timeout && ((expire = timeout - NOW()) > 0) )
>          apic_tmict = min_t(u64, (bus_scale * expire) >> 18, UINT_MAX);
> diff -r 0dc0bc411035 xen/arch/x86/time.c
> --- a/xen/arch/x86/time.c     Thu Oct 21 18:51:36 2010 +0100
> +++ b/xen/arch/x86/time.c     Sat Oct 30 04:28:14 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 0dc0bc411035 xen/include/asm-x86/cpufeature.h
> --- a/xen/include/asm-x86/cpufeature.h        Thu Oct 21 18:51:36 2010
> +0100
> +++ b/xen/include/asm-x86/cpufeature.h        Sat Oct 30 04:28:14 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 0dc0bc411035 xen/include/asm-x86/msr-index.h
> --- a/xen/include/asm-x86/msr-index.h Thu Oct 21 18:51:36 2010
> +0100
> +++ b/xen/include/asm-x86/msr-index.h Sat Oct 30 04:28:14 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 0dc0bc411035 xen/include/xen/time.h
> --- a/xen/include/xen/time.h  Thu Oct 21 18:51:36 2010 +0100
> +++ b/xen/include/xen/time.h  Sat Oct 30 04:28:14 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 {

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.