Most recent kernel where this bug did not occur: 2.6.13 Distribution: SuSE 9.2 Hardware Environment: HP ze1115 Notebook Software Environment: gcc 3.3.4 Problem Description: Wrong CPU frequency reported by powernow. Early in dmesg, the following is reported: Kernel command line: PROFILE=default root=/dev/hda4 psmouse.proto=exps lapic Local APIC disabled by BIOS -- reenabling. Found and enabled local APIC! mapped APIC to ffffd000 (fee00000) Initializing CPU#0 PID hash table entries: 4096 (order: 12, 65536 bytes) Detected 1100.134 MHz processor. This is the correct frequency, but near the end of dmesg is the following: powernow: PowerNOW! Technology present. Can scale: frequency and voltage. Detected 2366.570 MHz processor. powernow: No PST tables match this cpuid (0x771) powernow: This is indicative of a broken BIOS. powernow: Trying ACPI perflib powernow: Minimum speed 1075 MHz. Maximum speed 2366 MHz. I certainly believe that the BIOS might be broken, but why are these speeds being generated when earlier kernel versions reported a minimum of 500 MHz and a max of 1100? Steps to reproduce: Happens every boot.
[via e-mail from Bruno Ducrot] It's seems it's an issue I introduced trying to fix another one, but I believe it's not actually my fault. The powernow-k7 driver now calibrate in order to get it right with max and such. I believe that in some case the system clock run twice (well, at least I saw reports on this on nforce based systems IIRC) and therefore I think it's what need to be fixed. Read: I won't fix that and I don't think it is related to ACPI nor CPUFreq but to timer code.
Larry, Can you check if the system clock is running at double speed, ala bug 3927?
AFAIK, the problem did not involve doubling the system clock; however, it is not possible to check as the problem has been fixed (?) in 2.6.14-rc2, which I am now running. I had built 2.6.14-rc1-git[23], but I don't know if either of them had the problem. At the time, I was chasing a problem with WPA authentication for a wireless card, and was building essentially every version. Do you want me to backtrack and rebuild the earlier versions? Larry
Do I understand you correctly that this bug is solved now? If so, please CLOSE the bug.
No, this bug is NOT solved, except by the following patch: diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c --- a/arch/i386/kernel/timers/common.c +++ b/arch/i386/kernel/timers/common.c @@ -151,7 +151,7 @@ unsigned long read_timer_tsc(void) /* calculate cpu_khz */ void init_cpu_khz(void) { - if (cpu_has_tsc) { + if (cpu_has_tsc && !cpu_khz) { unsigned long tsc_quotient = calibrate_tsc(); if (tsc_quotient) { /* report CPU clock rate in Hz. My earlier statement was faulty. Sometimes it takes 3 or 4 boots before the error shows.
*** Bug 5435 has been marked as a duplicate of this bug. ***
Just looked at the duplicate report. I think your analyze is correct. It's very likely that calibrate_tsc() is interrupted somewhere. But your patch will reintroduce a bug though so I would much prefer that interruput being disabled when calling calibrate_tsc()?
Could you please elaborate how the previous patch introduces a bug? I don't follow how skipping the recalculation of cpu_freq causes a problem. Is the patch listed below better? It has been tested on a uniprocessor computer. I don't have access to any SMP equipment. diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c --- a/arch/i386/kernel/timers/common.c +++ b/arch/i386/kernel/timers/common.c @@ -34,10 +34,11 @@ unsigned long calibrate_tsc(void) unsigned long endlow, endhigh; unsigned long count; + local_irq_disable(); rdtsc(startlow,starthigh); mach_countup(&count); rdtsc(endlow,endhigh); - + local_irq_enable(); /* Error: ECTCNEVERSET */ if (count <= 1)
Well, I would prefer something like that (not tested) (copy and paste, that will require you apply by hand, sorry..) --- linux-2.6.14/arch/i386/kernel/timers/timer_tsc.c 2005/11/16 18:35:06 1.1 +++ linux-2.6.14/arch/i386/kernel/timers/timer_tsc.c 2005/11/16 18:36:27 @@ -325,7 +325,9 @@ int recalibrate_cpu_khz(void) unsigned int cpu_khz_old = cpu_khz; if (cpu_has_tsc) { + local_irq_disable(); init_cpu_khz(); + locale_irq_enable(); cpu_data[0].loops_per_jiffy = cpufreq_scale(cpu_data[0].loops_per_jiffy, cpu_khz_old, The reason why your previous patch will break powernow-k7 is that we really need to calibrate the cpu frequency *two* times, not only one. 1- that allow to do something like that: insmod powernow-k7 (change frequency to a lower frequency) rmmod powernow-k7 insmod powernow-k7 Since we assumed before that the frequency was always the max one, all frequencies computed were wrong. 2- some laptop, for reason I do not understand, set the processor to the lowest frequency, and when powernow-k7 is loaded later, the frequency is the highest one. The only solution to this is to recalibrate, and anyway that should fix some strange bug also since TSC will not be callibrated. Note that 1- may have been fixed by setting to max frequency when unloading. But 2- is much more embarrassing and I really don't see how to fix that other than by a recalibration of the TSC.
Thanks for the explanation of the origin of the bug. Your patch of arch/i386/kernel/timers/timer_tsc.c tests OK. After making that change and rebooting several times, the cpu_freq was always correct.
patch is in Linus' latest, closing.