Blob Blame History Raw
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