Re: [chrony-users] Leveraging PTM

[ Thread Index | Date Index | More chrony.tuxfamily.org/chrony-users Archives ]


On Mon, Sep 04, 2023 at 10:29:28AM +0200, Miroslav Lichvar wrote:
> On Mon, Sep 04, 2023 at 01:34:48PM +0700, James Clark wrote:
> > The  IES3110-8TF-R web UI has some configuration options that suggest it
> > supports unicast. See attached screenshot. I haven't experimented with it.
> > It also has option to select one-step vs two-step, but I haven't
> > experimented with that either.
> 
> That sounds promising. I'll order one and test it. It would be amazing
> if this switch could do what 100x more expensive switches cannot.

Ok, I got the switch and I can confirm it modifies the correction
field in NTP-over-PTP messages as a one-step transparent clock.

I did a quick test with two I210 NICs in a single machine connected to
the switch. I tried few different pairs of ports. With the worst one
and unmodified chronyd I see an asymmetry of about 25 ns and jitter of
about 140 ns. When I apply the PTP correction the asymmetry disappears
and jitter drops to 10 ns.

Here is a plot of the raw offset from the measurements log:
https://i.imgur.com/S6iywgH.png

I'm attaching the patch if you want to test it. It's a quick hack.
I think there will need to be a new extension field to provide the
correction of the request to the client to allow it to perform some
sanity checks and also some way to correct for asymmetric link speeds.

If anyone knows about other switches which can do this, please let me
know. I'll mention them in the NTP-over-PTP draft. I think this will
be a very nice improvement.

-- 
Miroslav Lichvar
commit 583ff7655615a3394871c61aae4351b633ec5906
Author: Miroslav Lichvar <mlichvar@xxxxxxxxxx>
Date:   Wed Sep 6 16:31:56 2023 +0200

    POC: ntp: apply PTP correction from delay requests

diff --git a/ntp_io.c b/ntp_io.c
index fce7b177..1cc7532d 100644
--- a/ntp_io.c
+++ b/ntp_io.c
@@ -428,6 +428,7 @@ process_message(SCK_Message *message, int sock_fd, int event)
   NTP_Local_Address local_addr;
   NTP_Local_Timestamp local_ts;
   struct timespec sched_ts;
+  double correction;
 
   SCH_GetLastEventTime(&local_ts.ts, &local_ts.err, NULL);
   local_ts.source = NTP_TS_DAEMON;
@@ -456,9 +457,14 @@ process_message(SCK_Message *message, int sock_fd, int event)
     DEBUG_LOG("Updated RX timestamp delay=%.9f tss=%u",
               UTI_DiffTimespecsToDouble(&sched_ts, &local_ts.ts), local_ts.source);
 
-  if (!NIO_UnwrapMessage(message, sock_fd))
+  if (!NIO_UnwrapMessage(message, sock_fd, &correction))
     return;
 
+  if (correction > 0.0 && correction < 1e-3) {
+    UTI_AddDoubleToTimespec(&local_ts.ts, -correction, &local_ts.ts);
+    DEBUG_LOG("Applied PTP correction %.9f", correction);
+  }
+
   /* Just ignore the packet if it's not of a recognized length */
   if (message->length < NTP_HEADER_LENGTH || message->length > sizeof (NTP_Packet)) {
     DEBUG_LOG("Unexpected length");
@@ -495,10 +501,12 @@ read_from_socket(int sock_fd, int event, void *anything)
 /* ================================================== */
 
 int
-NIO_UnwrapMessage(SCK_Message *message, int sock_fd)
+NIO_UnwrapMessage(SCK_Message *message, int sock_fd, double *correction)
 {
   PTP_NtpMessage *msg;
 
+  *correction = 0.0;
+
   if (!is_ptp_socket(sock_fd))
     return 1;
 
@@ -522,6 +530,8 @@ NIO_UnwrapMessage(SCK_Message *message, int sock_fd)
   message->data = (char *)message->data + PTP_NTP_PREFIX_LENGTH;
   message->length -= PTP_NTP_PREFIX_LENGTH;
 
+  *correction = (UTI_Integer64NetworkToHost(*(Integer64 *)msg->header.correction) >> 16) / 1e9;
+
   DEBUG_LOG("Unwrapped PTP->NTP len=%d", message->length);
 
   return 1;
diff --git a/ntp_io.h b/ntp_io.h
index 427bd966..dafcde06 100644
--- a/ntp_io.h
+++ b/ntp_io.h
@@ -64,7 +64,7 @@ extern int NIO_IsServerSocketOpen(void);
 extern int NIO_IsServerConnectable(NTP_Remote_Address *remote_addr);
 
 /* Function to unwrap an NTP message from non-native transport (e.g. PTP) */
-extern int NIO_UnwrapMessage(SCK_Message *message, int sock_fd);
+extern int NIO_UnwrapMessage(SCK_Message *message, int sock_fd, double *correction);
 
 /* Function to transmit a packet */
 extern int NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr,
diff --git a/ntp_io_linux.c b/ntp_io_linux.c
index 8f93f599..2a8cc46e 100644
--- a/ntp_io_linux.c
+++ b/ntp_io_linux.c
@@ -783,7 +783,8 @@ NIO_Linux_ProcessMessage(SCK_Message *message, NTP_Local_Address *local_addr,
     return 1;
   }
 
-  if (!NIO_UnwrapMessage(message, local_addr->sock_fd))
+  double c;
+  if (!NIO_UnwrapMessage(message, local_addr->sock_fd, &c))
     return 1;
 
   if (message->length < NTP_HEADER_LENGTH || message->length > sizeof (NTP_Packet))


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/