lost = jiffies - wall_jiffies;
if (lost)
usec += lost * (1000000 / HZ);
+
+ /*
+ * If time_adjust is negative then NTP is slowing the clock
+ * so make sure not to go into next possible interval.
+ * Better to lose some accuracy than have time go backwards..
+ */
+ if (unlikely(time_adjust < 0) && usec > tickadj)
+ usec = tickadj;
+
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
} while (read_seqretry(&xtime_lock, seq));
extern long time_reftime; /* time at last adjustment (s) */
extern long time_adjust; /* The amount of adjtime left */
+extern long time_next_adjust; /* Value for time_adjust at next tick */
/* interface variables pps->timer interrupt */
extern long pps_offset; /* pps time offset (us) */
result = time_state; /* mostly `TIME_OK' */
/* Save for later - semantics of adjtime is to return old value */
- save_adjust = time_adjust;
+ save_adjust = time_next_adjust ? time_next_adjust : time_adjust;
#if 0 /* STA_CLOCKERR is never set yet */
time_status &= ~STA_CLOCKERR; /* reset STA_CLOCKERR */
if (txc->modes & ADJ_OFFSET) { /* values checked earlier */
if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
/* adjtime() is independent from ntp_adjtime() */
- time_adjust = txc->offset;
+ if ((time_next_adjust = txc->offset) == 0)
+ time_adjust = 0;
}
else if ( time_status & (STA_PLL | STA_PPSTIME) ) {
ltemp = (time_status & (STA_PPSTIME | STA_PPSSIGNAL)) ==
long time_adj; /* tick adjust (scaled 1 / HZ) */
long time_reftime; /* time at last adjustment (s) */
long time_adjust;
+long time_next_adjust;
/*
* this routine handles the overflow of the microsecond field
}
xtime.tv_nsec += delta_nsec;
time_interpolator_update(delta_nsec);
+
+ /* Changes by adjtime() do not take effect till next tick. */
+ if (time_next_adjust != 0) {
+ time_adjust = time_next_adjust;
+ time_next_adjust = 0;
+ }
}
/*