From patchwork Mon Jan 28 17:45:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Andrzej Siewior X-Patchwork-Id: 1032096 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linutronix.de Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43pH9F2QnLz9sBb for ; Tue, 29 Jan 2019 04:45:53 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726779AbfA1Rpw (ORCPT ); Mon, 28 Jan 2019 12:45:52 -0500 Received: from Galois.linutronix.de ([146.0.238.70]:42809 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727189AbfA1Rpu (ORCPT ); Mon, 28 Jan 2019 12:45:50 -0500 Received: from bigeasy by Galois.linutronix.de with local (Exim 4.80) (envelope-from ) id 1goAyh-0003rR-FM; Mon, 28 Jan 2019 18:45:47 +0100 Date: Mon, 28 Jan 2019 18:45:47 +0100 From: Sebastian Andrzej Siewior To: Richard Cochran Cc: Andrew Lunn , Florian Fainelli , Heiner Kallweit , netdev@vger.kernel.org Subject: [RFC] net: dp83640: expire old TX-skb Message-ID: <20190128174547.twhwv64y2k5xx5x7@linutronix.de> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20180716 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org During sendmsg() a cloned skb is saved via dp83640_txtstamp() in ->tx_queue. After the NIC sends this packet, the PHY will reply with a timestamp for that TX packet. If the cable is pulled at the right time I don't see that packet. It might gets flushed as part of queue shutdown on NIC's side. Once the link is up again then after the next sendmsg() we enqueue another skb in dp83640_txtstamp() and have two on the list. Then the PHY will send a reply and decode_txts() attaches it to the first skb on the list. No crash occurs since refcounting works but we are one packet behind. linuxptp/ptp4l usually closes the socket and opens a new one (in such a timeout case) so those "stale" replies never get there. However it does not resume normal operation anymore. Purge old skbs in decode_txts(). Reviewed-by: Kurt Kanzenbach Signed-off-by: Sebastian Andrzej Siewior --- drivers/net/phy/dp83640.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 1dc043d0bc875..a50e0680a0322 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -920,13 +920,13 @@ static void decode_txts(struct dp83640_private *dp83640, { struct skb_shared_hwtstamps shhwtstamps; struct sk_buff *skb; + struct dp83640_skb_info *skb_info; u64 ns; u8 overflow; /* We must already have the skb that triggered this. */ - +again: skb = skb_dequeue(&dp83640->tx_queue); - if (!skb) { pr_debug("have timestamp but tx_queue empty\n"); return; @@ -941,6 +941,11 @@ static void decode_txts(struct dp83640_private *dp83640, } return; } + skb_info = (struct dp83640_skb_info *)skb->cb; + if (time_after(jiffies, skb_info->tmo)) { + kfree_skb(skb); + goto again; + } ns = phy2txts(phy_txts); memset(&shhwtstamps, 0, sizeof(shhwtstamps)); @@ -1489,6 +1494,7 @@ static void dp83640_txtstamp(struct phy_device *phydev, struct sk_buff *skb, int type) { struct dp83640_private *dp83640 = phydev->priv; + struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb; switch (dp83640->hwts_tx_en) { @@ -1500,6 +1506,7 @@ static void dp83640_txtstamp(struct phy_device *phydev, /* fall through */ case HWTSTAMP_TX_ON: skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + skb_info->tmo = jiffies + SKB_TIMESTAMP_TIMEOUT; skb_queue_tail(&dp83640->tx_queue, skb); break;