git: 84c9f1f3b3bd - stable/15 - iflib: update rs_pending based on descriptors consumed by isc_txd_encap

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Thu, 29 Oct 2026 06:03:13 UTC
The branch stable/15 has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=84c9f1f3b3bd52176e8d2a28ba8453166c9fea1c

commit 84c9f1f3b3bd52176e8d2a28ba8453166c9fea1c
Author:     Andrew Gallatin <gallatin@FreeBSD.org>
AuthorDate: 2026-09-02 17:41:32 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-10-29 05:28:38 +0000

    iflib: update rs_pending based on descriptors consumed by isc_txd_encap
    
    The new watchdog code triggers spurious watchdog resets on
    NICs doing KTLS offload.  Fix this by using the actual segments
    consumed by the NIC driver's isc_txd_encap.
    
    The issue is that rs_pending is updated using an estimate of
    the  descriptors that will be used for the current packet,
    based on what bus_dma produced. However, NICs which support
    ktls offload may do extra  DMAs (and consume extra
    descriptors) to derive crypto state when re-transmitting
    TLS segments.  This is the reason for allowing drivers to control
    ift_pad.  When this happens, the estimated rs_pending may undercount.
    This may also happen if NIC drivers consume extra descriptors for
    other reasons. (eg, hw errata handling on e1000)
    
    Reviewed by: kbowling
    Differential Revision:  https://reviews.freebsd.org/D59321
    Sponsored-by: Netflix
    
    (cherry picked from commit a5bb0fde672271f7a4c5a460ed0cd0282a18ca66)
---
 sys/net/iflib.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index 2829e9992a03..0961c1b2a21f 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -2509,8 +2509,7 @@ iflib_timer(void *arg)
 		 * (ift_processed) nor reclaimed (ift_cleaned accounts
 		 * the difference to ift_in_use).  The tail whose
 		 * report-status request is still deferred is never
-		 * reported and must not count (ift_rs_pending
-		 * over-counts it by one per packet).
+		 * reported and must not count.
 		 */
 		in_use = txq->ift_in_use;
 		outstanding = in_use -
@@ -3851,11 +3850,9 @@ defrag:
 	 * However, this also means that the driver will need to keep track
 	 * of the descriptors that RS was set on to check them for the DD bit.
 	 */
-	txq->ift_rs_pending += nsegs + 1;
-	if (txq->ift_rs_pending > TXQ_MAX_RS_DEFERRED(txq) ||
+	if (txq->ift_rs_pending + nsegs + 1 > TXQ_MAX_RS_DEFERRED(txq) ||
 	    iflib_no_tx_batch || (TXQ_AVAIL(txq) - nsegs) <= MAX_TX_DESC(ctx)) {
 		pi.ipi_flags |= IPI_TX_INTR;
-		txq->ift_rs_pending = 0;
 	}
 
 	pi.ipi_segs = segs;
@@ -3875,6 +3872,11 @@ defrag:
 			ndesc += txq->ift_size;
 			txq->ift_gen = 1;
 		}
+
+		if (pi.ipi_flags & IPI_TX_INTR)
+			txq->ift_rs_pending = 0;
+		else
+			txq->ift_rs_pending += ndesc;
 		/*
 		 * drivers can need up to ift_pad sentinels
 		 */