Subject: system timekeeping and CPU cycle counters
To: None <tech-kern@netbsd.org>
From: Erik E. Fair <fair@netbsd.org>
List: tech-kern
Date: 06/25/2005 17:53:44
The two items in the subject should not be mixed without great care.

When time keeping doesn't work as expected, very bad things happen to system
scheduling, and other system-wide functions.

Charles Hannum wrote a warning about this in 1998:

	http://mail-index.netbsd.org/port-i386/1998/11/19/0011.html

In laptop computers whose processors drop to lower clock frequencies as part
of power management to save power and extend battery life, you can't use the
cycle counter for interval timing unless you figure out exactly when the clock
frequency changed during any interval measurement, and correct for that in
the calculation of the interval.

If you've got a MULTIPROCESSOR system, you'd better be careful about which
CPU's cycle counter you read at any given point. Odds are that, having been
started/initialized at different times, the values read from different CPUs
in the same system will be skewed from each other.

System clocks are also skewed over short intervals to cheaply reduce
system-wide EMI/RFI:

http://www.maxim-ic.com/appnotes.cfm/appnote_number/3503

http://www.epn-online.com/page/18189/clock-oscillator-with-low-emi-spread-spectrum.html

http://www.mecxtal.com/pdf/te_notes/TN-020%20Low%20EMI%20Spread%20Spectrum%20Oscillators.PDF

http://www.sss-mag.com/cosc.html#nelarticle

The upshot of this is that CPU cycle counters cannot be relied upon for
accurate short interval timing.

I've also discovered (to my sorrow) i386 CPUs in which the TSC does not work
properly under all conditions, e.g. the Cyrix MediaGX, NSC SC1100.

Unfortunately, in the i386 port, NetBSD uses the TSC if it is present in
microtime(9), unless the kernel config contains:

options         NO_TSC_TIME

I suggest a new option to replace NO_TSC_TIME in an MI way: CPU_CC_MICROTIME
which would control when the CPU cycle counter code is compiled in and used
by default, and the option should be default OFF. This would reverse the
current default on i386.

I'll have to take a look at the other ports to see what they're doing.

	Erik <fair@clock.org>