Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 2503

kernel-2.6.18-128.1.10.el5.src.rpm

Date: Mon, 02 Oct 2006 16:15:54 -0400
From: Bhavana Nagendra <bnagendr@redhat.com>
Subject: Re: [RHEL 5 NEW PATCH] : Adding support for RDTSCP and vgetcpu syscall

--- linux-2.6.17.x86_64/arch/x86_64/kernel/time.c.orig	2006-10-02 15:56:53.000000000 -0400
+++ linux-2.6.17.x86_64/arch/x86_64/kernel/time.c	2006-10-02 16:10:28.000000000 -0400
@@ -24,6 +24,8 @@
 #include <linux/device.h>
 #include <linux/sysdev.h>
 #include <linux/bcd.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
 #include <linux/kallsyms.h>
 #include <linux/acpi.h>
 #ifdef CONFIG_ACPI
@@ -49,7 +51,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);
 EXPORT_SYMBOL(rtc_lock);
@@ -893,11 +895,22 @@ static struct irqaction irq0 = {
 	timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
 };
 
-void __init time_init(void)
+static int __cpuinit
+time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu)
 {
-	char *timename;
-	char *gtod;
+	unsigned cpu = (unsigned long) hcpu;
+
+	if (action == CPU_ONLINE && cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) {
+		unsigned p;
+		p = smp_processor_id() | (cpu_to_node(smp_processor_id())<<12);
+		write_rdtscp_aux(p);
+	}
 
+	return NOTIFY_DONE;
+}
+
+void __init time_init(void)
+{
 	if (nohpet)
 		vxtime.hpet_address = 0;
 
@@ -931,18 +944,19 @@ 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);
+
+	hotcpu_notifier(time_cpu_notifier, 0);
+	time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id());
+
+#ifndef CONFIG_SMP
+	time_init_gtod();
+#endif
 }
 
 /*
@@ -962,6 +976,11 @@ __cpuinit int unsynchronized_tsc(void)
 		/* But TSC doesn't tick in C3 so don't use it there */
 		if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
 			return 1;
+
+		/* AMD systems with constant TSCs have synchronized clocks */
+		if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && 
+			(boot_cpu_has(X86_FEATURE_CONSTANT_TSC)))
+			return 0;
 #endif
  		return 0;
 	}
@@ -973,12 +992,13 @@ __cpuinit int unsynchronized_tsc(void)
 /*
  * 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 (vxtime.hpet_address && notsc) {
 		timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
 		if (hpet_use_timer)
@@ -1001,7 +1021,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);
--- linux-2.6.17.x86_64/arch/x86_64/kernel/smpboot.c.orig	2006-10-02 15:56:47.000000000 -0400
+++ linux-2.6.17.x86_64/arch/x86_64/kernel/smpboot.c	2006-10-02 15:57:07.000000000 -0400
@@ -1181,6 +1181,8 @@ void __init smp_cpus_done(unsigned int m
 #endif
 
 	check_nmi_watchdog();
+
+	time_init_gtod();
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
--- linux-2.6.17.x86_64/include/asm-x86_64/proto.h.orig	2006-10-02 15:56:36.000000000 -0400
+++ linux-2.6.17.x86_64/include/asm-x86_64/proto.h	2006-10-02 15:57:07.000000000 -0400
@@ -49,6 +49,7 @@ extern unsigned long long monotonic_base
 extern int sysctl_vsyscall;
 extern int nohpet;
 extern unsigned long vxtime_hz;
+extern void time_init_gtod(void);
 
 extern int numa_setup(char *opt);
 
--- linux-2.6.17.x86_64/include/asm-x86_64/msr.h.orig	2006-10-02 15:56:42.000000000 -0400
+++ linux-2.6.17.x86_64/include/asm-x86_64/msr.h	2006-10-02 16:05:22.000000000 -0400
@@ -66,14 +66,25 @@
 #define rdtscl(low) \
      __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx")
 
+#define rdtscp(low,high,aux) \
+	asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux))
+
 #define rdtscll(val) do { \
      unsigned int __a,__d; \
      asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
      (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
 } while(0)
 
+#define rdtscpll(val, aux) do { \
+	unsigned long __a, __d; \
+	asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \
+	(val) = (__d << 32) | __a; \
+} while (0)
+
 #define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
 
+#define write_rdtscp_aux(val) wrmsr(0xc0000103, val, 0)
+
 #define rdpmc(counter,low,high) \
      __asm__ __volatile__("rdpmc" \
 			  : "=a" (low), "=d" (high) \