]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: make socket resume timeout configurable
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 9 Mar 2023 10:09:33 +0000 (11:09 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 9 Mar 2023 15:13:27 +0000 (16:13 +0100)
In some cases even the new timeout of 1 millisecond is not sufficient to
get all HW TX timestamps. Add a new directive to allow users to
specify longer timeouts.

conf.c
conf.h
doc/chrony.conf.adoc
ntp_io_linux.c

diff --git a/conf.c b/conf.c
index 0597836d8f05a4da117830236928ee5f07a3e2de..54652a099d7954695c330eb0cb7c533c6efaf30c 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -274,6 +274,9 @@ static int no_system_cert = 0;
 /* Array of CNF_HwTsInterface */
 static ARR_Instance hwts_interfaces;
 
+/* Timeout for resuming reading from sockets waiting for HW TX timestamp */
+static double hwts_timeout = 0.001;
+
 /* PTP event port (disabled by default) */
 static int ptp_port = 0;
 
@@ -602,6 +605,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
     parse_string(p, &hwclock_file);
   } else if (!strcasecmp(command, "hwtimestamp")) {
     parse_hwtimestamp(p);
+  } else if (!strcasecmp(command, "hwtstimeout")) {
+    parse_double(p, &hwts_timeout);
   } else if (!strcasecmp(command, "include")) {
     parse_include(p);
   } else if (!strcasecmp(command, "initstepslew")) {
@@ -2505,6 +2510,14 @@ CNF_GetHwTsInterface(unsigned int index, CNF_HwTsInterface **iface)
 
 /* ================================================== */
 
+double
+CNF_GetHwTsTimeout(void)
+{
+  return hwts_timeout;
+}
+
+/* ================================================== */
+
 int
 CNF_GetPtpPort(void)
 {
diff --git a/conf.h b/conf.h
index d7acb4fdd2b119932f359bba98883f0765571c0c..5ce6559e54350a40446f3e6df0d768b55041ede3 100644 (file)
--- a/conf.h
+++ b/conf.h
@@ -154,6 +154,7 @@ typedef struct {
 } CNF_HwTsInterface;
 
 extern int CNF_GetHwTsInterface(unsigned int index, CNF_HwTsInterface **iface);
+extern double CNF_GetHwTsTimeout(void);
 
 extern int CNF_GetPtpPort(void);
 
index f4dff3311ef80e2ad1509c7f5f16d795abc68e5b..b1e489c1efdaa4f641117d346290485a013a31c5 100644 (file)
@@ -2606,6 +2606,31 @@ hwtimestamp eth1 txcomp 300e-9 rxcomp 645e-9
 hwtimestamp *
 ----
 
+[[hwtstimeout]]*hwtstimeout* _timeout_::
+If hardware timestamping is used with a close NTP server, or the NIC or its
+driver is slow in providing the transmit timestamp of NTP requests, a response
+from the server can be received before the transmit timestamp of the request.
+To avoid calculating the offset with a less accurate transmit timestamp,
+*chronyd* suspends reading of NTP packets from the socket until the hardware
+transmit timestamp is provided. There is no guarantee that the timestamp will
+actually be provided (NICs typically have a limited rate of transmit
+timestamping). This directive configures how long should *chronyd* wait
+for the timestamp before resuming reading from the socket.
++
+The suspension is activated only on sockets that are not expected to receive
+requests, i.e. it does not work with the *peer* directive and also with the
+*server* and *pool* directives if the ports specified by the *port* and
+*acquisitionport* directives are equal.
++
+The default value is 0.001 seconds, which should be sufficient with most
+hardware. If you frequently see kernel transmit timestamps in the
+_measurements.log_ file or <<chronyc.adoc#ntpdata,*ntpdata*>> report, and it is
+not a server handling a high rate of requests in the interleaved mode on the
+same interface (which would compete with timestamping of the server's own
+requests), increasing the timeout to 0.01 or possibly even longer might help.
+Note that setting a timeout longer than the NTP polling interval causes the
+responses to be ignored when the timestamp is missing.
+
 [[keyfile]]*keyfile* _file_::
 This directive is used to specify the location of the file containing symmetric
 keys which are shared between NTP servers and clients, or peers, in order to
index b3d828ef6926653bbf91cde09241d8084dab13bb..3f0620a582d1be6721ac8e54e498f4d4770c931a 100644 (file)
@@ -91,8 +91,6 @@ static int permanent_ts_options;
    suspend reading of packets from the receive queue until a HW transmit
    timestamp is received from the error queue or a timeout reached. */
 
-#define RESUME_TIMEOUT 0.001
-
 struct HwTsSocket {
   int sock_fd;
   int suspended;
@@ -546,15 +544,16 @@ static void
 suspend_socket(int sock_fd)
 {
   struct HwTsSocket *ts_sock = get_hw_ts_socket(sock_fd, 1);
+  double timeout = CNF_GetHwTsTimeout();
 
-  if (!ts_sock)
+  if (!ts_sock || timeout <= 0.0)
     return;
 
   /* Remove previous timeout if there is one */
   SCH_RemoveTimeout(ts_sock->timeout_id);
 
   ts_sock->suspended = 1;
-  ts_sock->timeout_id = SCH_AddTimeoutByDelay(RESUME_TIMEOUT, resume_timeout, ts_sock);
+  ts_sock->timeout_id = SCH_AddTimeoutByDelay(timeout, resume_timeout, ts_sock);
   SCH_SetFileHandlerEvent(ts_sock->sock_fd, SCH_FILE_INPUT, 0);
 
   DEBUG_LOG("Suspended RX processing fd=%d", ts_sock->sock_fd);