On 10/22/2021 1:58 PM, Keller, Jacob E wrote:
> The phc_ctl program includes an implementation for comparing the PHC
> with CLOCK_REALTIME when PTP_SYS_OFFSET ioctls are not supported.
> 
> This implementation produces inverted results when compared with the
> implementation of the ioctl.
> 
> The PTP_SYS_OFFSET ioctls calculate the difference as "CLOCK_REALTIME -
> PHC_TIME" while this function calculates "PHC_TIME - CLOCK_REALTIME".
> This could produce confusing results if phc_ctl is used on a kernel
> which lacks the PTP_SYS_OFFSET ioctls.
> 
> Fix this by replacing the bespoke implementation in test_phc with the
> clockadj_compare function. That function mimics the interface of
> sysoff_measure and correctly computes the time offset between the two
> clocks in the same manner as the ioctls do. In addition, it supports
> performing multiple samples to reduce inaccuracy.
> 
> With this change, the fallback implementation of measurement will match
> the behavior of the ioctl based PTP_SYS_OFFSET flows.
> 
> Signed-off-by: Jacob Keller <jacob.e.kel...@intel.com>
> ---
>  phc_ctl.c | 54 ++++++++++++++++--------------------------------------
>  1 file changed, 16 insertions(+), 38 deletions(-)
> 
> diff --git a/phc_ctl.c b/phc_ctl.c
> index 673cb37e3583..e975dd803578 100644
> --- a/phc_ctl.c
> +++ b/phc_ctl.c
> @@ -90,26 +90,6 @@ static int install_handler(int signum, void(*handler)(int))
>       return 0;
>  }
>  
> -static int64_t calculate_offset(struct timespec *ts1,
> -                                   struct timespec *rt,
> -                                   struct timespec *ts2)
> -{
> -     int64_t interval;
> -     int64_t offset;
> -
> -#define NSEC_PER_SEC 1000000000ULL
> -     /* calculate interval between clock realtime */
> -     interval = (ts2->tv_sec - ts1->tv_sec) * NSEC_PER_SEC;
> -     interval += ts2->tv_nsec - ts1->tv_nsec;
> -
> -     /* assume PHC read occured half way between CLOCK_REALTIME reads */
> -
> -     offset = (rt->tv_sec - ts1->tv_sec) * NSEC_PER_SEC;
> -     offset += (rt->tv_nsec - ts1->tv_nsec) - (interval / 2);
> -
> -     return offset;
> -}
> -
>  static void usage(const char *progname)
>  {
>       fprintf(stderr,
> @@ -335,34 +315,32 @@ static int do_caps(clockid_t clkid, int cmdc, char 
> *cmdv[])
>  
>  static int do_cmp(clockid_t clkid, int cmdc, char *cmdv[])
>  {
> -     struct timespec ts, rta, rtb;
> -     int64_t sys_offset, delay = 0, offset;
> +     int64_t sys_offset, delay;
>       uint64_t sys_ts;
> -     int method;
> +     int method, fd;
>  
> -     method = sysoff_probe(CLOCKID_TO_FD(clkid), 9);
> +#define N_SAMPLES 9
>  
> -     if (method >= 0 && sysoff_measure(CLOCKID_TO_FD(clkid), method, 9,
> +     fd = CLOCKID_TO_FD(clkid);
> +
> +     method = sysoff_probe(fd, N_SAMPLES);
> +
> +     if (method >= 0 && sysoff_measure(fd, method, N_SAMPLES,
>                                         &sys_offset, &sys_ts, &delay) >= 0) {
> -             pr_notice( "offset from CLOCK_REALTIME is %"PRId64"ns\n",
> -                     sys_offset);
> +             pr_notice("offset from CLOCK_REALTIME is %"PRId64"ns\n",
> +                       sys_offset);
>               return 0;
>       }
>  
> -     memset(&ts, 0, sizeof(ts));
> -     memset(&rta, 0, sizeof(rta));
> -     memset(&rtb, 0, sizeof(rtb));
> -     if (clock_gettime(CLOCK_REALTIME, &rta) ||
> -         clock_gettime(clkid, &ts) ||
> -         clock_gettime(CLOCK_REALTIME, &rtb)) {
> -             pr_err("cmp: failed clock reads: %s\n",
> -                     strerror(errno));
> +     if (clockadj_compare(clkid, CLOCK_REALTIME, N_SAMPLES,
> +                          &sys_offset, &sys_ts, &delay)) {
> +             pr_err("cmp: failed to compare clocks: %s\n",
> +                    strerror(errno));
>               return -1;
>       }

Oops. This part is wrong. clockadj_compare returns positive when it
succeeds... Maybe that should be fixed to match expected functions...

Thanks,
Jake

>  
> -     offset = calculate_offset(&rta, &ts, &rtb);
> -     pr_notice( "offset from CLOCK_REALTIME is approximately %"PRId64"ns\n",
> -             offset);
> +     pr_notice("offset from CLOCK_REALTIME is approximately %"PRId64"ns\n",
> +               sys_offset);
>  
>       return 0;
>  }
> 


_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to