]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
refclock: rework update of reachability
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 31 Oct 2024 13:41:19 +0000 (14:41 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 5 Nov 2024 14:51:43 +0000 (15:51 +0100)
Update the reachability register of a refclock source by 1 if a valid
measurement is received by the drivers between source polls, and not
only when it is accumulated to sourcestats, similarly to how
reachability works with NTP sources.

This avoids drops in the reported reachability when a PHC refclock is
dropping samples due to significant changes in the measured delay (e.g.
due to high PCIe load), or a PPS refclock dropping samples due to failed
lock.

doc/chronyc.adoc
refclock.c
refclock.h
refclock_phc.c
refclock_pps.c
refclock_shm.c
refclock_sock.c
test/simulation/106-refclock

index 935f1da9346bce771ee8b55465e6fc8b139b7c2e..dea93c9f567349aef582de969e94766bc5dbbf61 100644 (file)
@@ -364,9 +364,12 @@ a measurement is being made every 64 seconds. *chronyd* automatically varies
 the polling rate in response to prevailing conditions.
 *Reach*:::
 This shows the source's reachability register printed as an octal number. The
-register has 8 bits and is updated on every received or missed packet from
-the source. A value of 377 indicates that a valid reply was received for all
-from the last eight transmissions.
+register has 8 bits. It is shifted to left by one bit with each poll and it is
+updated by 1 when a valid NTP response, or just a sample in case of a reference
+clock, is received from the source. A value of 377 indicates that a valid
+response or sample was received for all of the last 8 polls. Note that samples
+can be dropped if they are not considered good enough for synchronisation, but
+the reachability register will still have 1s for their polls.
 *LastRx*:::
 This column shows how long ago the last good sample (which is shown in the next
 column) was received from the source. Measurements that failed some tests are
index 22d775a5e7829a7927ced663c5d67c5e3b7eefc9..d14560fae98663308ed0e81269afe6b02f2ec978 100644 (file)
@@ -63,6 +63,7 @@ struct RCL_Instance_Record {
   int driver_poll;
   int driver_polled;
   int poll;
+  int reached;
   int leap_status;
   int local;
   int pps_forced;
@@ -175,6 +176,7 @@ RCL_AddRefclock(RefclockParameters *params)
   inst->driver_poll = params->driver_poll;
   inst->poll = params->poll;
   inst->driver_polled = 0;
+  inst->reached = 0;
   inst->leap_status = LEAP_Normal;
   inst->local = params->local;
   inst->pps_forced = params->pps_forced;
@@ -665,6 +667,12 @@ RCL_AddCookedPulse(RCL_Instance instance, struct timespec *cooked_time,
   return 1;
 }
 
+void
+RCL_UpdateReachability(RCL_Instance instance)
+{
+  instance->reached++;
+}
+
 double
 RCL_GetPrecision(RCL_Instance instance)
 {
@@ -792,6 +800,9 @@ poll_timeout(void *arg)
   if (!(inst->driver->poll && inst->driver_polled < (1 << (inst->poll - inst->driver_poll)))) {
     inst->driver_polled = 0;
 
+    SRC_UpdateReachability(inst->source, inst->reached > 0);
+    inst->reached = 0;
+
     if (SPF_GetFilteredSample(inst->filter, &sample)) {
       double local_freq, local_offset;
       struct timespec local_ref_time;
@@ -807,7 +818,6 @@ poll_timeout(void *arg)
         inst->leap_status = LEAP_Unsynchronised;
       }
 
-      SRC_UpdateReachability(inst->source, 1);
       SRC_UpdateStatus(inst->source, stratum, inst->leap_status);
       SRC_AccumulateSample(inst->source, &sample);
       SRC_SelectSource(inst->source);
@@ -816,8 +826,6 @@ poll_timeout(void *arg)
         follow_local(inst, &local_ref_time, local_freq, local_offset);
 
       log_sample(inst, &sample.time, 1, 0, 0.0, sample.offset, sample.peer_dispersion);
-    } else {
-      SRC_UpdateReachability(inst->source, 0);
     }
   }
 
index 40c852deb5dd2f4051a1d6c801b50310db8bc3e8..5fdbf9c75cb61b00a70b09229bc86bd298aab50f 100644 (file)
@@ -81,6 +81,7 @@ extern int RCL_AddSample(RCL_Instance instance, struct timespec *sample_time,
 extern int RCL_AddPulse(RCL_Instance instance, struct timespec *pulse_time, double second);
 extern int RCL_AddCookedPulse(RCL_Instance instance, struct timespec *cooked_time,
                               double second, double dispersion, double raw_correction);
+extern void RCL_UpdateReachability(RCL_Instance instance);
 extern double RCL_GetPrecision(RCL_Instance instance);
 extern int RCL_GetDriverPoll(RCL_Instance instance);
 
index e12f22583861e2d7d90560fdaa9a53e2262aab9c..6c0914f623124652f970503f66187392bfcbcdc5 100644 (file)
@@ -154,6 +154,8 @@ static void process_ext_pulse(RCL_Instance instance, struct timespec *phc_ts)
   }
   phc->last_extts = *phc_ts;
 
+  RCL_UpdateReachability(instance);
+
   if (!HCL_CookTime(phc->clock, phc_ts, &local_ts, &local_err))
     return;
 
@@ -204,6 +206,9 @@ static int phc_poll(RCL_Instance instance)
   if (n_readings < 1)
     return 0;
 
+  if (!phc->extpps)
+    RCL_UpdateReachability(instance);
+
   if (!HCL_ProcessReadings(phc->clock, n_readings, readings, &phc_ts, &sys_ts, &phc_err))
     return 0;
 
index 880c13fcbb5486f131faaa0eeece737387efbcd9..f00b7ccb113a38da1488475fb538f58edf21b545 100644 (file)
@@ -143,6 +143,8 @@ static int pps_poll(RCL_Instance instance)
 
   pps->last_seq = seq;
 
+  RCL_UpdateReachability(instance);
+
   return RCL_AddPulse(instance, &ts, 1.0e-9 * ts.tv_nsec);
 }
 
index ee13e871c9141ee5450c23f8d75f0726d845d3ae..22e51820f72a2d86abb65969e965aed8e6c13cef 100644 (file)
@@ -109,6 +109,8 @@ static int shm_poll(RCL_Instance instance)
 
   shm->valid = 0;
 
+  RCL_UpdateReachability(instance);
+
   receive_ts.tv_sec = t.receiveTimeStampSec;
   clock_ts.tv_sec = t.clockTimeStampSec;
 
index 2da57ef5b43bcc5b21b8008a2ac959423410d9b7..49cf3559559ce5acd2a8d57ab624b07d0327df0d 100644 (file)
@@ -129,6 +129,8 @@ static void read_sample(int sockfd, int event, void *anything)
   UTI_TimevalToTimespec(&sample.tv, &sys_ts);
   UTI_NormaliseTimespec(&sys_ts);
 
+  RCL_UpdateReachability(instance);
+
   if (!UTI_IsTimeOffsetSane(&sys_ts, sample.offset))
     return;
 
index dedab9b8f99a3a13faee5b164ef4c29ac5ce569e..3793bd86ce60b6c5fa021d793eb730f308afa411 100755 (executable)
@@ -114,6 +114,32 @@ Root delay      : 0\.000000001 seconds
        rm -f tmp/refclocks.log
 fi
 
+export CLKNETSIM_PHC_JITTER_OFF=$[2 * 25 * 492]
+export CLKNETSIM_PHC_JITTER_ON=$[2 * 25 * 8]
+export CLKNETSIM_PHC_JITTER=1e-6
+refclock_offset=0.0
+refclock_jitter=1e-9
+min_sync_time=5
+max_sync_time=7
+time_max_limit=1e-7
+time_rms_limit=1e-8
+client_conf="refclock PHC /dev/ptp0:nocrossts poll 0
+logdir tmp
+log refclocks"
+chronyc_start=500
+chronyc_conf="sources"
+
+run_test || test_fail
+check_chronyd_exit || test_fail
+check_source_selection || test_fail
+check_sync || test_fail
+check_chronyc_output "^MS.*
+=*
+#\* PHC0                          0   0   377     8 .*$" || test_fail
+
+unset CLKNETSIM_PHC_JITTER_OFF
+unset CLKNETSIM_PHC_JITTER_ON
+export CLKNETSIM_PHC_JITTER=1e-7
 refclock_offset="(+ 0.399 (sum 1e-3))"
 refclock_jitter=1e-6
 servers=1