git: 072e0983d7bc - main - e1000: count TSO wire segments in the AIM counters

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a655c57.32e3a.4118efce__32030.747264956$1785027739$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by kbowling:

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

commit 072e0983d7bce80356740324973993393e77023a
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-07-25 12:33:38 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-07-26 01:00:02 +0000

    e1000: count TSO wire segments in the AIM counters
    
    The transmit paths billed one packet of ipi_len bytes per request.  For
    TSO that is the whole unsegmented payload, up to 64KB, so the average
    size the moderation calculation sees is not a size that appears on the
    wire.
    
    Count the segments the hardware will put on the wire and the header each
    of them carries.
    
    Non-TSO accounting is unchanged.
    
    MFC after:      1 week
---
 sys/dev/e1000/em_txrx.c  | 21 +++++++++++++++++++--
 sys/dev/e1000/igb_txrx.c | 21 +++++++++++++++++++--
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/sys/dev/e1000/em_txrx.c b/sys/dev/e1000/em_txrx.c
index 6ac41816b043..b2a515027479 100644
--- a/sys/dev/e1000/em_txrx.c
+++ b/sys/dev/e1000/em_txrx.c
@@ -461,10 +461,27 @@ em_isc_txd_encap(void *arg, if_pkt_info_t pi)
 	    first, pidx_last, i);
 	pi->ipi_new_pidx = i;
 
-	/* Sent data accounting for AIM */
+	/*
+	 * Sent data accounting for AIM.  For TSO, ipi_len is the whole
+	 * unsegmented payload, which is not a size the moderation
+	 * calculation can use.  Count the segments the hardware will put on
+	 * the wire and the header each of them carries, so that the average
+	 * it sees is a wire packet.
+	 */
+	if (do_tso && pi->ipi_tso_segsz != 0) {
+		u32 hdrlen, segs;
+
+		hdrlen = pi->ipi_ehdrlen + pi->ipi_ip_hlen + pi->ipi_tcp_hlen;
+		if (pi->ipi_len > hdrlen) {
+			segs = howmany(pi->ipi_len - hdrlen, pi->ipi_tso_segsz);
+			txr->tx_bytes += pi->ipi_len + (segs - 1) * hdrlen;
+			txr->tx_packets += segs;
+			return (0);
+		}
+	}
+
 	txr->tx_bytes += pi->ipi_len;
 	++txr->tx_packets;
-
 	return (0);
 }
 
diff --git a/sys/dev/e1000/igb_txrx.c b/sys/dev/e1000/igb_txrx.c
index f6f462cfd577..57f098d2266d 100644
--- a/sys/dev/e1000/igb_txrx.c
+++ b/sys/dev/e1000/igb_txrx.c
@@ -289,10 +289,27 @@ igb_isc_txd_encap(void *arg, if_pkt_info_t pi)
 	txd->read.cmd_type_len |= htole32(E1000_TXD_CMD_EOP | txd_flags);
 	pi->ipi_new_pidx = i;
 
-	/* Sent data accounting for AIM */
+	/*
+	 * Sent data accounting for AIM.  For TSO, ipi_len is the whole
+	 * unsegmented payload, which is not a size the moderation calculation
+	 * can use.  Count the segments the hardware will put on the wire and
+	 * the header each of them carries, so that the average it sees is a
+	 * wire packet.
+	 */
+	if ((pi->ipi_csum_flags & CSUM_TSO) && pi->ipi_tso_segsz != 0) {
+		u32 hdrlen, segs;
+
+		hdrlen = pi->ipi_ehdrlen + pi->ipi_ip_hlen + pi->ipi_tcp_hlen;
+		if (pi->ipi_len > hdrlen) {
+			segs = howmany(pi->ipi_len - hdrlen, pi->ipi_tso_segsz);
+			txr->tx_bytes += pi->ipi_len + (segs - 1) * hdrlen;
+			txr->tx_packets += segs;
+			return (0);
+		}
+	}
+
 	txr->tx_bytes += pi->ipi_len;
 	++txr->tx_packets;
-
 	return (0);
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.