tech-kern archive

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

Re: PSA: Clock drift and pkgin



> Date: Fri, 22 Dec 2023 23:41:47 -0500 (EST)
> From: Mouse <mouse%Rodents-Montreal.ORG@localhost>
> 
> Specifically, under a kernel built with HZ=100, requesting signals at
> 100Hz actually delivers them at 50Hz.  This is behind the clock running
> at half speed on my VAX emulator, and quite likely behind similar
> behaviour from simh (which emulates VAXen, among other things) on 9.3.
> I suspect it will happen on any port when requesting signals one timer
> tick apart (ie, at HZ Hz).

This is the well-known problem that we don't have timers with sub-tick
resolution, PR kern/43997: https://gnats.netbsd.org/43997

In particular, there is no way to reliably sleep for a duration d
below 1/hz sec.  In principle with the current timer design it may be
possible to sleep for shorter durations, but not to sleep for _at
least_ any shorter duration (because the next tick wakeup might be
arbitrarily soon); the shortest duration that a process can reliably
sleep is 1/hz sec, but it may be up to 2/hz sec owing to scheduling
delays.

Fixing this requires adopting an MI API and MD clock driver support
for wakeups with sub-tick resolution, which nobody's done yet -- it's
not trivial and there's a lot of design choices to make.

> I don't _know_ what's behind it.  But today I went looking, and, in
> 5.2, there is code which looks suspicious.  I don't know where the
> analogous code is in 9.x, but presumably plenty of people here do.
> Speaking of 5.2, then: in kern/subr_time.c, there is tvtohz(), which
> has code
> 
>         } else if (sec <= (LONG_MAX / 1000000))
>                 ticks = (((sec * 1000000) + (unsigned long)usec + (tick - 1))
>                     / tick) + 1;
> 
> which looks suspicious.  If sec is zero and usec is tick, that
> expression will return 2 instead of the 1 I suspect it needs to return.

Whether this is a bug depends on whether:

(a) callout_schedule(ch, 1) triggers ch on the _next_ tick, meaning
    its delay may be arbitrarily small, or

(b) callout_schedule(ch, 1) triggers ch on the next tick after that,
    meaning it may be delayed by [1/hz sec, 2/hz sec].

I don't know offhand which of these it is but it shouldn't be too hard
to determine.


Home | Main Index | Thread Index | Old Index