Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] disable lost tick compensation before TSCs are synced

Avoid lost tick compensation early in boot before the TSCs are
synchronized. Currently timekeeping is enabled before the TSCs are
synchronized, thus when the TSCs are synched (reset to zero), it appears
that a number of lost ticks have occurred. This can cause premature expiry
of timers and in extreme cases can cause the soft lockup detection to fire.

This resolves issues reported by Andy Whitcroft as well as bug #5366
reported by Tim Mann.

Signed-off-by: John Stultz <johnstul@us.ibm.com>
Acked-by: Andy Whitcroft <apw@shadowen.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

john stultz and committed by
Linus Torvalds
bfaa1dee 2f7016d9

+12 -2
+12 -2
arch/i386/kernel/timers/timer_tsc.c
··· 45 45 static unsigned long long monotonic_base; 46 46 static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; 47 47 48 + /* Avoid compensating for lost ticks before TSCs are synched */ 49 + static int detect_lost_ticks; 50 + static int __init start_lost_tick_compensation(void) 51 + { 52 + detect_lost_ticks = 1; 53 + return 0; 54 + } 55 + late_initcall(start_lost_tick_compensation); 56 + 48 57 /* convert from cycles(64bits) => nanoseconds (64bits) 49 58 * basic equation: 50 59 * ns = cycles / (freq / ns_per_sec) ··· 205 196 206 197 /* lost tick compensation */ 207 198 offset = hpet_readl(HPET_T0_CMP) - hpet_tick; 208 - if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) { 199 + if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0)) 200 + && detect_lost_ticks) { 209 201 int lost_ticks = (offset - hpet_last) / hpet_tick; 210 202 jiffies_64 += lost_ticks; 211 203 } ··· 431 421 delta += delay_at_last_interrupt; 432 422 lost = delta/(1000000/HZ); 433 423 delay = delta%(1000000/HZ); 434 - if (lost >= 2) { 424 + if (lost >= 2 && detect_lost_ticks) { 435 425 jiffies_64 += lost-1; 436 426 437 427 /* sanity check to ensure we're not always losing ticks */