tc_windup() calls ntp_update_second() up to 200 times:
/* * A large step happens on boot. This constant detects such steps. * It is relatively small so that ntp_update_second gets called enough * in the typical 'missed a couple of seconds' case, but doesn't loop * forever when the time step is large. */ #define LARGE_STEP 200
ntp_update_second() subtracts some amount of time from adjtimedelta and sets th->th_adjustment accordingly. However, if ntp_update_second is called more than once in a row, only the last value of th->th_adjustment is actually applied. Shouldn't the adjustments from all ntp_update_second calls be added instead? I don't know how often this is actually hit in practice, the normal case is that ntp_update_second is called only once.
diff --git sys/kern/kern_tc.c sys/kern/kern_tc.c index 59b31dc..60ea119 100644 --- sys/kern/kern_tc.c +++ sys/kern/kern_tc.c @@ -425,8 +426,12 @@ tc_windup(void) i = bt.sec - tho->th_microtime.tv_sec; if (i > LARGE_STEP) i = 2; - for (; i > 0; i--) - ntp_update_second(&th->th_adjustment, &bt.sec); + th->th_adjustment = 0; + for (; i > 0; i--) { + uint64_t adj; + ntp_update_second(&adj, &bt.sec); + th->th_adjustment += adj; + } /* Update the UTC timestamps used by the get*() functions. */ /* XXX shouldn't do this here. Should force non-`get' versions. */