Add initalization of the RDTSCP auxilliary values From: Vojtech Pavlik This patch adds initalization of the RDTSCP auxilliary values to CPU numbers to time.c. If RDTSCP is available, the MSRs are written with the respective values. It can be later used to initalize per-cpu timekeeping variables. Signed-off-by: Vojtech Pavlik Signed-off-by: Andi Kleen --- arch/x86_64/kernel/smpboot.c | 4 ++++ arch/x86_64/kernel/time.c | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 12 deletions(-) Index: linux/arch/x86_64/kernel/time.c =================================================================== --- linux.orig/arch/x86_64/kernel/time.c +++ linux/arch/x86_64/kernel/time.c @@ -48,7 +48,7 @@ static void cpufreq_delayed_get(void); extern void i8254_timer_resume(void); extern int using_apic_timer; -static char *time_init_gtod(void); +static char *timename = NULL; DEFINE_SPINLOCK(rtc_lock); DEFINE_SPINLOCK(i8253_lock); @@ -892,9 +892,6 @@ static struct irqaction irq0 = { void __init time_init(void) { - char *timename; - char *gtod; - if (nohpet) vxtime.hpet_address = 0; @@ -928,18 +925,17 @@ void __init time_init(void) } vxtime.mode = VXTIME_TSC; - gtod = time_init_gtod(); - - printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n", - vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod); - printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", - cpu_khz / 1000, cpu_khz % 1000); vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; vxtime.last_tsc = get_cycles_sync(); setup_irq(0, &irq0); set_cyc2ns_scale(cpu_khz); + + +#ifndef CONFIG_SMP + time_init_gtod(); +#endif } /* @@ -960,15 +956,28 @@ __cpuinit int unsynchronized_tsc(void) return num_present_cpus() > 1; } +static void __init time_init_rdtsc(void *info) +{ + int p; + p = smp_processor_id(); + write_rdtscp_aux(p); +} + /* * Decide what mode gettimeofday should use. */ -__init static char *time_init_gtod(void) +void time_init_gtod(void) { char *timetype; if (unsynchronized_tsc()) notsc = 1; + + if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) { + printk(KERN_INFO "time.c: Initializing RDTSCP feature.\n"); + on_each_cpu(time_init_rdtsc, NULL, 1, 1); + } + if (vxtime.hpet_address && notsc) { timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; if (hpet_use_timer) @@ -991,7 +1000,16 @@ __init static char *time_init_gtod(void) timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC"; vxtime.mode = VXTIME_TSC; } - return timetype; + + printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n", + vxtime_hz / 1000000, vxtime_hz % 1000000, timename, timetype); + printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", + cpu_khz / 1000, cpu_khz % 1000); + vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; + vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; + vxtime.last_tsc = get_cycles_sync(); + + set_cyc2ns_scale(cpu_khz); } __setup("report_lost_ticks", time_setup); Index: linux/arch/x86_64/kernel/smpboot.c =================================================================== --- linux.orig/arch/x86_64/kernel/smpboot.c +++ linux/arch/x86_64/kernel/smpboot.c @@ -1163,6 +1163,8 @@ int __cpuinit __cpu_up(unsigned int cpu) return err; } +extern void time_init_gtod(void); + /* * Finish the SMP boot. */ @@ -1175,6 +1177,8 @@ void __init smp_cpus_done(unsigned int m #endif check_nmi_watchdog(); + + time_init_gtod(); } #ifdef CONFIG_HOTPLUG_CPU