Skip to content

Commit

Permalink
[PATCH] i386 Time: Avoid PIT SMP lockups
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
john stultz authored and Linus Torvalds committed Oct 17, 2006
1 parent b9f5d80 commit 3f4a0b9
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 5 deletions.
2 changes: 1 addition & 1 deletion arch/i386/kernel/i8253.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions arch/i386/kernel/tsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion kernel/time/jiffies.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit 3f4a0b9

Please sign in to comment.