From: Miroslav Lichvar Date: Tue, 27 Nov 2018 12:46:37 +0000 (+0100) Subject: sys_linux: add support for PTP_SYS_OFFSET_EXTENDED ioctl X-Git-Tag: 3.5-pre1~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cc8414b1b3909f4fc484d8eb4cae48f7f1c0309a;p=thirdparty%2Fchrony.git sys_linux: add support for PTP_SYS_OFFSET_EXTENDED ioctl A new ioctl will probably be added in Linux 4.21. It should enable a significantly more accurate measurement of the offset between PHC and system clock. --- diff --git a/sys_linux.c b/sys_linux.c index bd94c779..7688d513 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -544,6 +544,9 @@ SYS_Linux_EnableSystemCallFilter(int level) #ifdef PTP_PIN_SETFUNC PTP_PIN_SETFUNC, #endif +#ifdef PTP_SYS_OFFSET_EXTENDED + PTP_SYS_OFFSET_EXTENDED, +#endif #ifdef PTP_SYS_OFFSET_PRECISE PTP_SYS_OFFSET_PRECISE, #endif @@ -778,6 +781,42 @@ get_phc_sample(int phc_fd, double precision, struct timespec *phc_ts, /* ================================================== */ +static int +get_extended_phc_sample(int phc_fd, double precision, struct timespec *phc_ts, + struct timespec *sys_ts, double *err) +{ +#ifdef PTP_SYS_OFFSET_EXTENDED + struct timespec ts[PHC_READINGS][3]; + struct ptp_sys_offset_extended sys_off; + int i; + + /* Silence valgrind */ + memset(&sys_off, 0, sizeof (sys_off)); + + sys_off.n_samples = PHC_READINGS; + + if (ioctl(phc_fd, PTP_SYS_OFFSET_EXTENDED, &sys_off)) { + DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET_EXTENDED", strerror(errno)); + return 0; + } + + for (i = 0; i < PHC_READINGS; i++) { + ts[i][0].tv_sec = sys_off.ts[i][0].sec; + ts[i][0].tv_nsec = sys_off.ts[i][0].nsec; + ts[i][1].tv_sec = sys_off.ts[i][1].sec; + ts[i][1].tv_nsec = sys_off.ts[i][1].nsec; + ts[i][2].tv_sec = sys_off.ts[i][2].sec; + ts[i][2].tv_nsec = sys_off.ts[i][2].nsec; + } + + return process_phc_readings(ts, PHC_READINGS, precision, phc_ts, sys_ts, err); +#else + return 0; +#endif +} + +/* ================================================== */ + static int get_precise_phc_sample(int phc_fd, double precision, struct timespec *phc_ts, struct timespec *sys_ts, double *err) @@ -849,6 +888,10 @@ SYS_Linux_GetPHCSample(int fd, int nocrossts, double precision, int *reading_mod get_precise_phc_sample(fd, precision, phc_ts, sys_ts, err)) { *reading_mode = 2; return 1; + } else if ((*reading_mode == 3 || !*reading_mode) && + get_extended_phc_sample(fd, precision, phc_ts, sys_ts, err)) { + *reading_mode = 3; + return 1; } else if ((*reading_mode == 1 || !*reading_mode) && get_phc_sample(fd, precision, phc_ts, sys_ts, err)) { *reading_mode = 1;