Subject: Re: Need help with timecounters/todr
To: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
From: Frank Kardel <kardel@netbsd.org>
List: port-alpha
Date: 02/24/2007 17:32:37
Izumi Tsutsui wrote:
> kardel@NetBSD.org wrote:
> 
> 
>>In general I agree with the strategy but I think we
>>should try to avoid a copy if tsc.c here. I include an
>>old patch here that attempts to split tsc.c into a
>>MD part (tsc.c) and an MI part kern_cctr.c.
> 
> 
> Well, I completely agree with you, but I don't think
> it's my part to split it into MI/MD part ;-)
> (just I'd like to commit todr(9) diffs in my local tree)
> 
getting generic todr() is an improvement - and a good companion
for timecounters.

> Is there any reason why you have not committed this
> kern_cctr.c patch?
> 
I am waiting for another working timercounter port that makes
use of the then MI code. I thought alpha could be it, thats why I
did some work into that direction without having that hw.
So if we get alpha timercounterized that way I am more
than happy to commit that.

> 
>>Maybe you can
>>use that for the cycle counter part of the part
> 
> 
> With a quick glance, kern_cctr.c has MD x86_broadcast_ipi()
Ooops, didn't I say it was work in progress :-)?

> call. How should it be handled? (via a function pointer?)
How about just an MD supplied function (cc_broadcast_ipi())
could be just a macro defined appropriately in MD headers.

> I'm also afraid that some ports don't have opt_multiprocessor.h.
Hmm, maybe we can find a way via the MD header files.

> Is it better to move cc_calibrate() function into MD files?
Why replicate that? - kern_microtime.c had a similar MI calibration
functionality.

> 
> 
>>Also note
>>that the patch assumes that the counter is read by
>>cpu_counter32() - same headfile magic as was used
>>for kern_microtime.c.
> 
> 
> Alpha port currently uses kern_microtime.c and
> cpu_counter32() is defined in arch/alpha/include/cpu_counter.h.
> 
Yes, that's what I make use of in kern_cctr.c. All ports that
supported kern_microtime.c would be able to use kern_cctr.c given
the right cc_init() call (and the IPI broadcast callback for MP cases).

> 
>>The patch works for x86 - it should work for alpha when
>>cc_init is called at the right place - I hope - I have no
>>hw to check.
> 
> 
> I don't have SMP one, but I'll try my on DEC3000/300 and AlphaPC164.
> 
Good - that would be the first tme that code runs on alpha, good luck!

> 
>>>Note "make regress" on regress/sys/kern/sleeping fails
>>>even without this patch on alpha.
>>
>>I what way? Usually the check uncovers descrepancies between
>>timeout and timekeeping code.
> 
> 
> Here is a log on GENERIC kernel from daily snapshot:
> ---
> # uname -a
> NetBSD outlander 4.99.11 NetBSD 4.99.11 (GENERIC-$Revision: 1.310 $) #0: Mon Feb 19 19:48:43 UTC 2007  builds@b0.netbsd.org:/home/builds/ab/HEAD/alpha/200702190000Z-obj/home/builds/ab/HEAD/src/sys/arch/alpha/compile/GENERIC alpha
> # make regress
> ./sleeptest
> Testing sleep/timeout implementations
> accepted scheduling delta 30 ms
> testing up to 32000 ms for 5 interfaces
> ALARM interrupt after 11 sec once per run
> kevent timer will fire after 13200 ms
> [nanosleep] sleeping 30000000 nsec ... sig 0, real time sleep 30711000 nsec, remain(returned) 0 nsec, diff to supposed sleep -711000 nsec (rounded -711000 nsec) OK
> 
>  :
> 
> [nanosleep] sleeping 7680000000 nsec ... sig 0, real time sleep 7688819000 nsec, remain(returned) 0 nsec, diff to supposed sleep -8819000 nsec (rounded -8819000 nsec) OK
> [nanosleep] sleeping 15360000000 nsec ... - errno=Interrupted system call (OK) - sig 1, real time sleep 11013983000 nsec, remain(returned) 4346684000 nsec, diff to supposed sleep -667000 nsec (rounded -667000 nsec) OK
> [nanosleep] sleeping 30720000000 nsec ... sig 1, real time sleep 30754588000 nsec, remain(returned) 0 nsec, diff to supposed sleep -34588000 nsec (rounded -34588000 nsec) ERROR
Hmm, over 30ms difference to the expected value - usually I expect 
return within one-two clockticks. As the 30ms is hardcoded what is the 
clock interrupt frequency of alpha ?

> [nanosleep] sleeping 23040000000 nsec ... sig 1, real time sleep 23065463000 nsec, remain(returned) 0 nsec, diff to supposed sleep -25463000 nsec (rounded -25463000 nsec) OK
> 
>  :
> 
> TEST FAIL (1 errors, 5 alarms, 5 interfaces)
> *** Error code 1
> 
> Stop.
> make: stopped in /usr/src/regress/sys/kern/sleeping
> ---
> 
> Caused by inaccuracy of cpu_frequency() on alpha?
As others said around 5% - that could be - especially as it seems to 
happen on longer timeouts. could you do a simple check? Compare
the system time with the wall clock time over a period of about
1000 secs (~17 minutes).
Also run make regress in regress/sys/kern/time.

Another check is to use the clockinterrupt timecounter. That
should agree with wall clock time if the clock interrupt frequency is 
correct.

> 
> ---
> Izumi Tsutsui

Frank