Working in the lab, we have found a bug where Linux 2.2.14 fails to
boot if a x86 processor is faster than 4.3Ghz. This is caused because
it uses the rdtsc to calculate the processor speed in hz. Since the
result is a 32-bit number, the frequency can not be allowed to be
> 2**32.
Enclosed is a simple patch make calculates cpu_khz instead of cpu_hz.
Please include this in the kernel source.
Think of this as a Y2K-like bug waiting to happen, I want Linux to be
ready. :)
PS: We do NOT have a processor running this fast, just one that lies
to the OS.
Wayne Scott WMT Architecture - Intel Corp.
wscott@ichips.intel.com Work #: (503) 613-5063
Disclaimer: All views expressed are my own opinions, and not necessarily
those of Intel Corporation.
diff -ur kernel-source-2.2.14/arch/i386/kernel/setup.c ../kernel-source-2.2.14-kni/arch/i386/kernel/setup.c
--- kernel-source-2.2.14/arch/i386/kernel/setup.c Tue Jan 4 10:12:11 2000
+++ ../kernel-source-2.2.14-kni/arch/i386/kernel/setup.c Fri Mar 17 11:19:04 2000
@@ -102,7 +102,7 @@
extern int root_mountflags;
extern int _etext, _edata, _end;
-extern unsigned long cpu_hz;
+extern unsigned long cpu_khz;
/*
* This is set up by the setup-routine at boot-time
@@ -996,8 +996,8 @@
p += sprintf(p, "stepping\t: unknown\n");
if (c->x86_capability & X86_FEATURE_TSC) {
- p += sprintf(p, "cpu MHz\t\t: %lu.%06lu\n",
- cpu_hz / 1000000, (cpu_hz % 1000000));
+ p += sprintf(p, "cpu MHz\t\t: %lu.%03lu\n",
+ cpu_khz / 1000, cpu_khz % 1000);
}
/* Cache size */
diff -ur kernel-source-2.2.14/arch/i386/kernel/smp.c ../kernel-source-2.2.14-kni/arch/i386/kernel/smp.c
--- kernel-source-2.2.14/arch/i386/kernel/smp.c Tue Jan 4 10:12:11 2000
+++ ../kernel-source-2.2.14-kni/arch/i386/kernel/smp.c Fri Mar 17 11:20:12 2000
@@ -1149,7 +1155,7 @@
}
cycles_t cacheflush_time;
-extern unsigned long cpu_hz;
+extern unsigned long cpu_khz;
static void smp_tune_scheduling (void)
{
@@ -1165,7 +1171,7 @@
* the cache size)
*/
- if (!cpu_hz) {
+ if (!cpu_khz) {
/*
* this basically disables processor-affinity
* scheduling on SMP without a TSC.
@@ -1177,12 +1183,12 @@
if (cachesize == -1)
cachesize = 8; /* Pentiums */
- cacheflush_time = cpu_hz/1024*cachesize/5000;
+ cacheflush_time = cpu_khz/1024*cachesize/5;
}
printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n",
- (long)cacheflush_time/(cpu_hz/1000000),
- ((long)cacheflush_time*100/(cpu_hz/1000000)) % 100);
+ (long)cacheflush_time/(cpu_khz/1000),
+ ((long)cacheflush_time*100/(cpu_khz/1000)) % 100);
}
unsigned int prof_multiplier[NR_CPUS];
diff -ur kernel-source-2.2.14/arch/i386/kernel/time.c ../kernel-source-2.2.14-kni/arch/i386/kernel/time.c
--- kernel-source-2.2.14/arch/i386/kernel/time.c Thu Apr 29 11:53:41 1999
+++ ../kernel-source-2.2.14-kni/arch/i386/kernel/time.c Fri Mar 17 11:26:49 2000
@@ -62,7 +62,7 @@
#include "irq.h"
-unsigned long cpu_hz; /* Detected as we calibrate the TSC */
+unsigned long cpu_khz; /* Detected as we calibrate the TSC */
/* Number of usecs that the last interrupt was delayed */
static int delay_at_last_interrupt;
@@ -658,12 +658,12 @@
* The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
* clock/second. Our precision is about 100 ppm.
*/
- { unsigned long eax=0, edx=1000000;
+ { unsigned long eax=0, edx=1000;
__asm__("divl %2"
- :"=a" (cpu_hz), "=d" (edx)
+ :"=a" (cpu_khz), "=d" (edx)
:"r" (tsc_quotient),
"0" (eax), "1" (edx));
- printk("Detected %ld Hz processor.\n", cpu_hz);
+ printk("Detected %ld kHz processor.\n", cpu_khz);
}
}
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Thu Mar 23 2000 - 21:00:31 EST