Skip to content

Commit c259aca

Browse files
Mahesh Bandewardavem330
Mahesh Bandewar
authored andcommitted
ptp/ioctl: support MONOTONIC{,_RAW} timestamps for PTP_SYS_OFFSET_EXTENDED
The ability to read the PHC (Physical Hardware Clock) alongside multiple system clocks is currently dependent on the specific hardware architecture. This limitation restricts the use of PTP_SYS_OFFSET_PRECISE to certain hardware configurations. The generic soultion which would work across all architectures is to read the PHC along with the latency to perform PHC-read as offered by PTP_SYS_OFFSET_EXTENDED which provides pre and post timestamps. However, these timestamps are currently limited to the CLOCK_REALTIME timebase. Since CLOCK_REALTIME is affected by NTP (or similar time synchronization services), it can experience significant jumps forward or backward. This hinders the precise latency measurements that PTP_SYS_OFFSET_EXTENDED is designed to provide. This problem could be addressed by supporting MONOTONIC_RAW timestamps within PTP_SYS_OFFSET_EXTENDED. Unlike CLOCK_REALTIME or CLOCK_MONOTONIC, the MONOTONIC_RAW timebase is unaffected by NTP adjustments. This enhancement can be implemented by utilizing one of the three reserved words within the PTP_SYS_OFFSET_EXTENDED struct to pass the clock-id for timestamps. The current behavior aligns with clock-id for CLOCK_REALTIME timebase (value of 0), ensuring backward compatibility of the UAPI. Signed-off-by: Mahesh Bandewar <[email protected]> Signed-off-by: Vadim Fedorenko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d5c4546 commit c259aca

File tree

3 files changed

+56
-12
lines changed

3 files changed

+56
-12
lines changed

drivers/ptp/ptp_chardev.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,15 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
359359
extoff = NULL;
360360
break;
361361
}
362-
if (extoff->n_samples > PTP_MAX_SAMPLES
363-
|| extoff->rsv[0] || extoff->rsv[1] || extoff->rsv[2]) {
362+
if (extoff->n_samples > PTP_MAX_SAMPLES ||
363+
extoff->rsv[0] || extoff->rsv[1] ||
364+
(extoff->clockid != CLOCK_REALTIME &&
365+
extoff->clockid != CLOCK_MONOTONIC &&
366+
extoff->clockid != CLOCK_MONOTONIC_RAW)) {
364367
err = -EINVAL;
365368
break;
366369
}
370+
sts.clockid = extoff->clockid;
367371
for (i = 0; i < extoff->n_samples; i++) {
368372
err = ptp->info->gettimex64(ptp->info, &ts, &sts);
369373
if (err)

include/linux/ptp_clock_kernel.h

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,12 @@ struct system_device_crosststamp;
4747
* struct ptp_system_timestamp - system time corresponding to a PHC timestamp
4848
* @pre_ts: system timestamp before capturing PHC
4949
* @post_ts: system timestamp after capturing PHC
50+
* @clockid: clock-base used for capturing the system timestamps
5051
*/
5152
struct ptp_system_timestamp {
5253
struct timespec64 pre_ts;
5354
struct timespec64 post_ts;
55+
clockid_t clockid;
5456
};
5557

5658
/**
@@ -457,14 +459,40 @@ static inline ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp,
457459

458460
static inline void ptp_read_system_prets(struct ptp_system_timestamp *sts)
459461
{
460-
if (sts)
461-
ktime_get_real_ts64(&sts->pre_ts);
462+
if (sts) {
463+
switch (sts->clockid) {
464+
case CLOCK_REALTIME:
465+
ktime_get_real_ts64(&sts->pre_ts);
466+
break;
467+
case CLOCK_MONOTONIC:
468+
ktime_get_ts64(&sts->pre_ts);
469+
break;
470+
case CLOCK_MONOTONIC_RAW:
471+
ktime_get_raw_ts64(&sts->pre_ts);
472+
break;
473+
default:
474+
break;
475+
}
476+
}
462477
}
463478

464479
static inline void ptp_read_system_postts(struct ptp_system_timestamp *sts)
465480
{
466-
if (sts)
467-
ktime_get_real_ts64(&sts->post_ts);
481+
if (sts) {
482+
switch (sts->clockid) {
483+
case CLOCK_REALTIME:
484+
ktime_get_real_ts64(&sts->post_ts);
485+
break;
486+
case CLOCK_MONOTONIC:
487+
ktime_get_ts64(&sts->post_ts);
488+
break;
489+
case CLOCK_MONOTONIC_RAW:
490+
ktime_get_raw_ts64(&sts->post_ts);
491+
break;
492+
default:
493+
break;
494+
}
495+
}
468496
}
469497

470498
#endif

include/uapi/linux/ptp_clock.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,25 @@ struct ptp_sys_offset {
155155
struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1];
156156
};
157157

158+
/*
159+
* ptp_sys_offset_extended - data structure for IOCTL operation
160+
* PTP_SYS_OFFSET_EXTENDED
161+
*
162+
* @n_samples: Desired number of measurements.
163+
* @clockid: clockid of a clock-base used for pre/post timestamps.
164+
* @rsv: Reserved for future use.
165+
* @ts: Array of samples in the form [pre-TS, PHC, post-TS]. The
166+
* kernel provides @n_samples.
167+
*
168+
* Starting from kernel 6.12 and onwards, the first word of the reserved-field
169+
* is used for @clockid. That's backward compatible since previous kernel
170+
* expect all three reserved words (@rsv[3]) to be 0 while the clockid (first
171+
* word in the new structure) for CLOCK_REALTIME is '0'.
172+
*/
158173
struct ptp_sys_offset_extended {
159-
unsigned int n_samples; /* Desired number of measurements. */
160-
unsigned int rsv[3]; /* Reserved for future use. */
161-
/*
162-
* Array of [system, phc, system] time stamps. The kernel will provide
163-
* 3*n_samples time stamps.
164-
*/
174+
unsigned int n_samples;
175+
__kernel_clockid_t clockid;
176+
unsigned int rsv[2];
165177
struct ptp_clock_time ts[PTP_MAX_SAMPLES][3];
166178
};
167179

0 commit comments

Comments
 (0)