[PATCH net-next 3/5] ptp: add functions to adjust system timestamps

From: James Clark

Date: Fri Oct 09 2026 - 10:39:46 EST


Add ptp_adjust_system_prets() and ptp_adjust_system_postts(), which
shift the pre or post system timestamp by a given duration.

An MDIO bus driver can take system timestamps around the command that
starts a write, and knows how long after that command the write
completes, so it can shift the timestamps to bound the completion of
the write.

Signed-off-by: James Clark <jjc@xxxxxxxxxx>
Assisted-by: LLM
---
The time of the selected clock is moved by the CLOCK_MONOTONIC_RAW
duration without scaling it for that clock's frequency correction,
because timekeeping has no interface for that. While the clock is
synchronized the error is negligible: under 2 ns for a 50 ppm
correction over the 30 us MDIO write time in this series. It is larger
only while the clock is being slewed. An interface along these lines
would allow it to be done properly:

/* Scale a CLOCK_MONOTONIC_RAW duration to the rate of @clock_id */
u64 ktime_scale_raw_ns(clockid_t clock_id, u64 ns);

include/linux/ptp_clock_kernel.h | 48 ++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)

diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
index 36a27a91059..b4ac64228f1 100644
--- a/include/linux/ptp_clock_kernel.h
+++ b/include/linux/ptp_clock_kernel.h
@@ -520,4 +520,52 @@ static inline void ptp_read_system_postts(struct ptp_system_timestamp *sts)
ktime_get_snapshot_id(sts->clockid, &sts->post_sts);
}

+static inline void __ptp_adjust_snapshot(struct system_time_snapshot *snap,
+ s64 ns)
+{
+ if (!snap->valid)
+ return;
+ snap->systime = ktime_add_ns(snap->systime, ns);
+ snap->monoraw = ktime_add_ns(snap->monoraw, ns);
+ /* No counter value corresponds to the adjusted times. */
+ snap->cycles = 0;
+ snap->cs_id = CSID_GENERIC;
+ snap->hw_cycles = 0;
+ snap->hw_csid = CSID_GENERIC;
+}
+
+/**
+ * ptp_adjust_system_prets - Shift the lower system timestamp bound
+ * @sts: system timestamps, or NULL
+ * @ns: CLOCK_MONOTONIC_RAW nanoseconds to add
+ *
+ * Add @ns to the selected clock's time and to the CLOCK_MONOTONIC_RAW
+ * time of the lower bound, and clear its clocksource counter values.
+ * @ns is not scaled for the selected clock's frequency correction, so
+ * the bound is off by @ns times that correction.
+ */
+static inline void ptp_adjust_system_prets(struct ptp_system_timestamp *sts,
+ s64 ns)
+{
+ if (sts)
+ __ptp_adjust_snapshot(&sts->pre_sts, ns);
+}
+
+/**
+ * ptp_adjust_system_postts - Shift the upper system timestamp bound
+ * @sts: system timestamps, or NULL
+ * @ns: CLOCK_MONOTONIC_RAW nanoseconds to add
+ *
+ * Add @ns to the selected clock's time and to the CLOCK_MONOTONIC_RAW
+ * time of the upper bound, and clear its clocksource counter values.
+ * @ns is not scaled for the selected clock's frequency correction, so
+ * the bound is off by @ns times that correction.
+ */
+static inline void ptp_adjust_system_postts(struct ptp_system_timestamp *sts,
+ s64 ns)
+{
+ if (sts)
+ __ptp_adjust_snapshot(&sts->post_sts, ns);
+}
+
#endif
--
2.56.0