Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: "dmesg -T" date doesn't match "date" output

> On Oct 29, 2018, at 17:21, Robert Elz <kre%munnari.OZ.AU@localhost> wrote:
>  | We are talking about internal kernel data. If you need $uptime, you
>  | could expose it like $boottime.
> We could, but deisigning a system where now - boottime != uptime is
> kind of weird, don't you think?   boottime is where it all starts, if boottime
> is X, and uptime is Y, then X + Y should be now.
> None of that means that there can't be activity before boot time of
> course, we need to pick an epoch, (just like unix timestamps have
> 0 at 1 Jan 1970) and it should be something meaningful, with
> some practical reason to exist - but pick a point to call 0 does
> not mean earlier times don't exist.

Note that time_second(9) says boottime is “the system boot time” (in UTC,
implicitly) while uptime is “the time elapsed since boot”. I believe this
unambiguously defines boottime to be the (UTC) time when uptime was zero;
boottime is uptime’s epoch. This doesn’t mean that boottime needs to be
set when uptime is zero, it just means that when boottime is set it needs
to be set to (time(now) - uptime(now)) rather than just time(now). That it
is initialized to the latter is the bug.

It may be worth pointing out that the code in kern/kern_tc.c is written to
maintain the identity

    time = uptime + boottime

at all times, except that it instead maintains a local version of boottime
in the local variable timebasebin. While it is hard to deduce by reading it
the precision timescale that is maintained in there is actually uptime; when
something wants time it reads uptime(now) and adds timebasebin to it (i.e.
uptime + boottime) to compute the time of day. timebasebin is essentially
a version of ‘boottime’ that is initialized and maintained correctly, the
time of day of the uptime epoch.

I suspect the easiest way to fix the bug would be to eliminate the
independent initialization and maintenance of the boottime variable in
init_main.c and kern_time.c in favor of adding a

     bintime2timespec(&timebasebin, &boottime);

after timebasebin is updated in kern_tc.c:tc_setclock(). The code that
manipulates boottime outside of kern_tc.c is actually a leftover vestige
of the clock support code prior to timecounters that probably should have
disappeared when the latter was implemented.

As a quibble, the code in kern_todr.c:inittodr() could probably be improved
a bit. If reading the todr is successful what is returned is about the best
estimate of time(now) that we have so calling tc_setclock() with this value
is appropriate. If it falls back to the file system time, however, we can
not only be sure that this isn’t time(now) but is in fact a time that
predates the uptime epoch, so calling

    tc_setclock(filesystemtime + uptime(now) + maybe_a_fudge_factor)

would produce a time(now) that is at least a few seconds closer to reality.


Home | Main Index | Thread Index | Old Index