git: 6b02c24b33df - stable/15 - ixl: Honor iflib transmit completion batching

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Mon, 24 Aug 2026 00:53:30 UTC
The branch stable/15 has been updated by kbowling:

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

commit 6b02c24b33df53ffa9b5fe45e676261a2c305232
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-10 07:31:48 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-24 00:44:57 +0000

    ixl: Honor iflib transmit completion batching
    
    ixl uses head writeback by default.  Hardware publishes the transmit
    ring head through DMA only after completing a descriptor marked RS.
    Marking every packet requested much more frequent head updates than
    iflib needs to reclaim descriptors.
    
    iflib marks selected packets with IPI_TX_INTR as completion
    checkpoints.  It forces a checkpoint as deferred work or ring pressure
    grows.  Retain EOP on every packet, but set RS only at those
    checkpoints.  This batches head writebacks while preserving bounded
    descriptor reclamation.
    
    The optional descriptor writeback mode benefits as well.  ixl already
    recorded only IPI_TX_INTR descriptors in its report-status queue, so
    status written for every other packet was not inspected.
    
    DPDK uses the same sparse RS design.  Let iflib choose the adaptive
    interval for FreeBSD.  This is a PCIe/memory bandwidth savings.
    
    (cherry picked from commit dd32931271c784caf2c51e27f24514093b81429c)
---
 sys/dev/ixl/ixl_txrx.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/sys/dev/ixl/ixl_txrx.c b/sys/dev/ixl/ixl_txrx.c
index d5ec81499308..6acf1dfaf009 100644
--- a/sys/dev/ixl/ixl_txrx.c
+++ b/sys/dev/ixl/ixl_txrx.c
@@ -332,8 +332,6 @@ ixl_tso_setup(struct tx_ring *txr, if_pkt_info_t pi)
  *  	- return 0 on success, positive on failure
   *
   **********************************************************************/
-#define IXL_TXD_CMD (I40E_TX_DESC_CMD_EOP | I40E_TX_DESC_CMD_RS)
-
 static int
 ixl_isc_txd_encap(void *arg, if_pkt_info_t pi)
 {
@@ -345,12 +343,15 @@ ixl_isc_txd_encap(void *arg, if_pkt_info_t pi)
 	bus_dma_segment_t *segs = pi->ipi_segs;
 	struct i40e_tx_desc	*txd = NULL;
 	int             	i, j, mask, pidx_last;
-	u32			cmd, off, tx_intr;
+	u32			cmd, off, tx_intr, txd_cmd;
 
 	cmd = off = 0;
 	i = pi->ipi_pidx;
 
 	tx_intr = (pi->ipi_flags & IPI_TX_INTR);
+	txd_cmd = I40E_TX_DESC_CMD_EOP;
+	if (tx_intr)
+		txd_cmd |= I40E_TX_DESC_CMD_RS;
 
 	/* Set up the TSO/CSUM offload */
 	if (pi->ipi_csum_flags & CSUM_OFFLOAD) {
@@ -397,7 +398,7 @@ ixl_isc_txd_encap(void *arg, if_pkt_info_t pi)
 	}
 	/* Set the last descriptor for report */
 	txd->cmd_type_offset_bsz |=
-	    htole64(((u64)IXL_TXD_CMD << I40E_TXD_QW1_CMD_SHIFT));
+	    htole64((u64)txd_cmd << I40E_TXD_QW1_CMD_SHIFT);
 	/* Add to report status array (if using TX interrupts) */
 	if (!vsi->enable_head_writeback && tx_intr) {
 		txr->tx_rsq[txr->tx_rs_pidx] = pidx_last;