Subject: Re: Proposed changes to cc_microset().
To: None <tech-kern@NetBSD.org>
From: Alan Barrett <apb@cequrux.com>
List: tech-kern
Date: 07/08/2004 21:02:40
On Thu, 08 Jul 2004, Frederick Bruckman wrote:
> >I haven't worked out the details, but I think that it should be possible
> >to add a function that gets called with both old and new nominal speeds
> >when the CPU speed is changed, and that frobs the information in struct
> >cpu_info to DTRT.
> 
> There really is no "nominal" speed:

Well, there's no nominal CPU speed in MI code, but MD code could have
such a thing.  For example, the i386 speedstep code knows (or could
know) both the old and new values of machdep.est.frequency.target.  They
could be passed to an MI function that did something like this (details
are probably wrong):

void
cc_changespeed(u_int64_t oldspeed, u_int64_t newspeed)
{
	struct cpu_info *ci;
	u_int32_t cc;
	struct timeval t;

	/* XXX lock */
	/* get current cycle count and time */
	cc = cpu_counter32();
	cc_microtime(&t);
	/* frob ci so that cc_microtime() will allow for the new speed */
	ci = curcpu();
	ci->ci_cc_cc = cc;
	ci->ci_cc_time = t;
	ci->ci_cc_denom = ci->ci_cc_denom * oldspeed / newspeed;
	ci->ci_tsc_freq = ci->ci_tsc_freq * oldspeed / newspeed;
	/* XXX unlock */
}

For extra accuracy, pass the values of ci, cc and t as args
instead of calling curcpu(), cpu_counter32() and cc_microtime().

> ci_tsc_freq is set at boot-up by averaging over a 10 tick interval,
> then not touched again.

Right.  But when i386 MD code changes machdep.est.frequency.target from
the value it had at boot time to some new value, wouldn't it make sense
to also change ci_tsc_freq by the same ratio?  And perhaps also add a
way to to save a different value of ci_tsc_freq for each speed known by
the MD code?

> The ES code could do the same thing, then set ci_cc_denom = 0 to force
> ci_tsc_freq to be used until cc_microset() has a chance to do it's
> thing.

Yes, it could re-calibrate ci_tsc_freq after each speed change, by
counting cycles over some interval, but it's probably unacceptable to
do that using delay(9), as is done in several of the MI identifycpu()
functions.  And that still doesn't help with getting accurate time
during the one-second interval in which the speed change occurs.

> At some point, when the confidence is high, we should probably update
> ci_tsc_freq, as it is used as a fallback at times.

That's a good idea.  Perhaps when ci_cc_denom remains almost constant
for long enough, copy it to ci_tsc_freq.

--apb (Alan Barrett)