[PATCH 1/1] Switch to jiffies for native_sched_clock() when TSC warps
Tim Gardner
tim.gardner at canonical.com
Wed Mar 10 20:38:54 UTC 2010
On 03/10/2010 12:30 PM, Chase Douglas wrote:
> Some newer x86 processors (seen on core 2 duo, arrandale) warp their TSC
> registers after a suspend. It is believed that a microcode fix may be a
> solution, but for now we should work around the issue.
>
> This change adds an upper bound on the difference between TSC readings. It
> should be very generous (multiple year difference) so as to only catch TSC
> warping which appears to generate timestamps many years in the future.
> When a warp is found, usage of the TSC for timing is disabled. The
> kernel falls back to using the jiffies counter, which is not as precise
> but should be accurate.
>
> Signed-off-by: Chase Douglas<chase.douglas at canonical.com>
> ---
> arch/x86/kernel/tsc.c | 15 +++++++++++++++
> 1 files changed, 15 insertions(+), 0 deletions(-)
>
> diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
> index 597683a..3e2921d 100644
> --- a/arch/x86/kernel/tsc.c
> +++ b/arch/x86/kernel/tsc.c
> @@ -43,7 +43,9 @@ static int tsc_clocksource_reliable;
> u64 native_sched_clock(void)
> {
> u64 this_offset;
> + static u64 prev_offset;
>
> +jiffies:
> /*
> * Fall back to jiffies if there's no TSC available:
> * ( But note that we still use it if the TSC is marked
> @@ -60,6 +62,19 @@ u64 native_sched_clock(void)
> /* read the Time Stamp Counter: */
> rdtscll(this_offset);
>
> + /*
> + * if new time stamp is many years later, assume warping and disable
> + * TSC usage:
> + */
> + if (__cycles_2_ns(this_offset - prev_offset)> 0x100000000000000
> + && prev_offset) {
> + printk(KERN_WARNING "TSC warped, using jiffies\n");
> + tsc_disabled = 1;
> + goto jiffies;
> + }
> +
> + prev_offset = this_offset;
> +
> /* return the value in ns */
> return __cycles_2_ns(this_offset);
> }
I think this is not SMP safe. Surely this function is called by more
then one CPU, therefore prev_offset must be a percpu variable at the
very least.
I am also not in favor of changing runtime behavior. Why not simply
advise the user to boot with 'notsc' using the WARN_ON_ONCE() macro?
Is this the best place to detect warping? It _is_ a fairly high
performance path. How about stashing the TSC just before suspend and
checking it upon return?
rtg
--
Tim Gardner tim.gardner at canonical.com
More information about the kernel-team
mailing list