aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVojtech Pavlik <vojtech@suse.cz>2006-09-26 04:52:28 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:28 -0400
commita670fad0adb1cc6202a607d250f10bd380593905 (patch)
tree697d27fe0c92a65829f727f17f7048d46a675e4d
parent81af4449af9c9b686a4eeeb00112614621655704 (diff)
[PATCH] Add initalization of the RDTSCP auxilliary values
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. AK: Some cleanups. Move externs into headers and fix CPU hotplug. Signed-off-by: Vojtech Pavlik <vojtech@suse.cz> Signed-off-by: Andi Kleen <ak@suse.de>
-rw-r--r--arch/x86_64/kernel/smpboot.c2
-rw-r--r--arch/x86_64/kernel/time.c47
-rw-r--r--include/asm-x86_64/proto.h1
3 files changed, 38 insertions, 12 deletions
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 15555879ce95..582896f7d420 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -1181,6 +1181,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
1181#endif 1181#endif
1182 1182
1183 check_nmi_watchdog(); 1183 check_nmi_watchdog();
1184
1185 time_init_gtod();
1184} 1186}
1185 1187
1186#ifdef CONFIG_HOTPLUG_CPU 1188#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 7a9b18224182..97b9e46d1992 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -24,6 +24,8 @@
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/sysdev.h> 25#include <linux/sysdev.h>
26#include <linux/bcd.h> 26#include <linux/bcd.h>
27#include <linux/notifier.h>
28#include <linux/cpu.h>
27#include <linux/kallsyms.h> 29#include <linux/kallsyms.h>
28#include <linux/acpi.h> 30#include <linux/acpi.h>
29#ifdef CONFIG_ACPI 31#ifdef CONFIG_ACPI
@@ -49,7 +51,7 @@ static void cpufreq_delayed_get(void);
49extern void i8254_timer_resume(void); 51extern void i8254_timer_resume(void);
50extern int using_apic_timer; 52extern int using_apic_timer;
51 53
52static char *time_init_gtod(void); 54static char *timename = NULL;
53 55
54DEFINE_SPINLOCK(rtc_lock); 56DEFINE_SPINLOCK(rtc_lock);
55EXPORT_SYMBOL(rtc_lock); 57EXPORT_SYMBOL(rtc_lock);
@@ -893,11 +895,21 @@ static struct irqaction irq0 = {
893 timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL 895 timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
894}; 896};
895 897
896void __init time_init(void) 898static int __cpuinit
899time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu)
897{ 900{
898 char *timename; 901 unsigned cpu = (unsigned long) hcpu;
899 char *gtod; 902 if (action == CPU_ONLINE &&
903 cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) {
904 unsigned p;
905 p = smp_processor_id() | (cpu_to_node(smp_processor_id())<<12);
906 write_rdtscp_aux(p);
907 }
908 return NOTIFY_DONE;
909}
900 910
911void __init time_init(void)
912{
901 if (nohpet) 913 if (nohpet)
902 vxtime.hpet_address = 0; 914 vxtime.hpet_address = 0;
903 915
@@ -931,18 +943,19 @@ void __init time_init(void)
931 } 943 }
932 944
933 vxtime.mode = VXTIME_TSC; 945 vxtime.mode = VXTIME_TSC;
934 gtod = time_init_gtod();
935
936 printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
937 vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod);
938 printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
939 cpu_khz / 1000, cpu_khz % 1000);
940 vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; 946 vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
941 vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; 947 vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
942 vxtime.last_tsc = get_cycles_sync(); 948 vxtime.last_tsc = get_cycles_sync();
943 setup_irq(0, &irq0); 949 setup_irq(0, &irq0);
944 950
945 set_cyc2ns_scale(cpu_khz); 951 set_cyc2ns_scale(cpu_khz);
952
953 hotcpu_notifier(time_cpu_notifier, 0);
954 time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id());
955
956#ifndef CONFIG_SMP
957 time_init_gtod();
958#endif
946} 959}
947 960
948/* 961/*
@@ -973,12 +986,13 @@ __cpuinit int unsynchronized_tsc(void)
973/* 986/*
974 * Decide what mode gettimeofday should use. 987 * Decide what mode gettimeofday should use.
975 */ 988 */
976__init static char *time_init_gtod(void) 989void time_init_gtod(void)
977{ 990{
978 char *timetype; 991 char *timetype;
979 992
980 if (unsynchronized_tsc()) 993 if (unsynchronized_tsc())
981 notsc = 1; 994 notsc = 1;
995
982 if (vxtime.hpet_address && notsc) { 996 if (vxtime.hpet_address && notsc) {
983 timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; 997 timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
984 if (hpet_use_timer) 998 if (hpet_use_timer)
@@ -1001,7 +1015,16 @@ __init static char *time_init_gtod(void)
1001 timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC"; 1015 timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC";
1002 vxtime.mode = VXTIME_TSC; 1016 vxtime.mode = VXTIME_TSC;
1003 } 1017 }
1004 return timetype; 1018
1019 printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
1020 vxtime_hz / 1000000, vxtime_hz % 1000000, timename, timetype);
1021 printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
1022 cpu_khz / 1000, cpu_khz % 1000);
1023 vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
1024 vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
1025 vxtime.last_tsc = get_cycles_sync();
1026
1027 set_cyc2ns_scale(cpu_khz);
1005} 1028}
1006 1029
1007__setup("report_lost_ticks", time_setup); 1030__setup("report_lost_ticks", time_setup);
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index 038fe1f47e6f..3b1c60247902 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -51,6 +51,7 @@ extern unsigned long long monotonic_base;
51extern int sysctl_vsyscall; 51extern int sysctl_vsyscall;
52extern int nohpet; 52extern int nohpet;
53extern unsigned long vxtime_hz; 53extern unsigned long vxtime_hz;
54extern void time_init_gtod(void);
54 55
55extern int numa_setup(char *opt); 56extern int numa_setup(char *opt);
56 57