Messages in this thread Patch in this message | | | Date | Tue, 10 Mar 2009 12:29:45 +0100 (CET) | From | Thomas Gleixner <> | Subject | Re: Linux 2.6.29-rc6 |
| |
On Mon, 9 Mar 2009, Linus Torvalds wrote: > On Mon, 9 Mar 2009, Jesper Krogh wrote: > > > > First boot. > > [ 0.000000] ref_freq: 2311825 pit_freq: 2310386 > > Second boot: > > [ 0.000000] ref_freq: 2311803 pit_freq: 2310190 > > Third boot: > > [ 0.000000] ref_freq: 2311824 pit_freq: 2310080 > > Fourth boot: > > [ 0.000000] ref_freq: 2311831 pit_freq: 2310130 > > It's really quite impressively stable, but the fast-PIT calibration > frequency is reliably about 3/4 of a promille low. Or, put another way, > the TSC difference over the pit calibration is just a _tad_ too small > compared to the value we'd expect if that loop of pit_expect_msb() would > really run at the expected delay of a 1.193182MHz clock divided by 256. > > And it's stable in that it really always seems to be off by a very similar > amount. It's not moving around very much. > > I also wonder why it seems to happen mainly just to _you_. There's > absolutely nothing odd in your system, neither a slow CPU or anything > else that would stand out. > > Grr. Very annoyingly non-obvious.
Indeed. One hint is in the slow calibration path. 3 of 4 boots have:
> > [ 0.000000] TSC: PIT calibration matches PMTIMER. 2 loops
So the slow calibration path detects some disturbance.
Jesper, can you please apply the following patch instead of Johns and provide the output for a couple of boots? The output is:
Fast TSC calibration using PIT tsc 43425305 tscmin 624008 tscmax 632610
Thanks,
tglx
--- linux-2.6.orig/arch/x86/kernel/tsc.c +++ linux-2.6/arch/x86/kernel/tsc.c @@ -317,15 +317,22 @@ static unsigned long quick_pit_calibrate if (pit_expect_msb(0xff)) { int i; - u64 t1, t2, delta; + u64 t1, t2, t3, delta; unsigned char expect = 0xfe; + unsigned long tscmin = ULONG_MAX, tscmax = 0; - t1 = get_cycles(); + t1 = t2 = get_cycles(); for (i = 0; i < QUICK_PIT_ITERATIONS; i++, expect--) { if (!pit_expect_msb(expect)) goto failed; + t3 = get_cycles(); + delta = t3 - t2; + t2 = t3; + if ((unsigned long) delta < tscmin) + tscmin = (unsigned int) delta; + if ((unsigned long) delta > tscmax) + tscmax = (unsigned int) delta; } - t2 = get_cycles(); /* * Make sure we can rely on the second TSC timestamp: @@ -350,6 +357,8 @@ static unsigned long quick_pit_calibrate delta = (t2 - t1)*PIT_TICK_RATE; do_div(delta, QUICK_PIT_ITERATIONS*256*1000); printk("Fast TSC calibration using PIT\n"); + printk("tsc %ld tscmin %ld tscmax %ld\n", + (unsigned long) (t2 - t1), tscmin, tscmax); return delta; } failed:
| |