Re: Everything you want to know about time (Was: Cyrix 6x86MX and Centaur C6 CPUs in 2.1.102)

Riley Williams (
Thu, 21 May 1998 14:00:02 +0100 (BST)

Hi Scott.

> My apologies for the length.

No problem...

*** On the subject of the TSC and inter-jiffy times ***

> Note this is 64-bit time in cycles since init (rtsc at init is
> subtracted from rtsc at last jiffy interrupt), and the jiffy
> counter counts timer ticks since init. So the "average internal
> clocks per usec" is a running average since when the machine first
> booted. [This also eliminates the jitter that may happen at init.]
> This is done in do_fast_gettimeoffset, so if nobody's calling
> gettimeofday, then this will not be recalculated. So it's 100 times
> a second *max* (worst case once per jiffy, the first time in each
> jiffy that gettimeofday is called).

> *However*, there are many cases where it is not reasonable to
> assume that "average internal clocks per usec" is a constant.
> Haltable CPUs are one example, as are APM-enabled machines that
> slow the processor clock to save power. And let's not forget those
> ol' machines with the 'turbo' button on the front. Perhaps an
> average over the last N jiffies is more appropriate....

> ...but it doesn't really matter, because the worse that will happen
> if your clock speed changes (or even stops between interrupts) is
> that the intra-jiffy timing will be off---gettimeofday will
> estimate the wrong time based on the TSC count.

> THE EVIL OOPS POTENTIAL: (this is what really matters)
> ~~~~~~~~~~~~~~~~~~~~~~~~

> BUT some machines do the unthinkable -- they actually randomly
> destroy the TSC value during "power-saving." This is the Cyrix bug.
> This also occurs during APM suspend: only the low 32 bits of the
> TSC can be restored after you power off the processor; the high 32
> bits are zeroed.

Please excuse me if I'm being stupid, but there's one reasonably
obvious way to fix that as I see it - and it must be stupid if nobody
else has suggested it...

Q> For the above procedure to work, the kernel must have an idea of
Q> the normal inter-jiffy value, and it should be reasonable to
Q> assume that the variation will not normally exceed 50% of the
Q> current average.

Q> In this case, all the relevant code needs to do is to ignore any
Q> cases where the inter-jiffy value was outside the range of...

Q> 1.5 * AVG > CURRENT > 0.5 * AVG

Q> ...for whatever the current value of AVG is.

Alternatively, if that's too restricting, use the following to allow
the average to climb faster...

Q> 10 * AVG > CURRENT > 0.1 * AVG

This basically permits inter-jiffy counts between one tenth and ten
times the current average value...

The only problem I can see with this is during the initial machine
startup after the clock frequency is set, where the first few counts
may be well out, and to deal with that, I would suggest that the
initial average be set to the value that occurs exactly in the middle
of the sorted list of values for the first (2*N+1, N>9) jiffies, thus
ignoring any extremely low or high values...choose N based on your
favourite random number...

Best wishes from Riley.

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to