summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_ntptime.c74
-rw-r--r--sys/kern/kern_tc.c23
-rw-r--r--sys/kern/kern_time.c72
-rw-r--r--sys/kern/subr_param.c2
-rw-r--r--sys/sys/kernel.h3
5 files changed, 78 insertions, 96 deletions
diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c
index 4a9c7a6..d8218db 100644
--- a/sys/kern/kern_ntptime.c
+++ b/sys/kern/kern_ntptime.c
@@ -152,6 +152,8 @@ static l_fp time_offset; /* time offset (ns) */
static l_fp time_freq; /* frequency offset (ns/s) */
static l_fp time_adj; /* tick adjust (ns/s) */
+static int64_t time_adjtime; /* correction from adjtime(2) (usec) */
+
#ifdef PPS_SYNC
/*
* The following variables are used when a pulse-per-second (PPS) signal
@@ -437,6 +439,7 @@ void
ntp_update_second(struct timecounter *tcp)
{
u_int32_t *newsec;
+ int tickrate;
l_fp ftemp; /* 32/64-bit temporary */
newsec = &tcp->tc_offset.sec;
@@ -532,7 +535,31 @@ ntp_update_second(struct timecounter *tcp)
time_adj = ftemp;
L_SUB(time_offset, ftemp);
L_ADD(time_adj, time_freq);
+
+ /*
+ * Apply any correction from adjtime(2). If more than one second
+ * off we slew at a rate of 5ms/s (5000 PPM) else 500us/s (500PPM)
+ * until the last second is slewed the final < 500 usecs.
+ */
+ if (time_adjtime != 0) {
+ if (time_adjtime > 1000000)
+ tickrate = 5000;
+ else if (time_adjtime < -1000000)
+ tickrate = -5000;
+ else if (time_adjtime > 500)
+ tickrate = 500;
+ else if (time_adjtime < -500)
+ tickrate = -500;
+ else if (time_adjtime != 0)
+ tickrate = time_adjtime;
+ else
+ tickrate = 0; /* GCC sucks! */
+ time_adjtime -= tickrate;
+ L_LINT(ftemp, tickrate * 1000);
+ L_ADD(time_adj, ftemp);
+ }
tcp->tc_adjustment = time_adj;
+
#ifdef PPS_SYNC
if (pps_valid > 0)
pps_valid--;
@@ -865,3 +892,50 @@ hardpps(tsp, nsec)
time_freq = pps_freq;
}
#endif /* PPS_SYNC */
+
+#ifndef _SYS_SYSPROTO_H_
+struct adjtime_args {
+ struct timeval *delta;
+ struct timeval *olddelta;
+};
+#endif
+/*
+ * MPSAFE
+ */
+/* ARGSUSED */
+int
+adjtime(struct thread *td, struct adjtime_args *uap)
+{
+ struct timeval atv;
+ int error;
+
+ mtx_lock(&Giant);
+
+ if ((error = suser(td)))
+ goto done2;
+ if (uap->olddelta) {
+ atv.tv_sec = time_adjtime / 1000000;
+ atv.tv_usec = time_adjtime % 1000000;
+ if (atv.tv_usec < 0) {
+ atv.tv_usec += 1000000;
+ atv.tv_sec--;
+ }
+ printf("Old: time_adjtime = %ld.%06ld %lld\n",
+ atv.tv_sec, atv.tv_usec, time_adjtime);
+ error = copyout(&atv, uap->olddelta, sizeof(atv));
+ if (error)
+ goto done2;
+ }
+ if (uap->delta) {
+ error = copyin(uap->delta, &atv, sizeof(atv));
+ if (error)
+ goto done2;
+ time_adjtime = (int64_t)atv.tv_sec * 1000000 + atv.tv_usec;
+ printf("New: time_adjtime = %ld.%06ld %lld\n",
+ atv.tv_sec, atv.tv_usec, time_adjtime);
+ }
+done2:
+ mtx_unlock(&Giant);
+ return (error);
+}
+
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index e058e74..18e3ce3 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -238,11 +238,11 @@ tco_setscales(struct timecounter *tc)
/*
* We get nanoseconds with 32 bit binary fraction and want
* 64 bit binary fraction: x = a * 2^32 / 10^9 = a * 4.294967296
- * The range is +/- 500PPM so we can only multiply by about 8500
- * without overflowing. The best suitable fraction is 4398/1024.
- * Divide by 2 times 1024 to match the temporary lower precision.
+ * The range is +/- 5000PPM so we can only multiply by about 850
+ * without overflowing. The best suitable fraction is 2199/512.
+ * Divide by 2 times 512 to match the temporary lower precision.
*/
- scale += (tc->tc_adjustment * 4398) / 2048;
+ scale += (tc->tc_adjustment / 1024) * 2199;
scale /= tc->tc_tweak->tc_frequency;
tc->tc_scale = scale * 2;
}
@@ -338,7 +338,6 @@ tc_windup(void)
{
struct timecounter *tc, *tco;
struct bintime bt;
- struct timeval tvt;
unsigned ogen, delta;
int i;
@@ -362,20 +361,6 @@ tc_windup(void)
*/
if (tco->tc_poll_pps)
tco->tc_poll_pps(tco);
- if (timedelta != 0) {
- tvt = boottime;
- tvt.tv_usec += tickdelta;
- if (tvt.tv_usec >= 1000000) {
- tvt.tv_sec++;
- tvt.tv_usec -= 1000000;
- } else if (tvt.tv_usec < 0) {
- tvt.tv_sec--;
- tvt.tv_usec += 1000000;
- }
- boottime = tvt;
- timeval2bintime(&boottime, &boottimebin);
- timedelta -= tickdelta;
- }
for (i = tc->tc_offset.sec - tco->tc_offset.sec; i > 0; i--) {
ntp_update_second(tc); /* XXX only needed if xntpd runs */
tco_setscales(tc);
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index c24e9b0..fd86212 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -386,78 +386,6 @@ settimeofday(td, uap)
}
return (error);
}
-
-int tickdelta; /* current clock skew, us. per tick */
-long timedelta; /* unapplied time correction, us. */
-static long bigadj = 1000000; /* use 10x skew above bigadj us. */
-
-#ifndef _SYS_SYSPROTO_H_
-struct adjtime_args {
- struct timeval *delta;
- struct timeval *olddelta;
-};
-#endif
-/*
- * MPSAFE
- */
-/* ARGSUSED */
-int
-adjtime(td, uap)
- struct thread *td;
- register struct adjtime_args *uap;
-{
- struct timeval atv;
- register long ndelta, ntickdelta, odelta;
- int s, error;
-
- mtx_lock(&Giant);
-
- if ((error = suser(td)))
- goto done2;
- error = copyin((caddr_t)uap->delta, (caddr_t)&atv,
- sizeof(struct timeval));
- if (error)
- goto done2;
-
- /*
- * Compute the total correction and the rate at which to apply it.
- * Round the adjustment down to a whole multiple of the per-tick
- * delta, so that after some number of incremental changes in
- * hardclock(), tickdelta will become zero, lest the correction
- * overshoot and start taking us away from the desired final time.
- */
- ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
- if (ndelta > bigadj || ndelta < -bigadj)
- ntickdelta = 10 * tickadj;
- else
- ntickdelta = tickadj;
- if (ndelta % ntickdelta)
- ndelta = ndelta / ntickdelta * ntickdelta;
-
- /*
- * To make hardclock()'s job easier, make the per-tick delta negative
- * if we want time to run slower; then hardclock can simply compute
- * tick + tickdelta, and subtract tickdelta from timedelta.
- */
- if (ndelta < 0)
- ntickdelta = -ntickdelta;
- s = splclock();
- odelta = timedelta;
- timedelta = ndelta;
- tickdelta = ntickdelta;
- splx(s);
-
- if (uap->olddelta) {
- atv.tv_sec = odelta / 1000000;
- atv.tv_usec = odelta % 1000000;
- (void) copyout((caddr_t)&atv, (caddr_t)uap->olddelta,
- sizeof(struct timeval));
- }
-done2:
- mtx_unlock(&Giant);
- return (error);
-}
-
/*
* Get value of an interval timer. The process virtual and
* profiling virtual time timers are kept in the p_stats area, since
diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c
index 8c2e4c6..820fe0107 100644
--- a/sys/kern/subr_param.c
+++ b/sys/kern/subr_param.c
@@ -65,7 +65,6 @@
int hz;
int tick;
-int tickadj; /* can adjust 30ms in 60s */
int maxusers; /* base tunable */
int maxproc; /* maximum # of processes */
int maxprocperuid; /* max # of procs per user */
@@ -100,7 +99,6 @@ init_param1(void)
hz = HZ;
TUNABLE_INT_FETCH("kern.hz", &hz);
tick = 1000000 / hz;
- tickadj = howmany(30000, 60 * hz); /* can adjust 30ms in 60s */
#ifdef VM_SWZONE_SIZE_MAX
maxswzone = VM_SWZONE_SIZE_MAX;
diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h
index 7bc3a3e..9eff1b6 100644
--- a/sys/sys/kernel.h
+++ b/sys/sys/kernel.h
@@ -71,15 +71,12 @@ extern struct timeval boottime;
extern struct timezone tz; /* XXX */
extern int tick; /* usec per tick (1000000 / hz) */
-extern int tickadj; /* "standard" clock skew, us./tick */
extern int hz; /* system clock's frequency */
extern int psratio; /* ratio: prof / stat */
extern int stathz; /* statistics clock's frequency */
extern int profhz; /* profiling clock's frequency */
extern int ticks;
extern int lbolt; /* once a second sleep address */
-extern int tickdelta;
-extern long timedelta;
#endif /* _KERNEL */
OpenPOWER on IntegriCloud