Jiri Slaby 179bcf
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Jiri Slaby 179bcf
Date: Mon, 4 Feb 2019 11:20:29 +0100
Jiri Slaby 179bcf
Subject: net: dp83640: expire old TX-skb
Jiri Slaby 179bcf
Git-commit: 53bc8d2af08654659abfadfd3e98eb9922ff787c
Jiri Slaby 179bcf
Patch-mainline: v5.0-rc6
Jiri Slaby 179bcf
References: networking-stable-19_02_10
Jiri Slaby 179bcf
Jiri Slaby 179bcf
During sendmsg() a cloned skb is saved via dp83640_txtstamp() in
Jiri Slaby 179bcf
->tx_queue. After the NIC sends this packet, the PHY will reply with a
Jiri Slaby 179bcf
timestamp for that TX packet. If the cable is pulled at the right time I
Jiri Slaby 179bcf
don't see that packet. It might gets flushed as part of queue shutdown
Jiri Slaby 179bcf
on NIC's side.
Jiri Slaby 179bcf
Once the link is up again then after the next sendmsg() we enqueue
Jiri Slaby 179bcf
another skb in dp83640_txtstamp() and have two on the list. Then the PHY
Jiri Slaby 179bcf
will send a reply and decode_txts() attaches it to the first skb on the
Jiri Slaby 179bcf
list.
Jiri Slaby 179bcf
No crash occurs since refcounting works but we are one packet behind.
Jiri Slaby 179bcf
linuxptp/ptp4l usually closes the socket and opens a new one (in such a
Jiri Slaby 179bcf
timeout case) so those "stale" replies never get there. However it does
Jiri Slaby 179bcf
not resume normal operation anymore.
Jiri Slaby 179bcf
Jiri Slaby 179bcf
Purge old skbs in decode_txts().
Jiri Slaby 179bcf
Jiri Slaby 179bcf
Fixes: cb646e2b02b2 ("ptp: Added a clock driver for the National Semiconductor PHYTER.")
Jiri Slaby 179bcf
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Jiri Slaby 179bcf
Reviewed-by: Kurt Kanzenbach <kurt@linutronix.de>
Jiri Slaby 179bcf
Acked-by: Richard Cochran <richardcochran@gmail.com>
Jiri Slaby 179bcf
Signed-off-by: David S. Miller <davem@davemloft.net>
Jiri Slaby 179bcf
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby 179bcf
---
Jiri Slaby 179bcf
 drivers/net/phy/dp83640.c | 13 ++++++++++---
Jiri Slaby 179bcf
 1 file changed, 10 insertions(+), 3 deletions(-)
Jiri Slaby 179bcf
Jiri Slaby 179bcf
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
Jiri Slaby 179bcf
index 18b41bc345ab..6e8807212aa3 100644
Jiri Slaby 179bcf
--- a/drivers/net/phy/dp83640.c
Jiri Slaby 179bcf
+++ b/drivers/net/phy/dp83640.c
Jiri Slaby 179bcf
@@ -898,14 +898,14 @@ static void decode_txts(struct dp83640_private *dp83640,
Jiri Slaby 179bcf
 			struct phy_txts *phy_txts)
Jiri Slaby 179bcf
 {
Jiri Slaby 179bcf
 	struct skb_shared_hwtstamps shhwtstamps;
Jiri Slaby 179bcf
+	struct dp83640_skb_info *skb_info;
Jiri Slaby 179bcf
 	struct sk_buff *skb;
Jiri Slaby 179bcf
-	u64 ns;
Jiri Slaby 179bcf
 	u8 overflow;
Jiri Slaby 179bcf
+	u64 ns;
Jiri Slaby 179bcf
 
Jiri Slaby 179bcf
 	/* We must already have the skb that triggered this. */
Jiri Slaby 179bcf
-
Jiri Slaby 179bcf
+again:
Jiri Slaby 179bcf
 	skb = skb_dequeue(&dp83640->tx_queue);
Jiri Slaby 179bcf
-
Jiri Slaby 179bcf
 	if (!skb) {
Jiri Slaby 179bcf
 		pr_debug("have timestamp but tx_queue empty\n");
Jiri Slaby 179bcf
 		return;
Jiri Slaby 179bcf
@@ -920,6 +920,11 @@ static void decode_txts(struct dp83640_private *dp83640,
Jiri Slaby 179bcf
 		}
Jiri Slaby 179bcf
 		return;
Jiri Slaby 179bcf
 	}
Jiri Slaby 179bcf
+	skb_info = (struct dp83640_skb_info *)skb->cb;
Jiri Slaby 179bcf
+	if (time_after(jiffies, skb_info->tmo)) {
Jiri Slaby 179bcf
+		kfree_skb(skb);
Jiri Slaby 179bcf
+		goto again;
Jiri Slaby 179bcf
+	}
Jiri Slaby 179bcf
 
Jiri Slaby 179bcf
 	ns = phy2txts(phy_txts);
Jiri Slaby 179bcf
 	memset(&shhwtstamps, 0, sizeof(shhwtstamps));
Jiri Slaby 179bcf
@@ -1472,6 +1477,7 @@ static bool dp83640_rxtstamp(struct phy_device *phydev,
Jiri Slaby 179bcf
 static void dp83640_txtstamp(struct phy_device *phydev,
Jiri Slaby 179bcf
 			     struct sk_buff *skb, int type)
Jiri Slaby 179bcf
 {
Jiri Slaby 179bcf
+	struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb;
Jiri Slaby 179bcf
 	struct dp83640_private *dp83640 = phydev->priv;
Jiri Slaby 179bcf
 
Jiri Slaby 179bcf
 	switch (dp83640->hwts_tx_en) {
Jiri Slaby 179bcf
@@ -1484,6 +1490,7 @@ static void dp83640_txtstamp(struct phy_device *phydev,
Jiri Slaby 179bcf
 		/* fall through */
Jiri Slaby 179bcf
 	case HWTSTAMP_TX_ON:
Jiri Slaby 179bcf
 		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
Jiri Slaby 179bcf
+		skb_info->tmo = jiffies + SKB_TIMESTAMP_TIMEOUT;
Jiri Slaby 179bcf
 		skb_queue_tail(&dp83640->tx_queue, skb);
Jiri Slaby 179bcf
 		break;
Jiri Slaby 179bcf
 
Jiri Slaby 179bcf
-- 
Jiri Slaby 179bcf
2.21.0
Jiri Slaby 179bcf