git: a5bb0fde6722 - main - iflib: update rs_pending based on descriptors consumed by isc_txd_encap

From: Andrew Gallatin <gallatin_at_FreeBSD.org>
Date: Thu, 03 Sep 2026 14:45:55 UTC
The branch main has been updated by gallatin:

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

commit a5bb0fde672271f7a4c5a460ed0cd0282a18ca66
Author:     Andrew Gallatin <gallatin@FreeBSD.org>
AuthorDate: 2026-09-02 17:41:32 +0000
Commit:     Andrew Gallatin <gallatin@FreeBSD.org>
CommitDate: 2026-09-03 14:23:55 +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
---
 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 7a6e817f6073..0c2b03c0b5f3 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -2462,8 +2462,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 -
@@ -3756,11 +3755,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;
@@ -3780,6 +3777,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
 		 */