From da1a564439208f91b22f2af499b752b7a5ce3662 Mon Sep 17 00:00:00 2001 From: Vadim Fedorenko Date: Thu, 5 Jan 2023 08:22:26 -0800 Subject: [PATCH 1/2] unicast client: do not fail on absence of TX timestamp There is a possibility of no TX timestamp even if sendto() ended up with no error. Packet could be dropped because of hardware overflow or qdisc drops. Let's re-try sending delay request in this case. Signed-off-by: Vadim Fedorenko --- port.c | 16 ++++++++++++---- sk.c | 10 +++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/port.c b/port.c index a7ce01f..34880c8 100644 --- a/port.c +++ b/port.c @@ -647,7 +647,7 @@ static int peer_prepare_and_send(struct port *p, struct ptp_message *msg, } else { cnt = transport_peer(p->trp, &p->fda, event, msg); } - if (cnt <= 0) { + if (cnt < 0 || (event != TRANS_EVENT && cnt == 0)) { return -1; } port_stats_inc_tx(p, msg); @@ -1504,7 +1504,14 @@ static int port_pdelay_request(struct port *p) } if (msg_sots_missing(msg)) { pr_err("missing timestamp on transmitted peer delay request"); - goto out; + msg_put(msg); + if (p->peer_delay_req) { + msg_put(p->peer_delay_req); + p->peer_delay_req = NULL; + // we have to clean request to fail if we have really sent the + // request but got no HW timestamps + } + return 0; } if (p->peer_delay_req) { @@ -1566,8 +1573,9 @@ int port_delay_request(struct port *p) goto out; } if (msg_sots_missing(msg)) { + msg_put(msg); pr_err("missing timestamp on transmitted delay request"); - goto out; + return 0; } TAILQ_INSERT_HEAD(&p->delay_req, msg, list); @@ -3031,7 +3039,7 @@ int port_prepare_and_send(struct port *p, struct ptp_message *msg, } else { cnt = transport_send(p->trp, &p->fda, event, msg); } - if (cnt <= 0) { + if (cnt < 0 || (event != TRANS_EVENT && cnt == 0)) { return -1; } port_stats_inc_tx(p, msg); diff --git a/sk.c b/sk.c index d27abff..c0073e3 100644 --- a/sk.c +++ b/sk.c @@ -357,11 +357,15 @@ int sk_receive(int fd, void *buf, int buflen, /* Retry once on EINTR to avoid logging errors before exit */ if (res < 0 && errno == EINTR) res = poll(&pfd, 1, sk_tx_timeout); - if (res < 1) { - pr_err(res ? "poll for tx timestamp failed: %m" : - "timed out while polling for tx timestamp"); + if (!res) { + pr_err("timed out while polling for tx timestamp"); pr_err("increasing tx_timestamp_timeout may correct " "this issue, but it is likely caused by a driver bug"); + // we return 0 to indicate absence of timestamp + return 0; + } + if (res < 0) { + pr_err("poll for tx timestamp failed: %m"); return -errno; } else if (!(pfd.revents & sk_revents)) { pr_err("poll for tx timestamp woke up on non ERR event"); -- 2.30.2