4b595f
commit c0e49c708814ec783726fe92202371847703c5ed
4b595f
Author: Miroslav Lichvar <mlichvar@redhat.com>
4b595f
Date:   Mon Nov 12 17:27:58 2018 +0100
4b595f
4b595f
    sysoff: Initialize data for ioctl(PTP_SYS_OFFSET).
4b595f
    
4b595f
    This fixes valgrind errors.
4b595f
    
4b595f
    Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
4b595f
4b595f
diff --git a/sysoff.c b/sysoff.c
4b595f
index f7b6240..407a01c 100644
4b595f
--- a/sysoff.c
4b595f
+++ b/sysoff.c
4b595f
@@ -18,6 +18,7 @@
4b595f
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
4b595f
  */
4b595f
 #include <stdio.h>
4b595f
+#include <string.h>
4b595f
 #include <sys/ioctl.h>
4b595f
 #include <linux/ptp_clock.h>
4b595f
 
4b595f
@@ -76,6 +77,7 @@ int sysoff_measure(int fd, int n_samples,
4b595f
 		   int64_t *result, uint64_t *ts, int64_t *delay)
4b595f
 {
4b595f
 	struct ptp_sys_offset pso;
4b595f
+	memset(&pso, 0, sizeof(pso));
4b595f
 	pso.n_samples = n_samples;
4b595f
 	if (ioctl(fd, PTP_SYS_OFFSET, &pso)) {
4b595f
 		perror("ioctl PTP_SYS_OFFSET");
4b595f
4b595f
commit 93baf34adb81046a5e1c3b9a3e685029f2046993
4b595f
Author: Miroslav Lichvar <mlichvar@redhat.com>
4b595f
Date:   Mon Nov 12 17:27:59 2018 +0100
4b595f
4b595f
    sysoff: Extend API for different sysoff methods.
4b595f
    
4b595f
    The kernel supports different PTP_SYS_OFFSET* ioctls. Use the sysoff
4b595f
    enum to allow selecting between them in sysoff_measure().
4b595f
    
4b595f
    Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
4b595f
4b595f
diff --git a/phc2sys.c b/phc2sys.c
4b595f
index 15f8d75..2cd477a 100644
4b595f
--- a/phc2sys.c
4b595f
+++ b/phc2sys.c
4b595f
@@ -74,7 +74,7 @@ struct clock {
4b595f
 	LIST_ENTRY(clock) dst_list;
4b595f
 	clockid_t clkid;
4b595f
 	int phc_index;
4b595f
-	int sysoff_supported;
4b595f
+	int sysoff_method;
4b595f
 	int is_utc;
4b595f
 	int dest_only;
4b595f
 	int state;
4b595f
@@ -255,9 +255,8 @@ static struct clock *clock_add(struct node *node, char *device)
4b595f
 		c->servo = servo_add(node, c);
4b595f
 
4b595f
 	if (clkid != CLOCK_INVALID && clkid != CLOCK_REALTIME)
4b595f
-		c->sysoff_supported = (SYSOFF_SUPPORTED ==
4b595f
-				       sysoff_probe(CLOCKID_TO_FD(clkid),
4b595f
-						    node->phc_readings));
4b595f
+		c->sysoff_method = sysoff_probe(CLOCKID_TO_FD(clkid),
4b595f
+						node->phc_readings);
4b595f
 
4b595f
 	LIST_INSERT_HEAD(&node->clocks, c, list);
4b595f
 	return c;
4b595f
@@ -784,11 +783,12 @@ static int do_loop(struct node *node, int subscriptions)
4b595f
 				continue;
4b595f
 
4b595f
 			if (clock->clkid == CLOCK_REALTIME &&
4b595f
-			    node->master->sysoff_supported) {
4b595f
+			    node->master->sysoff_method >= 0) {
4b595f
 				/* use sysoff */
4b595f
 				if (sysoff_measure(CLOCKID_TO_FD(node->master->clkid),
4b595f
+						   node->master->sysoff_method,
4b595f
 						   node->phc_readings,
4b595f
-						   &offset, &ts, &delay))
4b595f
+						   &offset, &ts, &delay) < 0)
4b595f
 					return -1;
4b595f
 			} else {
4b595f
 				/* use phc */
4b595f
diff --git a/phc_ctl.c b/phc_ctl.c
4b595f
index 4a78a19..b9a9cf4 100644
4b595f
--- a/phc_ctl.c
4b595f
+++ b/phc_ctl.c
4b595f
@@ -367,10 +367,12 @@ static int do_cmp(clockid_t clkid, int cmdc, char *cmdv[])
4b595f
 	struct timespec ts, rta, rtb;
4b595f
 	int64_t sys_offset, delay = 0, offset;
4b595f
 	uint64_t sys_ts;
4b595f
+	int method;
4b595f
 
4b595f
-	if (SYSOFF_SUPPORTED ==
4b595f
-	    sysoff_measure(CLOCKID_TO_FD(clkid),
4b595f
-			   9, &sys_offset, &sys_ts, &delay)) {
4b595f
+	method = sysoff_probe(CLOCKID_TO_FD(clkid), 9);
4b595f
+
4b595f
+	if (method >= 0 && sysoff_measure(CLOCKID_TO_FD(clkid), method, 9,
4b595f
+					  &sys_offset, &sys_ts, &delay) >= 0) {
4b595f
 		pr_notice( "offset from CLOCK_REALTIME is %"PRId64"ns\n",
4b595f
 			sys_offset);
4b595f
 		return 0;
4b595f
diff --git a/sysoff.c b/sysoff.c
4b595f
index 407a01c..f709a9b 100644
4b595f
--- a/sysoff.c
4b595f
+++ b/sysoff.c
4b595f
@@ -73,8 +73,8 @@ static int64_t sysoff_estimate(struct ptp_clock_time *pct, int n_samples,
4b595f
 	return samples[0].offset;
4b595f
 }
4b595f
 
4b595f
-int sysoff_measure(int fd, int n_samples,
4b595f
-		   int64_t *result, uint64_t *ts, int64_t *delay)
4b595f
+static int sysoff_basic(int fd, int n_samples,
4b595f
+			int64_t *result, uint64_t *ts, int64_t *delay)
4b595f
 {
4b595f
 	struct ptp_sys_offset pso;
4b595f
 	memset(&pso, 0, sizeof(pso));
4b595f
@@ -84,13 +84,24 @@ int sysoff_measure(int fd, int n_samples,
4b595f
 		return SYSOFF_RUN_TIME_MISSING;
4b595f
 	}
4b595f
 	*result = sysoff_estimate(pso.ts, n_samples, ts, delay);
4b595f
-	return SYSOFF_SUPPORTED;
4b595f
+	return SYSOFF_BASIC;
4b595f
+}
4b595f
+
4b595f
+int sysoff_measure(int fd, int method, int n_samples,
4b595f
+		   int64_t *result, uint64_t *ts, int64_t *delay)
4b595f
+{
4b595f
+	switch (method) {
4b595f
+	case SYSOFF_BASIC:
4b595f
+		return sysoff_basic(fd, n_samples, result, ts, delay);
4b595f
+	}
4b595f
+	return SYSOFF_COMPILE_TIME_MISSING;
4b595f
 }
4b595f
 
4b595f
 int sysoff_probe(int fd, int n_samples)
4b595f
 {
4b595f
 	int64_t junk, delay;
4b595f
 	uint64_t ts;
4b595f
+	int i;
4b595f
 
4b595f
 	if (n_samples > PTP_MAX_SAMPLES) {
4b595f
 		fprintf(stderr, "warning: %d exceeds kernel max readings %d\n",
4b595f
@@ -99,7 +110,13 @@ int sysoff_probe(int fd, int n_samples)
4b595f
 		return SYSOFF_RUN_TIME_MISSING;
4b595f
 	}
4b595f
 
4b595f
-	return sysoff_measure(fd, n_samples, &junk, &ts, &delay);
4b595f
+	for (i = 0; i < SYSOFF_LAST; i++) {
4b595f
+		if (sysoff_measure(fd, i, n_samples, &junk, &ts, &delay) < 0)
4b595f
+			continue;
4b595f
+		return i;
4b595f
+	}
4b595f
+
4b595f
+	return SYSOFF_RUN_TIME_MISSING;
4b595f
 }
4b595f
 
4b595f
 #else /* !PTP_SYS_OFFSET */
4b595f
diff --git a/sysoff.h b/sysoff.h
4b595f
index cb70265..02ecdfa 100644
4b595f
--- a/sysoff.h
4b595f
+++ b/sysoff.h
4b595f
@@ -21,13 +21,14 @@
4b595f
 #include <stdint.h>
4b595f
 
4b595f
 enum {
4b595f
-	SYSOFF_SUPPORTED,
4b595f
-	SYSOFF_COMPILE_TIME_MISSING,
4b595f
-	SYSOFF_RUN_TIME_MISSING,
4b595f
+	SYSOFF_COMPILE_TIME_MISSING = -2,
4b595f
+	SYSOFF_RUN_TIME_MISSING = -1,
4b595f
+	SYSOFF_BASIC,
4b595f
+	SYSOFF_LAST,
4b595f
 };
4b595f
 
4b595f
 /**
4b595f
- * Check to see if the PTP_SYS_OFFSET ioctl is supported.
4b595f
+ * Check to see if a PTP_SYS_OFFSET ioctl is supported.
4b595f
  * @param fd  An open file descriptor to a PHC device.
4b595f
  * @return  One of the SYSOFF_ enumeration values.
4b595f
  */
4b595f
@@ -36,11 +37,12 @@ int sysoff_probe(int fd, int n_samples);
4b595f
 /**
4b595f
  * Measure the offset between a PHC and the system time.
4b595f
  * @param fd         An open file descriptor to a PHC device.
4b595f
+ * @param method     A non-negative SYSOFF_ value returned by sysoff_probe().
4b595f
  * @param n_samples  The number of consecutive readings to make.
4b595f
  * @param result     The estimated offset in nanoseconds.
4b595f
  * @param ts         The system time corresponding to the 'result'.
4b595f
  * @param delay      The delay in reading of the clock in nanoseconds.
4b595f
  * @return  One of the SYSOFF_ enumeration values.
4b595f
  */
4b595f
-int sysoff_measure(int fd, int n_samples,
4b595f
+int sysoff_measure(int fd, int method, int n_samples,
4b595f
 		   int64_t *result, uint64_t *ts, int64_t *delay);
4b595f
4b595f
commit 192b8e315c4585489d7aa7f59683035998805e40
4b595f
Author: Miroslav Lichvar <mlichvar@redhat.com>
4b595f
Date:   Mon Nov 12 17:28:00 2018 +0100
4b595f
4b595f
    sysoff: Add support for PTP_SYS_OFFSET_PRECISE ioctl.
4b595f
    
4b595f
    This ioctl uses cross timestamping for a more accurate measurement of
4b595f
    the offset. It is supported on some onboard Intel NICs using the e1000e
4b595f
    driver and a virtual PHC with the ptp_kvm driver.
4b595f
    
4b595f
    Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
4b595f
4b595f
diff --git a/sysoff.c b/sysoff.c
4b595f
index f709a9b..9f65d95 100644
4b595f
--- a/sysoff.c
4b595f
+++ b/sysoff.c
4b595f
@@ -22,6 +22,7 @@
4b595f
 #include <sys/ioctl.h>
4b595f
 #include <linux/ptp_clock.h>
4b595f
 
4b595f
+#include "print.h"
4b595f
 #include "sysoff.h"
4b595f
 
4b595f
 #define NS_PER_SEC 1000000000LL
4b595f
@@ -39,6 +40,23 @@ static struct {
4b595f
 	uint64_t timestamp;
4b595f
 } samples[PTP_MAX_SAMPLES];
4b595f
 
4b595f
+static int sysoff_precise(int fd, int64_t *result, uint64_t *ts)
4b595f
+{
4b595f
+#ifdef PTP_SYS_OFFSET_PRECISE
4b595f
+	struct ptp_sys_offset_precise pso;
4b595f
+	memset(&pso, 0, sizeof(pso));
4b595f
+	if (ioctl(fd, PTP_SYS_OFFSET_PRECISE, &pso)) {
4b595f
+		pr_debug("ioctl PTP_SYS_OFFSET_PRECISE: %m");
4b595f
+		return SYSOFF_RUN_TIME_MISSING;
4b595f
+	}
4b595f
+	*result = pctns(&pso.sys_realtime) - pctns(&pso.device);
4b595f
+	*ts = pctns(&pso.sys_realtime);
4b595f
+	return SYSOFF_PRECISE;
4b595f
+#else
4b595f
+	return SYSOFF_COMPILE_TIME_MISSING;
4b595f
+#endif
4b595f
+}
4b595f
+
4b595f
 static void insertion_sort(int length, int64_t interval, int64_t offset, uint64_t ts)
4b595f
 {
4b595f
 	int i = length - 1;
4b595f
@@ -91,6 +109,9 @@ int sysoff_measure(int fd, int method, int n_samples,
4b595f
 		   int64_t *result, uint64_t *ts, int64_t *delay)
4b595f
 {
4b595f
 	switch (method) {
4b595f
+	case SYSOFF_PRECISE:
4b595f
+		*delay = 0;
4b595f
+		return sysoff_precise(fd, result, ts);
4b595f
 	case SYSOFF_BASIC:
4b595f
 		return sysoff_basic(fd, n_samples, result, ts, delay);
4b595f
 	}
4b595f
diff --git a/sysoff.h b/sysoff.h
4b595f
index 02ecdfa..37f7353 100644
4b595f
--- a/sysoff.h
4b595f
+++ b/sysoff.h
4b595f
@@ -23,6 +23,7 @@
4b595f
 enum {
4b595f
 	SYSOFF_COMPILE_TIME_MISSING = -2,
4b595f
 	SYSOFF_RUN_TIME_MISSING = -1,
4b595f
+	SYSOFF_PRECISE,
4b595f
 	SYSOFF_BASIC,
4b595f
 	SYSOFF_LAST,
4b595f
 };
4b595f
4b595f
commit 68a9011c9d7d859920da339ba59c14dc1d617a45
4b595f
Author: Miroslav Lichvar <mlichvar@redhat.com>
4b595f
Date:   Mon Nov 12 17:28:01 2018 +0100
4b595f
4b595f
    sysoff: Add support for PTP_SYS_OFFSET_EXTENDED ioctl.
4b595f
    
4b595f
    This is a more accurate variant of the the PTP_SYS_OFFSET ioctl, which
4b595f
    will probably be supported in future kernel versions.
4b595f
    
4b595f
    Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
4b595f
4b595f
diff --git a/sysoff.c b/sysoff.c
4b595f
index 9f65d95..b993ee9 100644
4b595f
--- a/sysoff.c
4b595f
+++ b/sysoff.c
4b595f
@@ -71,17 +71,23 @@ static void insertion_sort(int length, int64_t interval, int64_t offset, uint64_
4b595f
 	samples[i+1].timestamp = ts;
4b595f
 }
4b595f
 
4b595f
-static int64_t sysoff_estimate(struct ptp_clock_time *pct, int n_samples,
4b595f
-			       uint64_t *ts, int64_t *delay)
4b595f
+static int64_t sysoff_estimate(struct ptp_clock_time *pct, int extended,
4b595f
+			       int n_samples, uint64_t *ts, int64_t *delay)
4b595f
 {
4b595f
 	int64_t t1, t2, tp;
4b595f
 	int64_t interval, offset;
4b595f
 	int i;
4b595f
 
4b595f
 	for (i = 0; i < n_samples; i++) {
4b595f
-		t1 = pctns(&pct[2*i]);
4b595f
-		tp = pctns(&pct[2*i+1]);
4b595f
-		t2 = pctns(&pct[2*i+2]);
4b595f
+		if (extended) {
4b595f
+			t1 = pctns(&pct[3*i]);
4b595f
+			tp = pctns(&pct[3*i+1]);
4b595f
+			t2 = pctns(&pct[3*i+2]);
4b595f
+		} else {
4b595f
+			t1 = pctns(&pct[2*i]);
4b595f
+			tp = pctns(&pct[2*i+1]);
4b595f
+			t2 = pctns(&pct[2*i+2]);
4b595f
+		}
4b595f
 		interval = t2 - t1;
4b595f
 		offset = (t2 + t1) / 2 - tp;
4b595f
 		insertion_sort(i, interval, offset, (t2 + t1) / 2);
4b595f
@@ -91,6 +97,24 @@ static int64_t sysoff_estimate(struct ptp_clock_time *pct, int n_samples,
4b595f
 	return samples[0].offset;
4b595f
 }
4b595f
 
4b595f
+static int sysoff_extended(int fd, int n_samples,
4b595f
+			   int64_t *result, uint64_t *ts, int64_t *delay)
4b595f
+{
4b595f
+#ifdef PTP_SYS_OFFSET_EXTENDED
4b595f
+	struct ptp_sys_offset_extended pso;
4b595f
+	memset(&pso, 0, sizeof(pso));
4b595f
+	pso.n_samples = n_samples;
4b595f
+	if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, &pso)) {
4b595f
+		pr_debug("ioctl PTP_SYS_OFFSET_EXTENDED: %m");
4b595f
+		return SYSOFF_RUN_TIME_MISSING;
4b595f
+	}
4b595f
+	*result = sysoff_estimate(&pso.ts[0][0], 1, n_samples, ts, delay);
4b595f
+	return SYSOFF_EXTENDED;
4b595f
+#else
4b595f
+	return SYSOFF_COMPILE_TIME_MISSING;
4b595f
+#endif
4b595f
+}
4b595f
+
4b595f
 static int sysoff_basic(int fd, int n_samples,
4b595f
 			int64_t *result, uint64_t *ts, int64_t *delay)
4b595f
 {
4b595f
@@ -101,7 +125,7 @@ static int sysoff_basic(int fd, int n_samples,
4b595f
 		perror("ioctl PTP_SYS_OFFSET");
4b595f
 		return SYSOFF_RUN_TIME_MISSING;
4b595f
 	}
4b595f
-	*result = sysoff_estimate(pso.ts, n_samples, ts, delay);
4b595f
+	*result = sysoff_estimate(pso.ts, 0, n_samples, ts, delay);
4b595f
 	return SYSOFF_BASIC;
4b595f
 }
4b595f
 
4b595f
@@ -112,6 +136,8 @@ int sysoff_measure(int fd, int method, int n_samples,
4b595f
 	case SYSOFF_PRECISE:
4b595f
 		*delay = 0;
4b595f
 		return sysoff_precise(fd, result, ts);
4b595f
+	case SYSOFF_EXTENDED:
4b595f
+		return sysoff_extended(fd, n_samples, result, ts, delay);
4b595f
 	case SYSOFF_BASIC:
4b595f
 		return sysoff_basic(fd, n_samples, result, ts, delay);
4b595f
 	}
4b595f
diff --git a/sysoff.h b/sysoff.h
4b595f
index 37f7353..79d2290 100644
4b595f
--- a/sysoff.h
4b595f
+++ b/sysoff.h
4b595f
@@ -24,6 +24,7 @@ enum {
4b595f
 	SYSOFF_COMPILE_TIME_MISSING = -2,
4b595f
 	SYSOFF_RUN_TIME_MISSING = -1,
4b595f
 	SYSOFF_PRECISE,
4b595f
+	SYSOFF_EXTENDED,
4b595f
 	SYSOFF_BASIC,
4b595f
 	SYSOFF_LAST,
4b595f
 };
4b595f
4b595f
commit 8142da41b61fb5b9ee4ad8f5ab56adb0447cd37b
4b595f
Author: Miroslav Lichvar <mlichvar@redhat.com>
4b595f
Date:   Mon Nov 12 17:28:02 2018 +0100
4b595f
4b595f
    phc2sys: Use reversed sysoff when synchronizing to system clock.
4b595f
    
4b595f
    If synchronizing a PHC to the system clock, use one of the
4b595f
    PTP_SYS_OFFSET ioctls (if supported) to measure the offset between the
4b595f
    two clocks. Negate the offset and switch the timestamp before passing
4b595f
    them to the servo.
4b595f
    
4b595f
    This makes the synchronization between PHC and system clock symmetric.
4b595f
    
4b595f
    Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
4b595f
4b595f
diff --git a/phc2sys.c b/phc2sys.c
4b595f
index 2cd477a..b8f1ea0 100644
4b595f
--- a/phc2sys.c
4b595f
+++ b/phc2sys.c
4b595f
@@ -790,6 +790,16 @@ static int do_loop(struct node *node, int subscriptions)
4b595f
 						   node->phc_readings,
4b595f
 						   &offset, &ts, &delay) < 0)
4b595f
 					return -1;
4b595f
+			} else if (node->master->clkid == CLOCK_REALTIME &&
4b595f
+				   clock->sysoff_method >= 0) {
4b595f
+				/* use reversed sysoff */
4b595f
+				if (sysoff_measure(CLOCKID_TO_FD(clock->clkid),
4b595f
+						   clock->sysoff_method,
4b595f
+						   node->phc_readings,
4b595f
+						   &offset, &ts, &delay) < 0)
4b595f
+					return -1;
4b595f
+				ts += offset;
4b595f
+				offset = -offset;
4b595f
 			} else {
4b595f
 				/* use phc */
4b595f
 				if (!read_phc(node->master->clkid, clock->clkid,
7934a2
commit e0580929f451e685d92cd10d80b76f39e9b09a97
7934a2
Author: Richard Cochran <richardcochran@gmail.com>
7934a2
Date:   Tue Dec 24 11:09:34 2019 -0800
7934a2
7934a2
    phc2sys: Fix frequency estimation when synchronizing a PHC to the system clock.
7934a2
    
7934a2
    When synchronizing a PHC to the Linux system clock (CLOCK_REALTIME),
7934a2
    the phc2sys uses the sysoff method, reversing the master and slave
7934a2
    roles.
7934a2
    
7934a2
    The offset between a master clock and a slave clock is given by
7934a2
    
7934a2
        offset = slave_ts - master_ts,
7934a2
    
7934a2
    and the call to sysoff_measure() provides the 'offset' and 'slave_ts'
7934a2
    values.  The needed local time stamp on the 'master' is given by
7934a2
    
7934a2
        master_ts = slave_ts - offset,
7934a2
    
7934a2
    but the code calcuates
7934a2
    
7934a2
        master_ts = slave_ts + offset.
7934a2
    
7934a2
    When passed to the servo, the local time stamp is used to estimate the
7934a2
    frequency offset between the two clocks before starting the main
7934a2
    synchronization loop.  The effect of the bug may be seen with a simple
7934a2
    test.  Here is a sample output with the existing code.
7934a2
    
7934a2
        $ sudo testptp -d /dev/ptp1 -f 62400000
7934a2
        frequency adjustment okay
7934a2
        $ sudo ./phc2sys -m -q -c eth6 -s CLOCK_REALTIME -O0
7934a2
        phc2sys[90221.239]: eth6 sys offset 191001318 s0 freq -62400000 delay   5547
7934a2
        phc2sys[90222.239]: eth6 sys offset 253380897 s1 freq  +8265884 delay   5507
7934a2
        phc2sys[90223.239]: eth6 sys offset  -8301685 s2 freq    -35801 delay   5487
7934a2
        phc2sys[90224.239]: eth6 sys offset  -8297136 s2 freq  -2521757 delay   5531
7934a2
        phc2sys[90225.239]: eth6 sys offset  -5806117 s2 freq  -2519879 delay   5542
7934a2
        phc2sys[90226.239]: eth6 sys offset  -3317009 s2 freq  -1772606 delay   5495
7934a2
        phc2sys[90227.240]: eth6 sys offset  -1575231 s2 freq  -1025931 delay   5505
7934a2
        phc2sys[90228.240]: eth6 sys offset   -580249 s2 freq   -503518 delay   5524
7934a2
        phc2sys[90229.240]: eth6 sys offset   -107770 s2 freq   -205114 delay   5519
7934a2
        phc2sys[90230.240]: eth6 sys offset     66298 s2 freq    -63377 delay   5490
7934a2
        phc2sys[90230.881]: eth6 sys offset     86942 s2 freq    -22844 delay   5495
7934a2
    
7934a2
    And this is the output with the bug fix in place.
7934a2
    
7934a2
        $ sudo testptp -d /dev/ptp1 -f 62400000
7934a2
        frequency adjustment okay
7934a2
        $ sudo ./phc2sys -m -q -c eth6 -s CLOCK_REALTIME -O0
7934a2
        phc2sys[90365.624]: eth6 sys offset 311912675 s0 freq -62400000 delay   5490
7934a2
        phc2sys[90366.624]: eth6 sys offset 374292766 s1 freq  -31098 delay   5642
7934a2
        phc2sys[90367.624]: eth6 sys offset     -3825 s2 freq  -34923 delay   5617
7934a2
        phc2sys[90368.625]: eth6 sys offset         6 s2 freq  -32240 delay   5564
7934a2
        phc2sys[90369.625]: eth6 sys offset      1241 s2 freq  -31003 delay   5605
7934a2
        phc2sys[90370.625]: eth6 sys offset      1131 s2 freq  -30741 delay   5600
7934a2
        phc2sys[90371.625]: eth6 sys offset       801 s2 freq  -30732 delay   5621
7934a2
        phc2sys[90372.625]: eth6 sys offset       458 s2 freq  -30834 delay   5640
7934a2
        phc2sys[90373.626]: eth6 sys offset       186 s2 freq  -30969 delay   5598
7934a2
        phc2sys[90374.626]: eth6 sys offset       134 s2 freq  -30965 delay   5599
7934a2
        phc2sys[90375.626]: eth6 sys offset        43 s2 freq  -31016 delay   5595
7934a2
        phc2sys[90375.681]: eth6 sys offset       -32 s2 freq  -31078 delay   5541
7934a2
    
7934a2
    This patch fixes the issue by correcting the calculation of the local
7934a2
    time stamp value.
7934a2
    
7934a2
    Fixes: 8142da41b61f ("phc2sys: Use reversed sysoff when synchronizing to system clock.")
7934a2
    Signed-off-by: Richard Cochran <richardcochran@gmail.com>
7934a2
    Reported-by: Cliff Spradlin <cspradlin@google.com>
7934a2
    Tested-by: Vladimir Oltean <olteanv@gmail.com>
7934a2
7934a2
diff --git a/phc2sys.c b/phc2sys.c
7934a2
index 28c657a..c0b7b3d 100644
7934a2
--- a/phc2sys.c
7934a2
+++ b/phc2sys.c
7934a2
@@ -770,8 +770,8 @@ static int do_loop(struct node *node, int subscriptions)
7934a2
 						   node->phc_readings,
7934a2
 						   &offset, &ts, &delay) < 0)
7934a2
 					return -1;
7934a2
-				ts += offset;
7934a2
 				offset = -offset;
7934a2
+				ts += offset;
7934a2
 			} else {
7934a2
 				/* use phc */
7934a2
 				if (!read_phc(node->master->clkid, clock->clkid,