From da1a564439208f91b22f2af499b752b7a5ce3662 Mon Sep 17 00:00:00 2001
From: Vadim Fedorenko <vadfed@meta.com>
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 <vadfed@meta.com>
---
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