Re: [PATCH] tsc-disable_B9

From: Alan Cox (alan@lxorguk.ukuu.org.uk)
Date: Thu Aug 08 2002 - 08:17:43 EST


On Thu, 2002-08-08 at 02:53, john stultz wrote:
> already seen on another cpu. This patch allows people compiling w/
> 'Multi-node NUMA support' to pass "notsc" or "bad-tsc" as boot
> parameters. "notsc" disables rdtsc calls, and forces the kernel to use
> the PIT for gettimeofday calucluations (as normally expected w/ i386
> compiled kernels). While "bad-tsc" forces the kernel to use the PIT for
> gettimeofday, but does not disable TSC access.

I've done a version of this for -ac which uses the NUMA autodetect, and
also provides the hook so I can disable tsc on split on x86 smp with
variable multipliers some time. The only comment I really have is please
use "badtsc" not "bad-tsc" - to match "notsc"

This is how I did it - barring the code that is -ac specific to automatically flip
the mode when NUMA hw is detected

diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.20pre1/include/asm-i386/processor.h linux.20pre1-ac2/include/asm-i386/processor.h
--- linux.20pre1/include/asm-i386/processor.h 2002-08-06 15:40:34.000000000 +0100
+++ linux.20pre1-ac2/include/asm-i386/processor.h 2002-08-07 15:23:39.000000000 +0100
@@ -96,7 +96,7 @@
 
 extern void identify_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
-extern void dodgy_tsc(void);
+extern int dodgy_tsc(void);
 
 /*
  * EFLAGS bits
--- linux.vanilla/arch/i386/kernel/time.c 2002-02-25 19:37:53.000000000 +0000
+++ linux.20pre1-ac2/arch/i386/kernel/time.c 2002-08-08 12:56:48.000000000 +0100
@@ -666,9 +666,7 @@
           * moaned if you have the only one in the world - you fix it!
           */
  
- dodgy_tsc();
-
- if (cpu_has_tsc) {
+ if (!dodgy_tsc()) {
                 unsigned long tsc_quotient = calibrate_tsc();
                 if (tsc_quotient) {
                         fast_gettimeoffset_quotient = tsc_quotient;
diff -u --exclude-from /usr/src/exclude --new-file --recursive linux.20pre1/arch/i386/kernel/setup.c linux.20pre1-ac2/arch/i386/kernel/setup.c
--- linux.20pre1/arch/i386/kernel/setup.c 2002-08-06 15:41:42.000000000 +0100
+++ linux.20pre1-ac2/arch/i386/kernel/setup.c 2002-08-07 15:23:29.000000000 +0100
@@ -1193,19 +1126,51 @@
 }
 __setup("cachesize=", cachesize_setup);
 
-
 #ifndef CONFIG_X86_TSC
+
 static int tsc_disable __initdata = 0;
 
-static int __init tsc_setup(char *str)
+void disable_tsc(void)
+{
+ if(tsc_disable == 0)
+ {
+ printk(KERN_INFO "Disabling use of TSC for time counting.\n");
+ tsc_disable = 1;
+ }
+}
+
+/* Disable TSC on processor and also for get time of day */
+
+static int __init notsc_setup(char *str)
+{
+ tsc_disable = 2;
+ return 1;
+}
+
+__setup("notsc", notsc_setup);
+
+/* Allow TSC use but don't use it for gettimeofday */
+
+static int __init badtsc_setup(char *str)
 {
         tsc_disable = 1;
         return 1;
 }
 
-__setup("notsc", tsc_setup);
+__setup("badtsc", badtsc_setup);
+
+#else
+
+#define tsc_disable 0
+
+void disable_tsc(void)
+{
+ panic("Time stamp counter required by this kernel, but not supported by the hardware.\n");
+}
+
 #endif
 
+
 static int __init get_model_name(struct cpuinfo_x86 *c)
 {
         unsigned int *v;
@@ -2843,10 +2762,8 @@
          */
 
         /* TSC disabled? */
-#ifndef CONFIG_X86_TSC
- if ( tsc_disable )
+ if ( tsc_disable > 1 )
                 clear_bit(X86_FEATURE_TSC, &c->x86_capability);
-#endif
 
         /* HT disabled? */
         if (disable_x86_ht)
@@ -2906,13 +2823,23 @@
  * Perform early boot up checks for a valid TSC. See arch/i386/kernel/time.c
  */
  
-void __init dodgy_tsc(void)
+int __init dodgy_tsc(void)
 {
         get_cpu_vendor(&boot_cpu_data);
 
         if ( boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX ||
              boot_cpu_data.x86_vendor == X86_VENDOR_NSC )
                 init_cyrix(&boot_cpu_data);
+
+ /* Is it disabled ? */
+ if(tsc_disable)
+ return 1;
+
+ /* Does it exist ? */
+ if(!cpu_has_tsc)
+ return 1;
+
+ return 0;
 }
 

@@ -3088,14 +3021,12 @@
 
         if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
                 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
-#ifndef CONFIG_X86_TSC
- if (tsc_disable && cpu_has_tsc) {
+ if (tsc_disable > 1 && cpu_has_tsc) {
                 printk(KERN_NOTICE "Disabling TSC...\n");
                 /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/
                 clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability);
                 set_in_cr4(X86_CR4_TSD);
         }
-#endif
 
         __asm__ __volatile__("lgdt %0": "=m" (gdt_descr));
         __asm__ __volatile__("lidt %0": "=m" (idt_descr));
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Aug 15 2002 - 22:00:16 EST