aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorjohn stultz <johnstul@us.ibm.com>2006-10-17 03:09:32 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-17 11:18:42 -0400
commit3f4a0b917ce72ef47e438d354c433eb645218e87 (patch)
tree82695f890785cfe1bd14303ce04453a16bd99c01 /arch/i386
parentb9f5d8040b470e4f74e3266ece2969ef06d0f8aa (diff)
[PATCH] i386 Time: Avoid PIT SMP lockups
Avoid possible PIT livelock issues seen on SMP systems (and reported by Andi), by not allowing it as a clocksource on SMP boxes. However, since the PIT may no longer be present, we have to properly handle the cases where SMP systems have TSC skew and fall back from the TSC. Since the PIT isn't there, it would "fall back" to the TSC again. So this changes the jiffies rating to 1, and the TSC-bad rating value to 0. Thus you will get the following behavior priority on i386 systems: tsc [if present & stable] hpet [if present] cyclone [if present] acpi_pm [if present] pit [if UP] jiffies Rather then the current more complicated: tsc [if present & stable] hpet [if present] cyclone [if present] acpi_pm [if present] pit [if cpus < 4] tsc [if present & unstable] jiffies Signed-off-by: John Stultz <johnstul@us.ibm.com> Cc: Andi Kleen <ak@suse.de> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/i8253.c2
-rw-r--r--arch/i386/kernel/tsc.c6
2 files changed, 4 insertions, 4 deletions
diff --git a/arch/i386/kernel/i8253.c b/arch/i386/kernel/i8253.c
index 477b24daff53..9a0060b92e32 100644
--- a/arch/i386/kernel/i8253.c
+++ b/arch/i386/kernel/i8253.c
@@ -109,7 +109,7 @@ static struct clocksource clocksource_pit = {
109 109
110static int __init init_pit_clocksource(void) 110static int __init init_pit_clocksource(void)
111{ 111{
112 if (num_possible_cpus() > 4) /* PIT does not scale! */ 112 if (num_possible_cpus() > 1) /* PIT does not scale! */
113 return 0; 113 return 0;
114 114
115 clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20); 115 clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20);
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c
index b8fa0a8b2e47..fbc95828cd74 100644
--- a/arch/i386/kernel/tsc.c
+++ b/arch/i386/kernel/tsc.c
@@ -349,8 +349,8 @@ static int tsc_update_callback(void)
349 int change = 0; 349 int change = 0;
350 350
351 /* check to see if we should switch to the safe clocksource: */ 351 /* check to see if we should switch to the safe clocksource: */
352 if (clocksource_tsc.rating != 50 && check_tsc_unstable()) { 352 if (clocksource_tsc.rating != 0 && check_tsc_unstable()) {
353 clocksource_tsc.rating = 50; 353 clocksource_tsc.rating = 0;
354 clocksource_reselect(); 354 clocksource_reselect();
355 change = 1; 355 change = 1;
356 } 356 }
@@ -461,7 +461,7 @@ static int __init init_tsc_clocksource(void)
461 clocksource_tsc.shift); 461 clocksource_tsc.shift);
462 /* lower the rating if we already know its unstable: */ 462 /* lower the rating if we already know its unstable: */
463 if (check_tsc_unstable()) 463 if (check_tsc_unstable())
464 clocksource_tsc.rating = 50; 464 clocksource_tsc.rating = 0;
465 465
466 init_timer(&verify_tsc_freq_timer); 466 init_timer(&verify_tsc_freq_timer);
467 verify_tsc_freq_timer.function = verify_tsc_freq; 467 verify_tsc_freq_timer.function = verify_tsc_freq;