Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140109536
D42940.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D42940.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D42940: FFclock: Upgrade of the FFclock daemon API
Attached
Detach File
Event Timeline
Log In to Comment