[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freebsd-hackers
Subject:    Re: Why is tc_get_timecount() called two times in tc_init()?
From:       Bruce Evans <brde () optusnet ! com ! au>
Date:       2019-10-05 15:10:12
Message-ID: 20191006000900.E2009 () besplex ! bde ! org
[Download RAW message or body]

On Sat, 5 Oct 2019, Bruce Evans wrote:

> Now event timers give more cases:
> - i8254 used for one-shot timeouts, so interrupting.  Syncing with its
>  interrupt needed but not done (programming one-shot timeouts doesn't
>  change internal state so leaves it as garbage).  Syncing was done for
>  pcaudio by only reprogramming the timeouts in the interrupt handler
>  under suitable locks.

Actual testing shows that event timers avoid this bug by only supporting
one-shot mode if the i8254 is not statically configured as a timecounter.
The i8254 is statically configured as a timecounter by default, but this
can be changed by an obscure environment variable ("attimer0.timecounter",
is not a tunable or readonly sysctl for some reason, and its device nameunit
"attimer0" is different from the timecounter and eventtimer name "i8254").

However, all timecounters that rollover on every timer interrupt were
broken for HZ > 1500 in r95947 in 2002, by limiting the frequency of
calling tc_windup() to 1000 Hz with slop to 1500 Hz.  tc_windup() is
supposed to guarantee calling tc_get_timecount() more often than
rollover, and limiting tc_windup()s freqency to anything less than HZ
breaks this when the rollover frequency is HZ.

After fixing this by removing the dynamic configuration of the
misdocumented divisor tc_tick (see sysctl -d output for useless information
about what this is), the i8254 rollover detection code still works at the
high frequency HZ = 20k.  Tested on an 8-CPU 4 GHz system using
kern.timecounter.hardware=i8254 and kern.eventtimer.timer=i8254 (this
forces a period eventtimer).  Interrupt latency from the interrupt to
tc_windup must be less than 25 (or perhaps 17 usec) for this to work.
4GHz and a spare CPU may be needed for this latency now, though i486/33
UP was enough before SMPng.

The sysctl to control tc_tick has different bugs in all versions.  It
was born broken in r95497 by misspelling its variable name as 'tick'
(this only compiles by referencing the unrelated global 'tick') and
by making it read-only despite the code having a long comment with
advice about changing it.  The spelling error was fixed in r108671.
The comment remains unchanged.  Completing the fix used to require
just changing CTLFLAG_RD to CTLFLAG_RW, but now it involves using a
sysctl function to update the associated globals tc_tick_bt and
tc_tick_sbt and possibly also lots of timeout state that was scaled
using these globals.

The sysctl is not fixed in my version, but I sometimes changed tc_tick
using ddb.  Now changing only tc_tick breaks timeouts.

Bruce
_______________________________________________
freebsd-hackers@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic