svn commit: r320901 - in head/sys: amd64/amd64 isa x86/isa

Ian Lepore ian at freebsd.org
Tue Jul 18 14:59:01 UTC 2017


On Tue, 2017-07-18 at 18:08 +1000, Bruce Evans wrote:
> On Mon, 17 Jul 2017, Ian Lepore wrote:
> 
> > On Thu, 2017-07-13 at 01:42 +1000, Bruce Evans wrote:
> >> On Wed, 12 Jul 2017, Ian Lepore wrote:
> >>
> >>> Log:
> [...]
> 
> I could barely read the reply, due to corruption of whitespace to
> spaces
> and \xa0.  Formatting fixed, except all tabs are corrupted to spaces,
> and there are extra blank lines after quotes.
> 

My mail client broke two updates ago.  I think nobody who works on gui
apps does plain-text email anymore; if html mail looks good they're
done.  ::sigh::

> >
> [lots of stuff about locking and accurate time-setting]
> 
> Good idea.
> 
> My inittodr() waits for the seconds register to change.  This
> increases
> boot time by an average of 0.5 seconds, but is needed to get a result
> that is not out of date by an average of 0.5 seconds.  After the
> seconds
> register changes, the window for reading the other registers is
> almost
> 1 second, but the reads must complete in a few microseconds anyway
> else
> the result is still too out of date.  Debugging printf()s show that
> the reads usually complete in 10-50 usec with low latency (faster on
> old systems with faster ISA buses).
> 

I was considering adding a tunable to do that for people who don't mind
the extra time to boot/wakeup.  It's interesting that you label an
error of a few microseconds as "too out of date", I was thinking that
reducing the average error from .5s to .005s was good enough.

The .005s number comes from an idea of using a callout that begins as
soon as interrupts are available that checks for rtc rollover every
10ms, with the hopes that it can catch the rollover between the time
callouts start working and rootfs mount time when inittodr() gets
called.  If it can catch the rollover happening in that window, it can
latch the monotonic clock and then use that at inittodr() time to
calculate the fractional part of the time.  Even if it doesn't catch
the rollover in that time, it at least has a measurement that sets a
floor value for the fractional part, reducing the error to something
less than .5s.

I have no idea yet how much time elapses between interrupts coming
online and the first inittodr() call on a typical modern x86
system.  For all my arm systems with nfsroot it's several seconds.  If
it averages a few milliseconds on x86 systems, it isn't useful enough
to justify the extra work.  If it's typically half a second or more it
probably is worth it.

> Accuracy for reading is not very important because accuracy for
> writing
> is very low (1-2 seconds).  My resettodr() only writes if the
> difference
> is more than 2 seconds.
> 

The gross inaccuracy when writing is fixable now.  I'm not worried
about the microsecond inaccuracies of accessing the hardware, what I
want to fix is the fact that clock_settime() may get called at x.995
and will record the time as x.0.

Because settime is now called from a task thread, any clock driver is
free to sleep as needed to set the clock hardware in a way that aligns
its second rollover with kernel time.  Not efficient, but easy to do.

Even better, most rtc hardware has unused storage.  Sometimes in the
form of battery-backed ram, sometimes in the form of things like alarm
registers that aren't used for anything and a driver can tuck away
values in them for its own use.  If clock_settime() stores the
fractional part of the second in such a location, clock_gettime() can
use it to remove all of the inaccuracy that otherwise happens when the
fraction is discarded.  If even a single bit is available the error is
cut in half.  If a byte is available it drops to ~40ms.

-- Ian


More information about the svn-src-head mailing list