From: Thomas Gleixner <tglx@linutronix.de>
To: Maxim Levitsky <maximlevitsky@gmail.com>
Cc: linux-kernel@vger.kernel.org, Ingo Molnar <mingo@elte.hu>,
Andrew Morton <akpm@linux-foundation.org>,
Adrian Bunk <bunk@stusta.de>,
Arjan van de Ven <arjan@infradead.org>,
Len Brown <lenb@kernel.org>
Subject: [PATCH] i386: trust the PM-Timer calibration of the local APIC timer
Date: Sat, 17 Mar 2007 01:04:56 +0100 [thread overview]
Message-ID: <1174089896.13341.362.camel@localhost.localdomain> (raw)
In-Reply-To: <1174088686.13341.347.camel@localhost.localdomain>
When PM-Timer is available for local APIC timer calibration we can skip
the verification of the calibrated time value. The resulting error is
quite small on a bunch of evaluated platforms and is less harming than
the observed false positives.
We need to keep the verification on systems, which have no PM-Timer to
avoid bogus local APIC timer calibrations in the range of factor 2-10,
which can be observed when swicthing off the PM-timer support in the
kernel configuration.
The wrong calibration values are probably caused by SMM code trying to
emulate a PS/2 keyboard from a (maybe connected or not) USB keyboard.
This prohibits the accurate delivery of PIT interrupts, which are used
to calibrate the local APIC timer. Unfortunately we have no way to
disable this BIOS misfeature in the early boot process.
Add also the dropped cpu_relax() back to the wait loops.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 2383bcf..92f4210 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -338,6 +338,7 @@ void __init setup_boot_APIC_clock(void)
void (*real_handler)(struct clock_event_device *dev);
unsigned long deltaj;
long delta, deltapm;
+ int pm_referenced = 0;
apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
"calibrating APIC timer ...\n");
@@ -357,7 +358,8 @@ void __init setup_boot_APIC_clock(void)
/* Let the interrupts run */
local_irq_enable();
- while(lapic_cal_loops <= LAPIC_CAL_LOOPS);
+ while(lapic_cal_loops <= LAPIC_CAL_LOOPS)
+ cpu_relax();
local_irq_disable();
@@ -394,6 +396,7 @@ void __init setup_boot_APIC_clock(void)
"%lu (%ld)\n", (unsigned long) res, delta);
delta = (long) res;
}
+ pm_referenced = 1;
}
/* Calculate the scaled math multiplication factor */
@@ -423,68 +426,41 @@ void __init setup_boot_APIC_clock(void)
calibration_result / (1000000 / HZ),
calibration_result % (1000000 / HZ));
-
- apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
-
- /*
- * Setup the apic timer manually
- */
local_apic_timer_verify_ok = 1;
- levt->event_handler = lapic_cal_handler;
- lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt);
- lapic_cal_loops = -1;
- /* Let the interrupts run */
- local_irq_enable();
+ /* We trust the pm timer based calibration */
+ if (!pm_referenced) {
+ apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
- while(lapic_cal_loops <= LAPIC_CAL_LOOPS);
+ /*
+ * Setup the apic timer manually
+ */
+ levt->event_handler = lapic_cal_handler;
+ lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt);
+ lapic_cal_loops = -1;
- local_irq_disable();
+ /* Let the interrupts run */
+ local_irq_enable();
- /* Stop the lapic timer */
- lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt);
+ while(lapic_cal_loops <= LAPIC_CAL_LOOPS)
+ cpu_relax();
- local_irq_enable();
+ local_irq_disable();
- /* Jiffies delta */
- deltaj = lapic_cal_j2 - lapic_cal_j1;
- apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj);
+ /* Stop the lapic timer */
+ lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt);
- /* Check, if the PM timer is available */
- deltapm = lapic_cal_pm2 - lapic_cal_pm1;
- apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm);
+ local_irq_enable();
- local_apic_timer_verify_ok = 0;
+ /* Jiffies delta */
+ deltaj = lapic_cal_j2 - lapic_cal_j1;
+ apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj);
- if (deltapm) {
- if (deltapm > (pm_100ms - pm_thresh) &&
- deltapm < (pm_100ms + pm_thresh)) {
- apic_printk(APIC_VERBOSE, "... PM timer result ok\n");
- /* Check, if the jiffies result is consistent */
- if (deltaj < LAPIC_CAL_LOOPS-2 ||
- deltaj > LAPIC_CAL_LOOPS+2) {
- /*
- * Not sure, what we can do about this one.
- * When high resultion timers are active
- * and the lapic timer does not stop in C3
- * we are fine. Otherwise more trouble might
- * be waiting. -- tglx
- */
- printk(KERN_WARNING "Global event device %s "
- "has wrong frequency "
- "(%lu ticks instead of %d)\n",
- global_clock_event->name, deltaj,
- LAPIC_CAL_LOOPS);
- }
- local_apic_timer_verify_ok = 1;
- }
- } else {
/* Check, if the jiffies result is consistent */
- if (deltaj >= LAPIC_CAL_LOOPS-2 &&
- deltaj <= LAPIC_CAL_LOOPS+2) {
+ if (deltaj >= LAPIC_CAL_LOOPS-2 && deltaj <= LAPIC_CAL_LOOPS+2)
apic_printk(APIC_VERBOSE, "... jiffies result ok\n");
- local_apic_timer_verify_ok = 1;
- }
+ else
+ local_apic_timer_verify_ok = 0;
}
if (!local_apic_timer_verify_ok) {
next prev parent reply other threads:[~2007-03-16 23:58 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-16 10:30 [BUG] 2.6.21-rc1,2,3 regressions on my system that I found so far Maxim Levitsky
2007-03-16 23:19 ` Len Brown
2007-03-17 23:00 ` Maxim
2007-03-17 23:32 ` Thomas Gleixner
2007-12-30 7:50 ` Mike Galbraith
2007-12-30 14:53 ` Ingo Molnar
2007-03-20 11:54 ` sysfs ugly timer interface (was Re: [BUG] 2.6.21-rc1,2,3 regressions on my system that I found so far) Pavel Machek
2007-03-22 15:28 ` Greg KH
2007-03-22 15:41 ` Thomas Gleixner
2007-03-23 1:24 ` sysfs q [was: sysfs ugly timer interface] Jan Engelhardt
2007-03-23 4:48 ` Greg KH
2007-03-23 6:05 ` Jan Engelhardt
2007-03-16 23:39 ` [BUG] 2.6.21-rc1,2,3 regressions on my system that I found so far Thomas Gleixner
2007-03-17 23:01 ` Maxim
2007-03-16 23:44 ` Thomas Gleixner
2007-03-17 0:04 ` Thomas Gleixner [this message]
2007-03-17 7:22 ` [PATCH] i386: trust the PM-Timer calibration of the local APIC timer Ingo Molnar
2007-03-17 13:24 ` Andi Kleen
2007-03-18 8:12 ` Andrew Morton
2007-03-18 8:45 ` Thomas Gleixner
2007-03-17 1:32 ` [BUG] 2.6.21-rc1,2,3 regressions on my system that I found so far Len Brown
2007-03-17 9:56 ` Thomas Gleixner
2007-03-17 11:05 ` Thomas Gleixner
2007-03-17 16:52 ` Thomas Gleixner
2007-03-17 10:32 ` Arjan van de Ven
2007-03-17 13:26 ` Andi Kleen
2007-03-20 4:27 ` Greg KH
2007-03-20 6:30 ` Thomas Gleixner
2007-03-20 9:14 ` Arjan van de Ven
2007-03-20 11:36 ` Andi Kleen
2007-03-20 11:41 ` Oliver Neukum
2007-03-17 22:45 ` Maxim
2007-03-20 5:04 ` Lee Revell
2007-03-20 5:36 ` Eric St-Laurent
2007-03-20 9:15 ` Arjan van de Ven
2007-03-20 18:04 ` Andy Lutomirski
2007-03-20 22:58 ` Eric St-Laurent
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1174089896.13341.362.camel@localhost.localdomain \
--to=tglx@linutronix.de \
--cc=akpm@linux-foundation.org \
--cc=arjan@infradead.org \
--cc=bunk@stusta.de \
--cc=lenb@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maximlevitsky@gmail.com \
--cc=mingo@elte.hu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox