threads runtime value is incorrect (tc_cpu_ticks() problem)

Uffe Jakobsen uffe at
Wed Jun 22 11:53:50 UTC 2011

On 2011-06-22 12:33, Svatopluk Kraus wrote:
> Hi,
>    I've tested FreeBSD-current from June 16 2011 on x86 (AMD Elan
> SC400). I found out that a sum of runtimes of all threads is about 120
> minutes after 180 minutes of system uptime and the difference is
> getting worse with time. The problem is in tc_cpu_ticks()
> implementation which takes into acount just one timecounter overflow,
> but in tested BSP (16-bit hardware counter) very often more than one
> overflow occured between two tc_cpu_ticks() calls.
>    I understand that 16-bit timecounter is a real relict nowadays, but
> I would like to solve the problem somehow reasonably. I have a few
> questions.
>    According to description in definition of timecounter structure
> (sys/timetc.h), tc_get_timecount() should read the counter and
> tc_counter_mask should mask off any unimplemented bits. In
> tc_cpu_ticks(), if ticks count returned from tc_get_timecount()
> overflows then (tc_counter_mask + 1) is added to result.
>    However, timecounter hardware can be initialized to value from
> interval (0, tc_counter_mask>, so if the description of
> tc_get_timecount() doesn't lie then adding (tc_counter_mask + 1) value
> at all times is not correct. Better description which satisfies
> tc_cpu_ticks() implementation is that tc_get_timecount() should count
> the ticks in interval<0, tc_counter_mask>. That's what
> i8254_get_timecount() (in sys/x86/isa/clock.c) does really. However,
> if tc_get_timecount() should count the ticks (and doesn't read the
> counter) then it can count the ticks in full uint64_t range? And
> tc_cpu_ticks() implementation could be very simple (not masking, not
> overflow checking). In i8254_get_timecount(), it is enough to change
> global variable 'i8254_offset' and local variable 'count' from
> uint16_t to uint64_t type.
>    Now, cpu_ticks() (whichs point to tc_cpu_ticks() by default) is
> called from mi_switch() which must be called often enough to satisfy
> tc_cpu_ticks() implementation (recognize just one timecounter
> overflow). That limits some of system parameters (at least hz
> selection).
>    It looks that tc_counter_mask is a little bit misused?
>    Maybe, tc_cpu_ticks() is only used for back compatibility and new
> system should use set_cputicker() to change this default?
>    Thanks for some help to better understand that.

I'm by no means an expert in this field - but your mentioning of AMD 
Elan SC400 triggered some old knowledge about the AMD Elan SC520.

If you have a look at the sys/i386/i386/elan-mmcr.c

Function "init_AMD_Elan_sc520()" adresses the fact that the i8254 has a 
nonstandard frequency with the AMD Elan SC520 at least - could it be the 
same with the SC400 ?

Just a thought ?


More information about the freebsd-hackers mailing list