Messages in this thread Patch in this message | | | Date | Mon, 30 Jan 2006 13:30:24 +0000 | From | Andy Whitcroft <> | Subject | Re: [PATCH] timer tsc ensure we allow for initial tsc and tsc sync |
| |
john stultz wrote:
> There's a test patch in there that maybe you could try?
Yep this one also seems to fix it. It also looks like a more general solution than mine. I've attached the patch here so that its recorded with this. I've added some description to the top. Tests ok on the machine which was showing issues for me. Help yourself to a:
Acked-by: Andy Whitcroft <apw@shadowen.org>
If you are happy with it I for one would like to see it in -mm. Perhaps you could sign it off and send it to Andrew for inclusion.
-apw From: John Stultz <johnstul@us.ibm.com>
Suppress lost tick detection until we are fully initialised. This prevents any modifications to the high resolution timers from causing non-linearities in the flow of time. For example on an SMP system we resyncronise the TSC values for all processors. This results in a TSC reset which will be seen as a huge apparent tick loss. This can cause premature expiry of timers and in extreme cases can cause the soft lockup detection to fire.
Acked-by: Andy Whitcroft <apw@shadowen.org>
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c @@ -45,6 +45,15 @@ static unsigned long last_tsc_high; /* m static unsigned long long monotonic_base; static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; +/* Avoid compensating for lost ticks before TSCs are synched */ +static int detect_lost_ticks; +static int __init start_lost_tick_compensation(void) +{ + detect_lost_ticks = 1; + return 0; +} +late_initcall(start_lost_tick_compensation); + /* convert from cycles(64bits) => nanoseconds (64bits) * basic equation: * ns = cycles / (freq / ns_per_sec) @@ -196,7 +205,8 @@ static void mark_offset_tsc_hpet(void) /* lost tick compensation */ offset = hpet_readl(HPET_T0_CMP) - hpet_tick; - if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) { + if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0)) + && detect_lost_ticks) { int lost_ticks = (offset - hpet_last) / hpet_tick; jiffies_64 += lost_ticks; } @@ -419,7 +429,7 @@ static void mark_offset_tsc(void) delta += delay_at_last_interrupt; lost = delta/(1000000/HZ); delay = delta%(1000000/HZ); - if (lost >= 2) { + if (lost >= 2 && detect_lost_ticks) { jiffies_64 += lost-1; /* sanity check to ensure we're not always losing ticks */ | |