From nobody Mon Sep 28 23:55:26 2026 Received: from mail-ot1-f49.google.com (mail-ot1-f49.google.com [209.85.210.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6753431DDBF for ; Sat, 15 Aug 2026 01:08:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786756117; cv=none; b=q6aXNIPoZMUuRTawrAS+yNHfveQONjtjoJ35aNtKFuO9HfGlP4Uv3+1nSxufSMIqajm+GgJkIIEI0QV7rtk7uPfkQkDjG4AtgEqIbsohbllaIglwfuzRMBqsIRHgbc4WLwSglc2yNCU5l10HWDu8TJuXBvUWssdehs3IO+/9V1o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786756117; c=relaxed/simple; bh=e3z45CP4vdDBjSxwmlNhdTt8RlVurE4vCAB/LGUpSyM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QLsS/B+WBbVVxKelrZPfff+4VxJruvIiulFZnOpgGYf63muPhG2gGnSWKBmmp2sE6DQGgsW6j6eTxfVKKP0jGVLTVpxICQj8yehnN4+mr56wuQEY5Rwe1LAPF7Q9FmkVx0baStVgiUuaTESDXJYe20t1LyPTKZ+/CAHkge2v9tI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=j0ctsmyB; arc=none smtp.client-ip=209.85.210.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="j0ctsmyB" Received: by mail-ot1-f49.google.com with SMTP id 46e09a7af769-7f18c0e03e3so827201a34.2 for ; Fri, 14 Aug 2026 18:08:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786756114; x=1787360914; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=0XZsci9bH9VjVjaoFyFfeIOs5MILIPzzI3xZQHGP9Vc=; b=j0ctsmyBidNiQIBWyslgX3aw0acsA4R5gyahU6vrKfOr3bWarkL12If8CYyaUAm0kN p8Xkogm367FyR3YDDnOFebvQcLDCyjbS7DyiSSY2VljHfk8LXVaUM9sx8uGypTW9IJov VPrIC06JqbyfcxNcG2cpddXUkWiA1+tCwRDTHvp7kBuR4xVf7P04f/LAJQQupXi+OTS3 +LEVXkfZY95q8n+tBPrV9n5s5LVcFA+vYTMyjDI+xqqoudhjpqmjpyArdgXcjxPzFi3O W/oc+TCXN04Dqm7Ha+ub7G8pRJw5MreQ9k3fSGdnzxQjIik/WyS8q2siK+BvC/Sim7i4 j1Ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786756114; x=1787360914; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=0XZsci9bH9VjVjaoFyFfeIOs5MILIPzzI3xZQHGP9Vc=; b=MAuU51fsSO9hfKU98xqGj0DZWmI26N6yHdrIjVXc+csnHsIGPTfecC2YwAwW/ooSDW mxWXSWEihsKbxT+Kc2+KCX9AUjEJPV453Q3+IVjpvQUnyUAcLf2JFqYpEgrY4pHoAtce QIxFKsN3r604NY34nfMCtPN4g3apvjS5WO5B9I4DBsycpddosxVrNpE29SOMoa1SNq7h rf0ThQ3d7tmHPVv95Y3PMcGeiwI6XQBGV0zAXuY1QVlyvWW2ZCA8ZkFUou40UnzM5m2f IMGGGI1UgglK+E1r+W+cx0PQTQtQruws4TB4K2at2ds3Io6g7X/lnf6m9xSUNA+94GbV 2HJw== X-Forwarded-Encrypted: i=1; AHgh+RruBL32oAjpLjI7zPZq91Cv5oboo7Hm1cjNyUKVqQrWI/dc71iBGCNP41uCOiSMJUCWPEWE7L+Bk1LD+1s=@vger.kernel.org X-Gm-Message-State: AOJu0Yy6/1HNLO8OpMuIl/rIePAfDiAkkThBGJ62ELhlf2VGV+aLKAZs j1tHnxPbO0Rh9BKkAvMtypvZZ+eTDk3O5B9+CRuJI1F0iONsUzgl1A/V X-Gm-Gg: AR+sD11MdC9qnxl4j2fqdCaFJnLHAF0oyiPIDea4bUZ7bzcEB9MggQG9+3yC2FD6P4w WVhPtRoA/Vy7f6XmmCnTMJ1YdABflx2esqp0JzfRGoy68vThCvL29khZCMFMOZtaML6vAnUJdZ6 ktVx/S5nqWHNk1/Hmny/DJm93rQFDXPjru0xlPIloQ0UchIwxBdftzVTHd6AhBqeYo+TBPRxBYr DDz6Yjpi+cqLJPDtOBXEOiP0wuqf0V0r/PytcqkMULD9YLMOZ5FYPzuSQkZ8Rk5e/Ei0uYvsZY2 ws5nmm9OqZARv4dGi/8SKj3vyoN+55LZ9AV93XNs/T1lWhd0O2zfPQu59P2iflleTL/Wr4yhs90 WPObAI0mVGCCEpZggVUz05Lb/sMk61WDWShXOuJn4qhNFF4JGw9PWH5kUlRFQ8tAOa3lvgU8wXO ocjXV5KE+Pu/fgBdXE9dAs0UwZVu+SY/bKHb5FEKn4qvZwVZAlVZKxLIMvIA69btnh7nVWNRnZ6 ev0EgHqabf3ZoytA4wY X-Received: by 2002:a05:6830:348a:b0:7f3:a8ac:45f7 with SMTP id 46e09a7af769-7f3de565798mr7439607a34.3.1786756114170; Fri, 14 Aug 2026 18:08:34 -0700 (PDT) Received: from shiv-machina.. (174-16-201-18.hlrn.qwest.net. [174.16.201.18]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f3e86282fesm2232153a34.14.2026.08.14.18.08.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Aug 2026 18:08:33 -0700 (PDT) From: Shivani Gupta To: intel-wired-lan@lists.osuosl.org, Tony Nguyen , Przemek Kitszel Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Richard Cochran , Jacob Keller , Matthew Vick , Vinicius Costa Gomes , Kurt Kanzenbach , Aleksandr Loktionov Subject: [PATCH iwl-net 1/2] igb: Fix race condition in PTP tx code Date: Sat, 15 Aug 2026 01:08:26 +0000 Message-Id: <20260815010827.91912-2-shivani07g@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260815010827.91912-1-shivani07g@gmail.com> References: <20260815010827.91912-1-shivani07g@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" igb stores one outstanding hardware Tx timestamp request in ptp_tx_skb. The state bit used for admission is atomic, but ptp_tx_skb and ptp_tx_start are accessed without common synchronization by the transmit path, timestamp worker, watchdog, error cleanup, and suspend path. The watchdog can run after the transmit path sets the state bit and stores the skb but before it refreshes ptp_tx_start. If the previous request is older than IGB_PTP_TX_TIMEOUT, the watchdog treats the new request as timed out and releases its timestamp reference. A later hardware latch can then be associated with another request. Add ptp_tx_lock and use it for all accesses to the request pointer and start time. Initialize the lock during software setup, before register_netdev() can expose the watchdog and transmit paths. The pointer itself now provides admission control, so remove __IGB_PTP_TX_IN_PROGRESS. The worker and watchdog share a lock-held timeout helper. The watchdog no longer calls cancel_work_sync(), which would deadlock while holding the new lock and is unnecessary because the worker rechecks the pointer under that lock. Also remove cancel_work_sync() from the ndo_start_xmit error path, where sleeping is not allowed. Clear the slot only if it still belongs to the skb whose transmit failed, so a completed request cannot make error cleanup discard a replacement request. Suspend retains synchronous cancellation outside the lock before freeing the pending reference. This follows the locking model introduced for igc by commit 9c50e2b150c8 ("igc: Fix race condition in PTP tx code"), with the additional 82576 polling and transmit-error paths required by igb. Fixes: e5f36ad14c93 ("igb: check for Tx timestamp timeouts during watchdog") Fixes: 74344e32fcc0 ("igb: avoid permanent lock of *_PTP_TX_IN_PROGRESS") Signed-off-by: Shivani Gupta --- drivers/net/ethernet/intel/igb/igb.h | 3 +- drivers/net/ethernet/intel/igb/igb_main.c | 25 ++++-- drivers/net/ethernet/intel/igb/igb_ptp.c | 104 +++++++++++++--------- 3 files changed, 83 insertions(+), 49 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/in= tel/igb/igb.h index 0fff1df81b7b..ecd284f51d3e 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -625,6 +625,8 @@ struct igb_adapter { struct ptp_clock_info ptp_caps; struct delayed_work ptp_overflow_work; struct work_struct ptp_tx_work; + /* Access to ptp_tx_skb and ptp_tx_start is protected by ptp_tx_lock. */ + spinlock_t ptp_tx_lock; struct sk_buff *ptp_tx_skb; struct kernel_hwtstamp_config tstamp_config; unsigned long ptp_tx_start; @@ -714,7 +716,6 @@ enum e1000_state_t { __IGB_TESTING, __IGB_RESETTING, __IGB_DOWN, - __IGB_PTP_TX_IN_PROGRESS, }; =20 enum igb_boards { diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethern= et/intel/igb/igb_main.c index a1e89a375744..fc70f7aa4ce0 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -4062,6 +4062,8 @@ static int igb_sw_init(struct igb_adapter *adapter) adapter->max_frame_size =3D netdev->mtu + IGB_ETH_PKT_HDR_PAD; adapter->min_frame_size =3D ETH_ZLEN + ETH_FCS_LEN; =20 + /* The netdev watchdog can run as soon as the device is registered. */ + spin_lock_init(&adapter->ptp_tx_lock); spin_lock_init(&adapter->nfc_lock); spin_lock_init(&adapter->stats64_lock); =20 @@ -6561,10 +6563,11 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, =20 if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { struct igb_adapter *adapter =3D netdev_priv(tx_ring->netdev); + unsigned long flags; =20 + spin_lock_irqsave(&adapter->ptp_tx_lock, flags); if (adapter->tstamp_config.tx_type =3D=3D HWTSTAMP_TX_ON && - !test_and_set_bit_lock(__IGB_PTP_TX_IN_PROGRESS, - &adapter->state)) { + !adapter->ptp_tx_skb) { skb_shinfo(skb)->tx_flags |=3D SKBTX_IN_PROGRESS; tx_flags |=3D IGB_TX_FLAGS_TSTAMP; =20 @@ -6575,6 +6578,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, } else { adapter->tx_hwtstamp_skipped++; } + spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); } =20 if (skb_vlan_tag_present(skb)) { @@ -6603,12 +6607,19 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, cleanup_tx_tstamp: if (unlikely(tx_flags & IGB_TX_FLAGS_TSTAMP)) { struct igb_adapter *adapter =3D netdev_priv(tx_ring->netdev); + unsigned long flags; =20 - dev_kfree_skb_any(adapter->ptp_tx_skb); - adapter->ptp_tx_skb =3D NULL; - if (adapter->hw.mac.type =3D=3D e1000_82576) - cancel_work_sync(&adapter->ptp_tx_work); - clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state); + /* ndo_start_xmit runs in atomic context, so the scheduled + * ptp_tx_work cannot be cancelled here. It checks + * ptp_tx_skb under ptp_tx_lock and does nothing once the + * pending timestamp request is cleared. + */ + spin_lock_irqsave(&adapter->ptp_tx_lock, flags); + if (adapter->ptp_tx_skb =3D=3D skb) { + dev_kfree_skb_any(adapter->ptp_tx_skb); + adapter->ptp_tx_skb =3D NULL; + } + spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); } =20 return NETDEV_TX_OK; diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/etherne= t/intel/igb/igb_ptp.c index 638d8242b66b..3cc05f9198f8 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -796,6 +796,21 @@ static int igb_ptp_verify_pin(struct ptp_clock_info *p= tp, unsigned int pin, return 0; } =20 +/* Requires adapter->ptp_tx_lock held by caller. */ +static void igb_ptp_tx_timeout(struct igb_adapter *adapter) +{ + struct e1000_hw *hw =3D &adapter->hw; + + dev_kfree_skb_any(adapter->ptp_tx_skb); + adapter->ptp_tx_skb =3D NULL; + adapter->tx_hwtstamp_timeouts++; + /* Clear the tx valid bit in TSYNCTXCTL register to enable + * interrupt + */ + rd32(E1000_TXSTMPH); + dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n"); +} + /** * igb_ptp_tx_work * @work: pointer to work struct @@ -808,23 +823,18 @@ static void igb_ptp_tx_work(struct work_struct *work) struct igb_adapter *adapter =3D container_of(work, struct igb_adapter, ptp_tx_work); struct e1000_hw *hw =3D &adapter->hw; + unsigned long flags; u32 tsynctxctl; =20 + spin_lock_irqsave(&adapter->ptp_tx_lock, flags); + if (!adapter->ptp_tx_skb) - return; + goto unlock; =20 if (time_is_before_jiffies(adapter->ptp_tx_start + IGB_PTP_TX_TIMEOUT)) { - dev_kfree_skb_any(adapter->ptp_tx_skb); - adapter->ptp_tx_skb =3D NULL; - clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state); - adapter->tx_hwtstamp_timeouts++; - /* Clear the tx valid bit in TSYNCTXCTL register to enable - * interrupt - */ - rd32(E1000_TXSTMPH); - dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n"); - return; + igb_ptp_tx_timeout(adapter); + goto unlock; } =20 tsynctxctl =3D rd32(E1000_TSYNCTXCTL); @@ -833,6 +843,9 @@ static void igb_ptp_tx_work(struct work_struct *work) else /* reschedule to check later */ schedule_work(&adapter->ptp_tx_work); + +unlock: + spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); } =20 static void igb_ptp_overflow_check(struct work_struct *work) @@ -897,32 +910,45 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter) */ void igb_ptp_tx_hang(struct igb_adapter *adapter) { - struct e1000_hw *hw =3D &adapter->hw; - bool timeout =3D time_is_before_jiffies(adapter->ptp_tx_start + - IGB_PTP_TX_TIMEOUT); + unsigned long flags; + + spin_lock_irqsave(&adapter->ptp_tx_lock, flags); =20 if (!adapter->ptp_tx_skb) - return; + goto unlock; =20 - if (!test_bit(__IGB_PTP_TX_IN_PROGRESS, &adapter->state)) - return; + if (time_is_after_jiffies(adapter->ptp_tx_start + IGB_PTP_TX_TIMEOUT)) + goto unlock; =20 /* If we haven't received a timestamp within the timeout, it is * reasonable to assume that it will never occur, so we can unlock the * timestamp bit when this occurs. */ - if (timeout) { - cancel_work_sync(&adapter->ptp_tx_work); - dev_kfree_skb_any(adapter->ptp_tx_skb); - adapter->ptp_tx_skb =3D NULL; - clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state); - adapter->tx_hwtstamp_timeouts++; - /* Clear the tx valid bit in TSYNCTXCTL register to enable - * interrupt - */ - rd32(E1000_TXSTMPH); - dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n"); - } + igb_ptp_tx_timeout(adapter); + +unlock: + spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); +} + +/** + * igb_ptp_clear_tx_tstamp - drop a pending Tx timestamp request + * @adapter: private network adapter structure + * + * Cancel the timestamp retrieval work and free a pending timestamp skb. + * + * Context: Must be called in sleepable context with ptp_tx_lock not held; + * cancel_work_sync() waits for igb_ptp_tx_work() which takes it. + */ +static void igb_ptp_clear_tx_tstamp(struct igb_adapter *adapter) +{ + unsigned long flags; + + cancel_work_sync(&adapter->ptp_tx_work); + + spin_lock_irqsave(&adapter->ptp_tx_lock, flags); + dev_kfree_skb_any(adapter->ptp_tx_skb); + adapter->ptp_tx_skb =3D NULL; + spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); } =20 /** @@ -932,6 +958,8 @@ void igb_ptp_tx_hang(struct igb_adapter *adapter) * If we were asked to do hardware stamping and such a time stamp is * available, then it must have been for this skb here because we only * allow only one such packet into the queue. + * + * Context: Expects adapter->ptp_tx_lock to be held by caller. **/ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter) { @@ -963,15 +991,14 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *a= dapter) shhwtstamps.hwtstamp =3D ktime_add_ns(shhwtstamps.hwtstamp, adjust); =20 - /* Clear the lock early before calling skb_tstamp_tx so that - * applications are not woken up before the lock bit is clear. We use - * a copy of the skb pointer to ensure other threads can't change it - * while we're notifying the stack. + /* Clear the pending request before calling skb_tstamp_tx so that + * a new timestamp request can be accepted. We use a copy of the skb + * pointer to ensure other threads can't change it while we're + * notifying the stack. */ adapter->ptp_tx_skb =3D NULL; - clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state); =20 - /* Notify the stack and free the skb after we've unlocked */ + /* Notify the stack and free the skb */ skb_tstamp_tx(skb, &shhwtstamps); dev_kfree_skb_any(skb); } @@ -1434,12 +1461,7 @@ void igb_ptp_suspend(struct igb_adapter *adapter) if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK) cancel_delayed_work_sync(&adapter->ptp_overflow_work); =20 - cancel_work_sync(&adapter->ptp_tx_work); - if (adapter->ptp_tx_skb) { - dev_kfree_skb_any(adapter->ptp_tx_skb); - adapter->ptp_tx_skb =3D NULL; - clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state); - } + igb_ptp_clear_tx_tstamp(adapter); } =20 /** From nobody Mon Sep 28 23:55:26 2026 Received: from mail-ot1-f42.google.com (mail-ot1-f42.google.com [209.85.210.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9890231E83D for ; Sat, 15 Aug 2026 01:08:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786756119; cv=none; b=JosiLOAlzSq8vHOUgu5vTgzmofJZ2EkKhhQ49UvDOw7Lmw6JC+Mqifqllg+5GC3kNTJ9CQJkHf2m4P0S+dFvH+thphueNEvYFd/fMiuRmfs5BOdwJEOWkvhFP2dqQgkk5F7LEho7X4QhmBMlYcmQAwt4MgRChy1YfAq+AY/8yjQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786756119; c=relaxed/simple; bh=7o+1KtI0zZ/g7VBmIPoP7jQv4Hd6/Jllv2m0vsr1XPc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=FbMWiFztADBcjVqjnqPHA0pc6823Aiqx6Q/zDOACgmBPXjKtSQer5l8xfN+PlJVZgDX1Wa7Y5wPUrBgd+2PBB9gOwxf+kQAVJy7SvMvA3MQuBwpGF7+XYFg/eaoJ1f+USHRhHtP3Xw0kMnRACxfSzHQe7LrJf+aF3ujL2ENYKS4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BcJ0zlvo; arc=none smtp.client-ip=209.85.210.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BcJ0zlvo" Received: by mail-ot1-f42.google.com with SMTP id 46e09a7af769-7ee4f241f42so1748353a34.1 for ; Fri, 14 Aug 2026 18:08:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786756116; x=1787360916; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=7VA9P9TmAckj6vhir0RJ/OmqAptpB42Jyovrg4yN07c=; b=BcJ0zlvoWTQFa852xlJDV3WUZpH5AQGFD03QtP7bX8FQCnVcj6k1G0uL1lJK8dKG0p tSWhUWK53jg0DX7MylegGh2Rxs8Cd3ayPb8i/uJim0LF2b+z4nttqlcatmWalB9nWZwn NoXpnOAWVazGjBqxbeQheHqJYq/NTFokfp1eVWbbf65VsPlzJ/2ha1P/HzokWeSffbrl 2w377ZVinI2rRJDHbjagOovtAvXG8+wOzOMUU3TSItSng7qSLFyePJjOgCbIC+viBoV0 BIk+CnIzw9olgVfuUP3orBrlqhGaixA6nhbd67zdn3WYVAU+XoseoDAEIVjfohZAXn5Q HwgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786756116; x=1787360916; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=7VA9P9TmAckj6vhir0RJ/OmqAptpB42Jyovrg4yN07c=; b=cKsVAICP2hR/ifpO/2tZoMi8n43KcbWTiN26qmq61YWX/sLuR+aGiQqUjY6RQ8mmeH VwzR+D+m46OD0lMTerZdRmgXZzGssl84UJMZDBb7+aN0tOj+R/xuEAhBXz1/tRi5jUw/ 3C0v7KPGisEVU+qc2qMxPMaa4Rh1PbmDqMDXo3ljXzC6Mt2vHJuDN8Icoa5DOeIEgHCS 64PAXmU98ah/PCZj4w9FhPWt6cJTJe55w6fWZ/yAQcd/y7hO+SDI90/HT1nqjT/Iy/XV i7b55PPOLQVSxRjeNPk0Fxx1h6yyhtxP3elFvlfOHJYCGFhm7vkYbhZPTAp/YYq9ew57 EXIg== X-Forwarded-Encrypted: i=1; AHgh+Rp+6n0y7swAv5TmcggyzFDtqcUBRKfeImTiDfbnYLkhcmn9zyBTDuoJVj5BWgc0DN+U7+axFLMVI1oNeow=@vger.kernel.org X-Gm-Message-State: AOJu0Yz8/Kvtb+yrppQMPnfPDgU1hYRTDB4fbzp4wheZ6j68BQnLg2t7 +35qX5gQOEaye4PH0Q2xy10A1w/6/zbXeLG7QvnZXUMzhiBlOLqmwLrW X-Gm-Gg: AR+sD109AAfWh2AfPkteIlTkAJYckgrraV1oyi+c05o7meR4U49jCz4tpRCvvgKwKOl aIylWwrXmTrMcX4Gz3EDRtpjJITsS8QmWORn50zr1k/oovZ7Q5Ykg8v7mf1r4Zcb8N9AryGBLoQ H+AQQH6Zokm/xp6PUspFYEa+XZ077EflsJ+YmKP3Q9W8HA0jj5c4fLUsl1t4Qv7EsIYEipHX769 e1pAyzjUOxKmm5NsacjktPeTq2RoKs8o9sPfP6kz/dkjYua/Qmm7sYkc8vQ/PPpgIp4+dtRUjYN mV16Y1JMSmLmO3xgprlmpdtVsz4sk+1vt+zLgcgV02OIaitoCZFZh2TlgAdYqrZ+HMUMsi7aFZ6 yeWtToRSu8uUyfXg5q827nCEcsyTZf/ZQwr8YC4D1am9TC4LLOepB8BM6n7ntWBYQW10wsDytgG P57R/HBsHI7MUxnI0j5Py52W0vrg97zL7p63lIjroKn52YOVVMc899i4DgJmlp1wlzCwtmgiUgl XZe75eeb/+0Zn1EKCmr X-Received: by 2002:a9d:69ca:0:b0:7f3:daf9:eda3 with SMTP id 46e09a7af769-7f3daf9f40emr4856740a34.4.1786756116462; Fri, 14 Aug 2026 18:08:36 -0700 (PDT) Received: from shiv-machina.. (174-16-201-18.hlrn.qwest.net. [174.16.201.18]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f3e86282fesm2232153a34.14.2026.08.14.18.08.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Aug 2026 18:08:36 -0700 (PDT) From: Shivani Gupta To: intel-wired-lan@lists.osuosl.org, Tony Nguyen , Przemek Kitszel Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Richard Cochran , Jacob Keller , Matthew Vick , Vinicius Costa Gomes , Kurt Kanzenbach , Aleksandr Loktionov Subject: [PATCH iwl-net 2/2] igb: Clear pending Tx timestamp requests when disabling Tx timestamping Date: Sat, 15 Aug 2026 01:08:27 +0000 Message-Id: <20260815010827.91912-3-shivani07g@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260815010827.91912-1-shivani07g@gmail.com> References: <20260815010827.91912-1-shivani07g@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Disabling Tx hardware timestamping clears TSYNCTXCTL.EN but leaves an outstanding request in ptp_tx_skb. Re-enabling within IGB_PTP_TX_TIMEOUT therefore finds the single timestamp slot occupied and skips new requests until the watchdog reports a misleading timeout, producing a blackout of up to 15 seconds. Cancel timestamp retrieval when disabling Tx timestamping, then publish HWTSTAMP_TX_OFF and release the pending request under ptp_tx_lock. The transmit path tests both the configured mode and slot ownership under the same lock, so no request can be admitted between clearing the slot and publishing the disabled state. Updates to the saved configuration and the watchdog mode check use that lock as well. Suspend uses the same cleanup helper without changing the saved mode, allowing reset to restore the requested configuration after resume. Only count a timestamp request as skipped when hardware timestamping is enabled and the slot is occupied. Requests carrying SKBTX_HW_TSTAMP while the feature is disabled could never have been serviced and are ignored without changing the counter. Fixes: 1f6e8178d685 ("igb: Prevent dropped Tx timestamps via work items and= interrupts.") Signed-off-by: Shivani Gupta --- drivers/net/ethernet/intel/igb/igb_main.c | 26 +++++++++++++---------- drivers/net/ethernet/intel/igb/igb_ptp.c | 20 +++++++++++++++-- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethern= et/intel/igb/igb_main.c index fc70f7aa4ce0..42204e3307d6 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -6565,18 +6565,22 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, struct igb_adapter *adapter =3D netdev_priv(tx_ring->netdev); unsigned long flags; =20 + /* A timestamp that was requested while Tx timestamping was + * not enabled can never be delivered, it is not "skipped". + */ spin_lock_irqsave(&adapter->ptp_tx_lock, flags); - if (adapter->tstamp_config.tx_type =3D=3D HWTSTAMP_TX_ON && - !adapter->ptp_tx_skb) { - skb_shinfo(skb)->tx_flags |=3D SKBTX_IN_PROGRESS; - tx_flags |=3D IGB_TX_FLAGS_TSTAMP; - - adapter->ptp_tx_skb =3D skb_get(skb); - adapter->ptp_tx_start =3D jiffies; - if (adapter->hw.mac.type =3D=3D e1000_82576) - schedule_work(&adapter->ptp_tx_work); - } else { - adapter->tx_hwtstamp_skipped++; + if (adapter->tstamp_config.tx_type =3D=3D HWTSTAMP_TX_ON) { + if (!adapter->ptp_tx_skb) { + skb_shinfo(skb)->tx_flags |=3D SKBTX_IN_PROGRESS; + tx_flags |=3D IGB_TX_FLAGS_TSTAMP; + + adapter->ptp_tx_skb =3D skb_get(skb); + adapter->ptp_tx_start =3D jiffies; + if (adapter->hw.mac.type =3D=3D e1000_82576) + schedule_work(&adapter->ptp_tx_work); + } else { + adapter->tx_hwtstamp_skipped++; + } } spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); } diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/etherne= t/intel/igb/igb_ptp.c index 3cc05f9198f8..adc7be6a2ee2 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -914,6 +914,9 @@ void igb_ptp_tx_hang(struct igb_adapter *adapter) =20 spin_lock_irqsave(&adapter->ptp_tx_lock, flags); =20 + if (adapter->tstamp_config.tx_type !=3D HWTSTAMP_TX_ON) + goto unlock; + if (!adapter->ptp_tx_skb) goto unlock; =20 @@ -933,19 +936,22 @@ void igb_ptp_tx_hang(struct igb_adapter *adapter) /** * igb_ptp_clear_tx_tstamp - drop a pending Tx timestamp request * @adapter: private network adapter structure + * @disable: whether to disable Tx timestamp admission * * Cancel the timestamp retrieval work and free a pending timestamp skb. * * Context: Must be called in sleepable context with ptp_tx_lock not held; * cancel_work_sync() waits for igb_ptp_tx_work() which takes it. */ -static void igb_ptp_clear_tx_tstamp(struct igb_adapter *adapter) +static void igb_ptp_clear_tx_tstamp(struct igb_adapter *adapter, bool disa= ble) { unsigned long flags; =20 cancel_work_sync(&adapter->ptp_tx_work); =20 spin_lock_irqsave(&adapter->ptp_tx_lock, flags); + if (disable) + adapter->tstamp_config.tx_type =3D HWTSTAMP_TX_OFF; dev_kfree_skb_any(adapter->ptp_tx_skb); adapter->ptp_tx_skb =3D NULL; spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); @@ -1250,6 +1256,13 @@ static int igb_ptp_set_timestamp_mode(struct igb_ada= pter *adapter, regval |=3D tsync_tx_ctl; wr32(E1000_TSYNCTXCTL, regval); =20 + /* Drop a possibly pending Tx timestamp request when disabling Tx + * timestamping. It would otherwise block new requests until it is + * flagged as timed out by the watchdog up to 15 seconds later. + */ + if (!tsync_tx_ctl) + igb_ptp_clear_tx_tstamp(adapter, true); + /* enable/disable RX */ regval =3D rd32(E1000_TSYNCRXCTL); regval &=3D ~(E1000_TSYNCRXCTL_ENABLED | E1000_TSYNCRXCTL_TYPE_MASK); @@ -1310,6 +1323,7 @@ int igb_ptp_hwtstamp_set(struct net_device *netdev, struct netlink_ext_ack *extack) { struct igb_adapter *adapter =3D netdev_priv(netdev); + unsigned long flags; int err; =20 err =3D igb_ptp_set_timestamp_mode(adapter, config); @@ -1317,7 +1331,9 @@ int igb_ptp_hwtstamp_set(struct net_device *netdev, return err; =20 /* save these settings for future reference */ + spin_lock_irqsave(&adapter->ptp_tx_lock, flags); adapter->tstamp_config =3D *config; + spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); =20 return 0; } @@ -1461,7 +1477,7 @@ void igb_ptp_suspend(struct igb_adapter *adapter) if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK) cancel_delayed_work_sync(&adapter->ptp_overflow_work); =20 - igb_ptp_clear_tx_tstamp(adapter); + igb_ptp_clear_tx_tstamp(adapter, false); } =20 /**