sysoff: Extend API for different sysoff methods.

The kernel supports different PTP_SYS_OFFSET* ioctls. Use the sysoff
enum to allow selecting between them in sysoff_measure().

Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
master
Miroslav Lichvar 2018-11-12 17:27:59 +01:00 committed by Richard Cochran
parent c0e49c7088
commit 93baf34adb
4 changed files with 39 additions and 18 deletions

View File

@ -74,7 +74,7 @@ struct clock {
LIST_ENTRY(clock) dst_list; LIST_ENTRY(clock) dst_list;
clockid_t clkid; clockid_t clkid;
int phc_index; int phc_index;
int sysoff_supported; int sysoff_method;
int is_utc; int is_utc;
int dest_only; int dest_only;
int state; int state;
@ -255,9 +255,8 @@ static struct clock *clock_add(struct node *node, char *device)
c->servo = servo_add(node, c); c->servo = servo_add(node, c);
if (clkid != CLOCK_INVALID && clkid != CLOCK_REALTIME) if (clkid != CLOCK_INVALID && clkid != CLOCK_REALTIME)
c->sysoff_supported = (SYSOFF_SUPPORTED == c->sysoff_method = sysoff_probe(CLOCKID_TO_FD(clkid),
sysoff_probe(CLOCKID_TO_FD(clkid), node->phc_readings);
node->phc_readings));
LIST_INSERT_HEAD(&node->clocks, c, list); LIST_INSERT_HEAD(&node->clocks, c, list);
return c; return c;
@ -784,11 +783,12 @@ static int do_loop(struct node *node, int subscriptions)
continue; continue;
if (clock->clkid == CLOCK_REALTIME && if (clock->clkid == CLOCK_REALTIME &&
node->master->sysoff_supported) { node->master->sysoff_method >= 0) {
/* use sysoff */ /* use sysoff */
if (sysoff_measure(CLOCKID_TO_FD(node->master->clkid), if (sysoff_measure(CLOCKID_TO_FD(node->master->clkid),
node->master->sysoff_method,
node->phc_readings, node->phc_readings,
&offset, &ts, &delay)) &offset, &ts, &delay) < 0)
return -1; return -1;
} else { } else {
/* use phc */ /* use phc */

View File

@ -367,10 +367,12 @@ static int do_cmp(clockid_t clkid, int cmdc, char *cmdv[])
struct timespec ts, rta, rtb; struct timespec ts, rta, rtb;
int64_t sys_offset, delay = 0, offset; int64_t sys_offset, delay = 0, offset;
uint64_t sys_ts; uint64_t sys_ts;
int method;
if (SYSOFF_SUPPORTED == method = sysoff_probe(CLOCKID_TO_FD(clkid), 9);
sysoff_measure(CLOCKID_TO_FD(clkid),
9, &sys_offset, &sys_ts, &delay)) { if (method >= 0 && sysoff_measure(CLOCKID_TO_FD(clkid), method, 9,
&sys_offset, &sys_ts, &delay) >= 0) {
pr_notice( "offset from CLOCK_REALTIME is %"PRId64"ns\n", pr_notice( "offset from CLOCK_REALTIME is %"PRId64"ns\n",
sys_offset); sys_offset);
return 0; return 0;

View File

@ -73,7 +73,7 @@ static int64_t sysoff_estimate(struct ptp_clock_time *pct, int n_samples,
return samples[0].offset; return samples[0].offset;
} }
int sysoff_measure(int fd, int n_samples, static int sysoff_basic(int fd, int n_samples,
int64_t *result, uint64_t *ts, int64_t *delay) int64_t *result, uint64_t *ts, int64_t *delay)
{ {
struct ptp_sys_offset pso; struct ptp_sys_offset pso;
@ -84,13 +84,24 @@ int sysoff_measure(int fd, int n_samples,
return SYSOFF_RUN_TIME_MISSING; return SYSOFF_RUN_TIME_MISSING;
} }
*result = sysoff_estimate(pso.ts, n_samples, ts, delay); *result = sysoff_estimate(pso.ts, n_samples, ts, delay);
return SYSOFF_SUPPORTED; return SYSOFF_BASIC;
}
int sysoff_measure(int fd, int method, int n_samples,
int64_t *result, uint64_t *ts, int64_t *delay)
{
switch (method) {
case SYSOFF_BASIC:
return sysoff_basic(fd, n_samples, result, ts, delay);
}
return SYSOFF_COMPILE_TIME_MISSING;
} }
int sysoff_probe(int fd, int n_samples) int sysoff_probe(int fd, int n_samples)
{ {
int64_t junk, delay; int64_t junk, delay;
uint64_t ts; uint64_t ts;
int i;
if (n_samples > PTP_MAX_SAMPLES) { if (n_samples > PTP_MAX_SAMPLES) {
fprintf(stderr, "warning: %d exceeds kernel max readings %d\n", fprintf(stderr, "warning: %d exceeds kernel max readings %d\n",
@ -99,7 +110,13 @@ int sysoff_probe(int fd, int n_samples)
return SYSOFF_RUN_TIME_MISSING; return SYSOFF_RUN_TIME_MISSING;
} }
return sysoff_measure(fd, n_samples, &junk, &ts, &delay); for (i = 0; i < SYSOFF_LAST; i++) {
if (sysoff_measure(fd, i, n_samples, &junk, &ts, &delay) < 0)
continue;
return i;
}
return SYSOFF_RUN_TIME_MISSING;
} }
#else /* !PTP_SYS_OFFSET */ #else /* !PTP_SYS_OFFSET */

View File

@ -21,13 +21,14 @@
#include <stdint.h> #include <stdint.h>
enum { enum {
SYSOFF_SUPPORTED, SYSOFF_COMPILE_TIME_MISSING = -2,
SYSOFF_COMPILE_TIME_MISSING, SYSOFF_RUN_TIME_MISSING = -1,
SYSOFF_RUN_TIME_MISSING, SYSOFF_BASIC,
SYSOFF_LAST,
}; };
/** /**
* Check to see if the PTP_SYS_OFFSET ioctl is supported. * Check to see if a PTP_SYS_OFFSET ioctl is supported.
* @param fd An open file descriptor to a PHC device. * @param fd An open file descriptor to a PHC device.
* @return One of the SYSOFF_ enumeration values. * @return One of the SYSOFF_ enumeration values.
*/ */
@ -36,11 +37,12 @@ int sysoff_probe(int fd, int n_samples);
/** /**
* Measure the offset between a PHC and the system time. * Measure the offset between a PHC and the system time.
* @param fd An open file descriptor to a PHC device. * @param fd An open file descriptor to a PHC device.
* @param method A non-negative SYSOFF_ value returned by sysoff_probe().
* @param n_samples The number of consecutive readings to make. * @param n_samples The number of consecutive readings to make.
* @param result The estimated offset in nanoseconds. * @param result The estimated offset in nanoseconds.
* @param ts The system time corresponding to the 'result'. * @param ts The system time corresponding to the 'result'.
* @param delay The delay in reading of the clock in nanoseconds. * @param delay The delay in reading of the clock in nanoseconds.
* @return One of the SYSOFF_ enumeration values. * @return One of the SYSOFF_ enumeration values.
*/ */
int sysoff_measure(int fd, int n_samples, int sysoff_measure(int fd, int method, int n_samples,
int64_t *result, uint64_t *ts, int64_t *delay); int64_t *result, uint64_t *ts, int64_t *delay);