Page MenuHomeFreeBSD

D42940.diff
No OneTemporary

D42940.diff

diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
--- a/sys/compat/freebsd32/freebsd32.h
+++ b/sys/compat/freebsd32/freebsd32.h
@@ -67,14 +67,14 @@
struct ffclock_estimate32 {
struct bintime32 update_time;
ffcounter update_ffcount;
- ffcounter leapsec_next;
+ ffcounter leapsec_expected;
uint64_t period;
uint32_t errb_abs;
uint32_t errb_rate;
uint32_t status;
- int16_t leapsec_total;
- int8_t leapsec;
- int8_t _pad;
+ int16_t secs_to_nextupdate;
+ int8_t leapsec_total;
+ int8_t leapsec_next;
}
#if defined(__amd64__)
__attribute__((packed))
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -4103,16 +4103,17 @@
sizeof(struct ffclock_estimate32))) != 0)
return (error);
- CP(cest.update_time, cest32.update_time, sec);
+ CP(cest32.update_time, cest.update_time, sec);
memcpy(&cest.update_time.frac, &cest32.update_time.frac, sizeof(uint64_t));
- CP(cest, cest32, update_ffcount);
- CP(cest, cest32, leapsec_next);
- CP(cest, cest32, period);
- CP(cest, cest32, errb_abs);
- CP(cest, cest32, errb_rate);
- CP(cest, cest32, status);
- CP(cest, cest32, leapsec_total);
- CP(cest, cest32, leapsec);
+ CP(cest32, cest, update_ffcount);
+ CP(cest32, cest, leapsec_expected);
+ CP(cest32, cest, period);
+ CP(cest32, cest, errb_abs);
+ CP(cest32, cest, errb_rate);
+ CP(cest32, cest, status);
+ CP(cest32, cest, secs_to_nextupdate);
+ CP(cest32, cest, leapsec_total);
+ CP(cest32, cest, leapsec_next);
mtx_lock(&ffclock_mtx);
memcpy(&ffclock_estimate, &cest, sizeof(struct ffclock_estimate));
@@ -4133,16 +4134,17 @@
memcpy(&cest, &ffclock_estimate, sizeof(struct ffclock_estimate));
mtx_unlock(&ffclock_mtx);
- CP(cest32.update_time, cest.update_time, sec);
+ CP(cest.update_time, cest32.update_time, sec);
memcpy(&cest32.update_time.frac, &cest.update_time.frac, sizeof(uint64_t));
- CP(cest32, cest, update_ffcount);
- CP(cest32, cest, leapsec_next);
- CP(cest32, cest, period);
- CP(cest32, cest, errb_abs);
- CP(cest32, cest, errb_rate);
- CP(cest32, cest, status);
- CP(cest32, cest, leapsec_total);
- CP(cest32, cest, leapsec);
+ CP(cest, cest32, update_ffcount);
+ CP(cest, cest32, leapsec_expected);
+ CP(cest, cest32, period);
+ CP(cest, cest32, errb_abs);
+ CP(cest, cest32, errb_rate);
+ CP(cest, cest32, status);
+ CP(cest, cest32, secs_to_nextupdate);
+ CP(cest, cest32, leapsec_total);
+ CP(cest, cest32, leapsec_next);
error = copyout(&cest32, uap->cest, sizeof(struct ffclock_estimate32));
return (error);
diff --git a/sys/kern/kern_ffclock.c b/sys/kern/kern_ffclock.c
--- a/sys/kern/kern_ffclock.c
+++ b/sys/kern/kern_ffclock.c
@@ -91,14 +91,14 @@
} while (update_ffcount != ffclock_estimate.update_ffcount);
/*
- * Leap second adjustment. Total as seen by synchronisation algorithm
- * since it started. cest.leapsec_next is the ffcounter prediction of
- * when the next leapsecond occurs.
+ * Leap second adjustment. Total as seen by the FFclock daemon since it
+ * started. cest.leapsec_expected is the ffcounter prediction of when
+ * the next leapsecond occurs.
*/
if ((flags & FFCLOCK_LEAPSEC) == FFCLOCK_LEAPSEC) {
- bt->sec -= cest.leapsec_total;
- if (ffc > cest.leapsec_next)
- bt->sec -= cest.leapsec;
+ bt->sec -= cest.leapsec_total; // subtracting = including leaps
+ if (cest.leapsec_expected != 0 && ffc > cest.leapsec_expected)
+ bt->sec -= cest.leapsec_next;
}
/* Boot time adjustment, for uptime/monotonic clocks. */
@@ -159,9 +159,9 @@
#define MAX_SYSCLOCK_NAME_LEN 16
#define NUM_SYSCLOCKS nitems(sysclocks)
-static int ffclock_version = 2;
+static int ffclock_version = 3;
SYSCTL_INT(_kern_sysclock_ffclock, OID_AUTO, version, CTLFLAG_RD,
- &ffclock_version, 0, "Feedforward clock kernel version");
+ &ffclock_version, 0, "FFclock kernel version");
/* List available sysclocks. */
static int
@@ -375,7 +375,7 @@
/*
* System call allowing userland applications to retrieve the current value of
- * the feedforward clock counter.
+ * the FFclock counter.
*/
#ifndef _SYS_SYSPROTO_H_
struct ffclock_getcounter_args {
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -579,13 +579,14 @@
timespec2bintime(ts, &ffclock_boottime);
timespec2bintime(ts, &(cest.update_time));
ffclock_read_counter(&cest.update_ffcount);
- cest.leapsec_next = 0;
+ cest.secs_to_nextupdate = 0;
cest.period = ((1ULL << 63) / tc->tc_frequency) << 1;
cest.errb_abs = 0;
cest.errb_rate = 0;
cest.status = FFCLOCK_STA_UNSYNC;
+ cest.leapsec_expected = 0;
cest.leapsec_total = 0;
- cest.leapsec = 0;
+ cest.leapsec_next = 0;
mtx_lock(&ffclock_mtx);
memcpy(&ffclock_estimate, &cest, sizeof(struct ffclock_estimate));
@@ -647,7 +648,6 @@
struct bintime bt, gap;
ffcounter ffdelta;
uint64_t frac;
- unsigned int polling;
uint8_t forward_jump, ogen;
/* Prepare next fftimehand where tick state will be updated. */
@@ -683,18 +683,20 @@
bintime_add(&ffth->tick_time_mono, &bt);
/* Check if the clock status should be set to unsynchronized.
- * Assessment based on age of last/current update. If the
+ * Assessment based on age of last/current update, and the
+ * daemon's estimate of the wait to the next update. If the
* daemon's UNSYNC status is too stale, it is over-ridden.
*/
if (ffclock_updated == 0) {
- ffdelta = ffth->tick_ffcount - cest->update_ffcount;
- ffclock_convert_delta(ffdelta, cest->period, &bt);
- if (bt.sec > 2 * FFCLOCK_SKM_SCALE)
+ bt = ffth->tick_time;
+ bintime_sub(&bt, &cest->update_time);
+ if (bt.sec > 3 * FFCLOCK_SKM_SCALE &&
+ bt.sec > 3 * cest->secs_to_nextupdate)
ffclock_status |= FFCLOCK_STA_UNSYNC;
}
}
-
+
/*
* An update in FFclock parameters is available in this tick. Generate
* the new tick state based on this, projected from the update time.
@@ -733,7 +735,7 @@
bintime_add(&ffth->tick_time_mono, &bt);
}
- /* Record direction of jump between monoFFC and natFFC */
+ /* Record direction of jump between monoFFC and natFFC. */
if (bintime_cmp(&ffth->tick_time, &ffth->tick_time_mono, >))
forward_jump = 1;
else
@@ -789,21 +791,20 @@
ffth->period_mono = cest->period; // re-initialize
/* Keep default if no visible gap or no daemon updates yet. */
- if (bintime_isset(&gap)) {
-
- /* Estimate #seconds to next update. */
- ffdelta = cest->update_ffcount;
- ffdelta -= fftimehands->cest.update_ffcount;
- ffclock_convert_delta(ffdelta, cest->period, &bt);
- polling = bt.sec;
+ if (bintime_isset(&gap) && cest->secs_to_nextupdate > 0) {
/* Calculate cap */
bt.sec = 0;
bt.frac = 5000000 * NS_AS_BINFRAC;
- bintime_mul(&bt, polling);
+ bintime_mul(&bt, cest->secs_to_nextupdate);
if (bintime_cmp(&gap, &bt, >))
gap = bt; // gap = min(gap, bt)
+ /* Convert secs_to_nextupdate to counter units. */
+ frac = 0;
+ frac -= 1; // approximate 2^64 with (2^64)-1 for ease
+ ffdelta = (frac/cest->period) * cest->secs_to_nextupdate;
+
/* Store the portion of gap per cycle in frac. */
frac = 0;
if (gap.sec > 0) {
@@ -877,10 +878,14 @@
memcpy(cest, &(fftimehands->cest), sizeof(struct ffclock_estimate));
cest->update_ffcount = ffth->tick_ffcount;
+ cest->secs_to_nextupdate = 0;
cest->period = ((1ULL << 63) / tc->tc_frequency ) << 1;
cest->errb_abs = 0;
cest->errb_rate = 0;
cest->status |= FFCLOCK_STA_UNSYNC;
+ cest->leapsec_expected = 0;
+ cest->leapsec_total = 0;
+ cest->leapsec_next = 0;
ffth->tick_time = fftimehands->tick_time;
ffth->tick_error = fftimehands->tick_error;
@@ -1206,10 +1211,14 @@
if (!fast)
clock_snap->ffcount += delta;
- /* Record feedforward clock leap second adjustment. */
+ /*
+ * Pre-calculate total leap adjustment appropriate to this ffcount. That
+ * is, total leaps so far and impending leap ffcount may have surpassed.
+ */
ffi->leapsec_adjustment = cest.leapsec_total;
- if (clock_snap->ffcount > cest.leapsec_next)
- ffi->leapsec_adjustment -= cest.leapsec;
+ if (cest.leapsec_expected != 0 && clock_snap->ffcount >
+ cest.leapsec_expected)
+ ffi->leapsec_adjustment += cest.leapsec_next;
/* Record feedforward clock status and error. */
ffi->status = cest.status;
diff --git a/sys/sys/timeffc.h b/sys/sys/timeffc.h
--- a/sys/sys/timeffc.h
+++ b/sys/sys/timeffc.h
@@ -34,6 +34,10 @@
#include <sys/_ffcounter.h>
+
+#if __BSD_VISIBLE
+#ifdef _KERNEL
+
/*
* Feedforward clock estimate
* Holds time mark as a ffcounter and conversion to bintime based on current
@@ -41,20 +45,18 @@
* Provides time of last daemon update, clock status and bound on error.
*/
struct ffclock_estimate {
- struct bintime update_time; /* Time of last estimates update. */
- ffcounter update_ffcount; /* Counter value at last update. */
- ffcounter leapsec_next; /* Counter value of next leap second. */
- uint64_t period; /* Estimate of counter period. */
- uint32_t errb_abs; /* Bound on absolute clock error [ns]. */
- uint32_t errb_rate; /* Bound on counter rate error [ps/s]. */
- uint32_t status; /* Clock status. */
- int16_t leapsec_total; /* All leap seconds seen so far. */
- int8_t leapsec; /* Next leap second (in {-1,0,1}). */
+ struct bintime update_time; /* FFclock time of last update. */
+ ffcounter update_ffcount; /* Counter value at last update. */
+ ffcounter leapsec_expected; /* Approx counter value of next leap. */
+ uint64_t period; /* Counter period estimate [2^-64 s]. */
+ uint32_t errb_abs; /* Bound on absolute clock error [ns]. */
+ uint32_t errb_rate; /* Bound on rel. counter period err [ps/s]*/
+ uint32_t status; /* Clock status. */
+ uint16_t secs_to_nextupdate;/* Estimated wait til next update [s]. */
+ int8_t leapsec_total; /* Sum of leap secs since clock start. */
+ int8_t leapsec_next; /* Next leap second (in {-1,0,1}). */
};
-#if __BSD_VISIBLE
-#ifdef _KERNEL
-
/* Constants to hold errors and error rates in 64bit binary fraction fields. */
#define MS_AS_BINFRAC (uint64_t)18446744073709551ULL // floor(2^64/1e3)
#define MUS_AS_BINFRAC (uint64_t)18446744073709ULL // floor(2^64/1e6)

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 21, 8:48 AM (12 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27110534
Default Alt Text
D42940.diff (10 KB)

Event Timeline