linuxptp/SOURCES/linuxptp-ppsmiss.patch

80 lines
2.6 KiB
Diff

commit b4c146daa086436807abcd75157bd9d0a44971cb
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Aug 28 15:14:01 2025 +0200
ts2phc: Better handle missing pulses with multiple sinks.
The ts2phc_pps_sink_poll() function waits until it has collected pulses
for all active sinks, or a timeout of 2 seconds between events is
reached.
If a sink missed a pulse (e.g. after a port state change and switching
PPS signal direction in the external PPS mode) and the next pulse of
that sink came before pulses of the other sinks, it was mixed with
events of the previous pulse and the measured offset had an error of
1/rate seconds.
To avoid mixing events corresponding to different pulses, adjust the
poll() timeout so that it waits only up to a third of the pulse period
after the first received event.
(Rebased to 4.4)
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/ts2phc_pps_sink.c b/ts2phc_pps_sink.c
index 9076de9..72d8ea4 100644
--- a/ts2phc_pps_sink.c
+++ b/ts2phc_pps_sink.c
@@ -381,10 +381,11 @@ void ts2phc_pps_sink_cleanup(struct ts2phc_private *priv)
int ts2phc_pps_sink_poll(struct ts2phc_private *priv)
{
struct ts2phc_sink_array *polling_array = priv->polling_array;
+ bool first_poll = true, ignore_any = false;
bool all_sinks_have_events = false;
- bool ignore_any = false;
+ struct timespec first_ts = {0}, ts;
+ int cnt, timeout;
unsigned int i;
- int cnt;
for (i = 0; i < priv->n_sinks; i++)
polling_array->collected_events[i] = 0;
@@ -395,7 +396,22 @@ int ts2phc_pps_sink_poll(struct ts2phc_private *priv)
if (!is_running())
return 0;
- cnt = poll(polling_array->pfd, priv->n_sinks, 2000);
+ /*
+ * Collect only events within a third of the pulse period to
+ * avoid mixing events corresponding to different pulses.
+ */
+ if (first_poll) {
+ timeout = 2000;
+ } else {
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ timeout = 333;
+ timeout -= (ts.tv_sec - first_ts.tv_sec) * 1000 +
+ (ts.tv_nsec - first_ts.tv_nsec) / 1000000;
+ if (timeout < 0)
+ timeout = 0;
+ }
+
+ cnt = poll(polling_array->pfd, priv->n_sinks, timeout);
if (cnt < 0) {
if (errno == EINTR) {
return 0;
@@ -408,6 +424,11 @@ int ts2phc_pps_sink_poll(struct ts2phc_private *priv)
return 0;
}
+ if (first_poll) {
+ clock_gettime(CLOCK_MONOTONIC, &first_ts);
+ first_poll = false;
+ }
+
for (i = 0; i < priv->n_sinks; i++) {
if (polling_array->pfd[i].revents & POLLERR) {
sink = polling_array->sink[i];