Messages in this thread | | | Date | Thu, 21 May 1998 06:13:51 -0400 (EDT) | From | "C. Scott Ananian" <> | Subject | Re: Everything you want to know about time (Was: Cyrix 6x86MX and Centaur C6 CPUs in 2.1.102) |
| |
On Thu, 21 May 1998, Andre Derrick Balsa wrote:
> Actually, there is a simple way to do a RDTSC calibration that will get > us an accurate measurement of the number of cpu_clock_cycles/jiffy: > > At kernel boot, in time_init (which should run with interrupts > disabled), > > a) Do a busy wait on the CTC timer until it zeroes. > b) Now read the TSC. > c) Do another busy wait on the CTC timer until it zeroes. > d) Read the TSC again. > e) The difference in TSC readings is our cpu_clock_cycles/jiffy. > > Maximum time spent on this calibration procedure is just 0.02 seconds, > and this is at boot time. Note that since both the TSC and the CPU clock > depend on the same quartz crystal (a 14.31818MHz part), they will never > drift apart, so there is *no* need to repeat this calibration procedure.
That's really quite nice. I double-checked, interrupts *are* disabled (from all sources) during time_init(). It still doesn't really change the variable-clock-speed problem, though. (CPU halt, a turbo button, APM slowing the clock...) But I guess if you screw with your CPU speed you deserve the timing problems you get.
> > 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. > > Sorry if I am being picky, but this is not quite so. The Cyrix doesn't > destroy the TSC or anything of the sort.
Sorry, but I *am* right. Look carefully at the code. It is *impossible* for the Cyrix to generate a divide-by-zero Oops (which has been experimentally verified by numerous sources) *unless* the Cyrix is zero-ing the top 32 bits of the TSC on HLT. I call that "destroying the TSC".
It is impossible to Oops if the Cyrix is just stopping the TSC. The times will be off, but no Oops.
> We have two cases: > > 1) If the Suspend-on-Halt feature is disabled (default state after a > reset), the Cyrix 6x86MX will behave just like the Intel part.
I'll believe you there. *BUT* this needs to be documented in big red letter somewhere: DON'T SUSPEND-ON-HALT. *However* it seems that many people really really like Suspend-on-halt because it keeps their processors cooler than the summer sidewalk in new york; it seems being safe and allowing people to use power-saving on their CPUs is not so unreasonable an option.
I'll leave this choice up to the Cyrix community. At the moment Linus has implemented 'prevent-the-Oops,' which I think is a reasonable decision.
> 2) If Suspend-on-Halt is _explicitly_ enabled (e.g. using a utility > called set6x86), the Cyrix 6x86MX acts like the Centaur C6 step 0, i.e. > it stops the TSC when Halted.
See above. The Cyrix is trashing the TSC. There's no other way it can Oops.
On the same note, if people are seeing Oopsen with the Centaur chips, which allegedly merely halt the CPU, I'd be very interested to hear about it.
I wrote: > > [...](Note that only intra-jiffy > > times are affected; read the source for the details on how the error is > > bounded). ...
> The error is bounded as follows: > > maximum 1 jiffy error - 1 microsecond over 1 jiffy. Or if you prefer, > 100% over 1 jiffy, 50% over 2 jiffies, etc...
Right. I'm bored, I'll recap for the interested why this is so: (linux/arch/i386/kernel/time.c) /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (edx >= USECS_PER_JIFFY) edx = USECS_PER_JIFFY-1;
return edx; So if do_fast_gettimeoffset() computes a totally bogus value, it is hard limited to "just before the next jiffy." Each jiffy increments the time by USECS_PER_JIFFY since the last jiffy time, ignoring the gettimeoffset values altogether. So the error will never be larger than (one jiffy minus one microsecond), as you noted.
> BTW if we are concerned with the time it takes for > gettimeofday() to execute, _this_ cumulative average algorithm in > do_fast_gettimeoffset() is a low performance solution.
Well, 100 times a second is not really *often* by CPU standards... ..but I agree, if we can do this *just once,* we probably should.
> if (machine_supports_tsc) > show_MegaHertz_rating > else > show_Bogomips_rating > > should go a long way to solve the confusion in many people's minds about > bogomips, MHz and CPU performance...
Heaven help us if some manufacturer decides to over- or under- clock their TSC... --Scott
[more info re: divide-by-zero from TSC halt -vs- divide-by-zero by TSC trash: The *only way* you could get a divide-by-zero from a HALTED (not trashed) TSC is if the *average* "cycles per jiffy" is less than 1. That means you have to spend a substantial portion of your total uptime in a completely halted state (no TSC advancement *at all*, not even during the jiffy handler), and once the Oopsen start they should never stop (maybe a slight respite if the TSC advances during the printk of the Oops, but you get my point). If *this* is what's happening, the Cyrix CPU is not just buggy, it's *seriously screwed*.] @ @ =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-oOO-(_)-OOo-=-=-=-=-= C. Scott Ananian: cananian@lcs.mit.edu / Declare the Truth boldly and Laboratory for Computer Science/Crypto / without hindrance. Massachusetts Institute of Technology /META-PARRESIAS AKOLUTOS:Acts 28:31 -.-. .-.. .. ..-. ..-. --- .-. -.. ... -.-. --- - - .- -. .- -. .. .- -. PGP key available via finger and from http://www.pdos.lcs.mit.edu/~cananian
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |