Date: Sun, 6 Oct 2019 01:10:12 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Bruce Evans <brde@optusnet.com.au> Cc: Poul-Henning Kamp <phk@phk.freebsd.dk>, Sebastian Huber <sebastian.huber@embedded-brains.de>, Warner Losh <imp@bsdimp.com>, Konstantin Belousov <kostikbel@gmail.com>, FreeBSD <freebsd-hackers@freebsd.org> Subject: Re: Why is tc_get_timecount() called two times in tc_init()? Message-ID: <20191006000900.E2009@besplex.bde.org> In-Reply-To: <20191005171343.X925@besplex.bde.org> References: <0e27fb3e-0f60-68e1-dbba-f17c3d91c332@embedded-brains.de> <20191002140040.GA44691@kib.kiev.ua> <20191003013314.O2151@besplex.bde.org> <20191002163946.GE44691@kib.kiev.ua> <20191003030837.C2787@besplex.bde.org> <20191003084021.GI44691@kib.kiev.ua> <CANCZdfpcOBJiYAKafhiWZS2g4vnLGVvzqhaOXetSSnU2Hj91nw@mail.gmail.com> <47834.1570116246@critter.freebsd.dk> <141ee0af-2ff4-50fc-b4e4-6d1fc47e04f3@embedded-brains.de> <60167.1570198248@critter.freebsd.dk> <20191005024530.U1757@besplex.bde.org> <20191005171343.X925@besplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20191006000900.E2009>