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