svn commit: r349029 - head/sys/kern

Bruce Evans brde at optusnet.com.au
Fri Jun 14 14:25:10 UTC 2019


On Fri, 14 Jun 2019, Alexander Motin wrote:

> On 14.06.2019 08:58, Bruce Evans wrote:
>> On Fri, 14 Jun 2019, Alexander Motin wrote:
>>
>>> Log:
>>>  Update td_runtime of running thread on each statclock().
>>>
>>>  Normally td_runtime is updated on context switch, but there are some
>>> kernel
>>>  threads that due to high absolute priority may run for many seconds
>>> without
>>>  context switches (yes, that is bad, but that is true), which means their
>>>  td_runtime was not updated all that time, that made them invisible
>>> for top
>>>  other then as some general CPU usage.
>>>
>>>  MFC after:    1 week
>>>  Sponsored by:    iXsystems, Inc.
>>
>> This and more is supposed to be done in calcru().  It is also necessary to
>> adjust for the current timeslice.
>>
>> I thought that calcru() was fixed, but the fix seems to be only in my
>> version of FreeBSD-5.2.
>>
>> The bug seems to be in fill_kinfo_proc_only().  calcru() should update
>> td_runtime for all threads in the proc (and sum into rux_rutime),
>
> ...
>
>> td_runtime is updated in one other place: in rufetchtd(), but this function
>> has the same bug eas everywhere else -- it only updates the runtimes for
>> curthread.
>
> I think it has very simple reason -- now each CPU measures CPU time in
> its own time units, since cpu_ticks() are not synchronized and can not
> be compared between different CPUs, so to update td_runtime of another
> running thread you would need to switch to that CPU, or somehow else get
> the value (cache it periodically?).

I forgot about that bugfeature in the cpu ticker.

> I see in your code you are using binuptime() calls instead of
> cpu_ticks().  I suppose it fixes many problems, since it is globally
> synchronous, but there was a reason why cpu_ticks() exists -- it is
> cheaper on system non-synchronized TSC.  May be we could reconsider
> that, giving up on old platforms, expecting all new one to not have this
> problem, but for right now I think my patch is good enough to make top
> sane again, that annoyed me for years.

It was written before the cpu ticker existed.

cpu_ticks() exists because bintime() is too slow if the timecounter hardware
is too slow.  i8254 timecounter hardware takes about 5 usec, ACPI timer
about 1 usec, and HPET many hundreds of nsec.  And of course,
non-synchronized TSCs make the TSC unusable as a timecounter, so require
use of a slow timecounter.  Some systems don't have a TSC, so they use a
timecounter for the cpu ticker anyway.

There are many other bugs in the cpu ticker which only became not too bad
when P-state invariant TSCs became common.  The largest one is that all
ticks are scaled at the current cpu ticker frequency.  If synchronized
P-state invariant TSCs are available, then the cpu ticker reduces to
a micro-optimization.

My code is used mainly on UP systems with TSC timecounters.  I don't have
any systems without a TSC, and UP avoids the problems of synchronization,
and not throttling the CPU avoids the problem of the frequency changing,
and I never noticed the micro-pessimization of using bintime() for the
cpu ticker.

I never noticed the problem in -current either, though I use my version of
SCHED_4BSD with lots of tuning to reduce context switches.  The tuning often
results in threads running for a full quantum (100 msec) before switching,
but I never noticed threads not switching for several seconds.

Bruce


More information about the svn-src-all mailing list