ntp: make socket resume timeout configurable
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.
This commit is contained in:
parent
ccebec3eb6
commit
ab776ed9d8
4 changed files with 42 additions and 4 deletions
13
conf.c
13
conf.c
|
@ -274,6 +274,9 @@ static int no_system_cert = 0;
|
||||||
/* Array of CNF_HwTsInterface */
|
/* Array of CNF_HwTsInterface */
|
||||||
static ARR_Instance hwts_interfaces;
|
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) */
|
/* PTP event port (disabled by default) */
|
||||||
static int ptp_port = 0;
|
static int ptp_port = 0;
|
||||||
|
|
||||||
|
@ -602,6 +605,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
|
||||||
parse_string(p, &hwclock_file);
|
parse_string(p, &hwclock_file);
|
||||||
} else if (!strcasecmp(command, "hwtimestamp")) {
|
} else if (!strcasecmp(command, "hwtimestamp")) {
|
||||||
parse_hwtimestamp(p);
|
parse_hwtimestamp(p);
|
||||||
|
} else if (!strcasecmp(command, "hwtstimeout")) {
|
||||||
|
parse_double(p, &hwts_timeout);
|
||||||
} else if (!strcasecmp(command, "include")) {
|
} else if (!strcasecmp(command, "include")) {
|
||||||
parse_include(p);
|
parse_include(p);
|
||||||
} else if (!strcasecmp(command, "initstepslew")) {
|
} 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
|
int
|
||||||
CNF_GetPtpPort(void)
|
CNF_GetPtpPort(void)
|
||||||
{
|
{
|
||||||
|
|
1
conf.h
1
conf.h
|
@ -154,6 +154,7 @@ typedef struct {
|
||||||
} CNF_HwTsInterface;
|
} CNF_HwTsInterface;
|
||||||
|
|
||||||
extern int CNF_GetHwTsInterface(unsigned int index, CNF_HwTsInterface **iface);
|
extern int CNF_GetHwTsInterface(unsigned int index, CNF_HwTsInterface **iface);
|
||||||
|
extern double CNF_GetHwTsTimeout(void);
|
||||||
|
|
||||||
extern int CNF_GetPtpPort(void);
|
extern int CNF_GetPtpPort(void);
|
||||||
|
|
||||||
|
|
|
@ -2606,6 +2606,31 @@ hwtimestamp eth1 txcomp 300e-9 rxcomp 645e-9
|
||||||
hwtimestamp *
|
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_::
|
[[keyfile]]*keyfile* _file_::
|
||||||
This directive is used to specify the location of the file containing symmetric
|
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
|
keys which are shared between NTP servers and clients, or peers, in order to
|
||||||
|
|
|
@ -91,8 +91,6 @@ static int permanent_ts_options;
|
||||||
suspend reading of packets from the receive queue until a HW transmit
|
suspend reading of packets from the receive queue until a HW transmit
|
||||||
timestamp is received from the error queue or a timeout reached. */
|
timestamp is received from the error queue or a timeout reached. */
|
||||||
|
|
||||||
#define RESUME_TIMEOUT 0.001
|
|
||||||
|
|
||||||
struct HwTsSocket {
|
struct HwTsSocket {
|
||||||
int sock_fd;
|
int sock_fd;
|
||||||
int suspended;
|
int suspended;
|
||||||
|
@ -546,15 +544,16 @@ static void
|
||||||
suspend_socket(int sock_fd)
|
suspend_socket(int sock_fd)
|
||||||
{
|
{
|
||||||
struct HwTsSocket *ts_sock = get_hw_ts_socket(sock_fd, 1);
|
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;
|
return;
|
||||||
|
|
||||||
/* Remove previous timeout if there is one */
|
/* Remove previous timeout if there is one */
|
||||||
SCH_RemoveTimeout(ts_sock->timeout_id);
|
SCH_RemoveTimeout(ts_sock->timeout_id);
|
||||||
|
|
||||||
ts_sock->suspended = 1;
|
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);
|
SCH_SetFileHandlerEvent(ts_sock->sock_fd, SCH_FILE_INPUT, 0);
|
||||||
|
|
||||||
DEBUG_LOG("Suspended RX processing fd=%d", ts_sock->sock_fd);
|
DEBUG_LOG("Suspended RX processing fd=%d", ts_sock->sock_fd);
|
||||||
|
|
Loading…
Reference in a new issue