[PATCH] i386 Time: Avoid PIT SMP lockups
authorjohn stultz <johnstul@us.ibm.com>
Tue, 17 Oct 2006 07:09:32 +0000 (00:09 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 17 Oct 2006 15:18:42 +0000 (08:18 -0700)
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>
arch/i386/kernel/i8253.c
arch/i386/kernel/tsc.c
kernel/time/jiffies.c

index 477b24daff539bf3d5a1ab6be6e10f6f10dedc22..9a0060b92e32ace2911ae839a9d8b710e7458ec4 100644 (file)
@@ -109,7 +109,7 @@ static struct clocksource clocksource_pit = {
 
 static int __init init_pit_clocksource(void)
 {
-       if (num_possible_cpus() > 4) /* PIT does not scale! */
+       if (num_possible_cpus() > 1) /* PIT does not scale! */
                return 0;
 
        clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20);
index b8fa0a8b2e4733170d0b72cff576d7ddb8c750cd..fbc95828cd7493082aeeedc0396a762db056097b 100644 (file)
@@ -349,8 +349,8 @@ static int tsc_update_callback(void)
        int change = 0;
 
        /* check to see if we should switch to the safe clocksource: */
-       if (clocksource_tsc.rating != 50 && check_tsc_unstable()) {
-               clocksource_tsc.rating = 50;
+       if (clocksource_tsc.rating != 0 && check_tsc_unstable()) {
+               clocksource_tsc.rating = 0;
                clocksource_reselect();
                change = 1;
        }
@@ -461,7 +461,7 @@ static int __init init_tsc_clocksource(void)
                                                        clocksource_tsc.shift);
                /* lower the rating if we already know its unstable: */
                if (check_tsc_unstable())
-                       clocksource_tsc.rating = 50;
+                       clocksource_tsc.rating = 0;
 
                init_timer(&verify_tsc_freq_timer);
                verify_tsc_freq_timer.function = verify_tsc_freq;
index 126bb30c4afe42b01b78945d2105033f994979b3..a99b2a6e6a07354781da79b6067b1944d438d5f9 100644 (file)
@@ -57,7 +57,7 @@ static cycle_t jiffies_read(void)
 
 struct clocksource clocksource_jiffies = {
        .name           = "jiffies",
-       .rating         = 0, /* lowest rating*/
+       .rating         = 1, /* lowest valid rating*/
        .read           = jiffies_read,
        .mask           = 0xffffffff, /*32bits*/
        .mult           = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */