Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
names for TSO and LRO
To:
tech@openbsd.org
Date:
Wed, 16 Apr 2025 23:39:21 +0200

Download raw body.

Thread
Hi,

Now that we have software LRO, we need consistent naming with TSO.
One is called tcp_softlro and the other tcp_copper.  As claudio@
suggested the descriptive name "copper", I would like to have it
this way for LRO.  tcp_glue_enqueue() came to my mind.

Also the netstat -s description is not quite right anymore.  The
idea is that we have one counter each when we do something in
software, and one for offloading.  The loopback pseudo device it
special, as it just passes large packets.

Here is an expample for lo(4).  Large packets are processed by
device, but no small packets are on the network.

tcp:
        34977 packets sent
                0 output TSO large packets chopped in software
                1486 output TSO large packets to device
                0 output TSO generated packets sent to network
                0 bad TSO packets dropped
        34970 packets received
                0 input LRO generated packets glued in software
                1486 input LRO generated packets from device
                0 input LRO small packets received from network
                0 bad LRO packets dropped

And this is accounted with ixl(4).  TSO is done in hardware, LRO
is software only implementation.

tcp:
        3267132 packets sent
                0 output TSO large packets chopped in software
                4644123 output TSO large packets to device
                57013318 output TSO generated packets sent to network
                0 bad TSO packets dropped
        5962903 packets received
                5663423 input LRO generated packets glued in software
                0 input LRO generated packets from device
                40208598 input LRO small packets received from network
                0 bad LRO packets dropped

ok?

bluhm


Index: sys/dev/pci/if_ixl.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_ixl.c,v
diff -u -p -r1.104 if_ixl.c
--- sys/dev/pci/if_ixl.c	16 Apr 2025 17:17:06 -0000	1.104
+++ sys/dev/pci/if_ixl.c	16 Apr 2025 21:00:15 -0000
@@ -3342,7 +3342,7 @@ ixl_rxeof(struct ixl_softc *sc, struct i
 				if (ISSET(ifp->if_xflags, IFXF_LRO) &&
 				    (ptype == IXL_RX_DESC_PTYPE_MAC_IPV4_TCP ||
 				     ptype == IXL_RX_DESC_PTYPE_MAC_IPV6_TCP))
-					tcp_softlro_enqueue(ifp, &mltcp, m);
+					tcp_glue_enqueue(ifp, &mltcp, m);
 				else
 					ml_enqueue(&ml, m);
 			} else {
Index: sys/net/if.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if.c,v
diff -u -p -r1.729 if.c
--- sys/net/if.c	19 Mar 2025 23:29:49 -0000	1.729
+++ sys/net/if.c	16 Apr 2025 20:39:52 -0000
@@ -824,9 +824,7 @@ if_input_local(struct ifnet *ifp, struct
 		    ISSET(ifp->if_capabilities, IFCAP_TSOv4)) ||
 		    (af == AF_INET6 &&
 		    ISSET(ifp->if_capabilities, IFCAP_TSOv6)))) {
-			tcpstat_inc(tcps_inswlro);
-			tcpstat_add(tcps_inpktlro,
-			    (m->m_pkthdr.len + ifp->if_mtu - 1) / ifp->if_mtu);
+			tcpstat_inc(tcps_inhwlro);
 		} else {
 			tcpstat_inc(tcps_inbadlro);
 			m_freem(m);
Index: sys/netinet/tcp_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
diff -u -p -r1.436 tcp_input.c
--- sys/netinet/tcp_input.c	16 Apr 2025 17:17:06 -0000	1.436
+++ sys/netinet/tcp_input.c	16 Apr 2025 20:58:41 -0000
@@ -4452,7 +4452,7 @@ tcp_softlro(struct mbuf *mhead, struct m
 }
 
 void
-tcp_softlro_enqueue(struct ifnet *ifp, struct mbuf_list *ml, struct mbuf *mtail)
+tcp_glue_enqueue(struct ifnet *ifp, struct mbuf_list *ml, struct mbuf *mtail)
 {
 	struct mbuf *mhead;
 
Index: sys/netinet/tcp_var.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_var.h,v
diff -u -p -r1.187 tcp_var.h
--- sys/netinet/tcp_var.h	16 Apr 2025 17:17:06 -0000	1.187
+++ sys/netinet/tcp_var.h	16 Apr 2025 20:59:06 -0000
@@ -720,7 +720,7 @@ void	 tcp_init(void);
 int	 tcp_input(struct mbuf **, int *, int, int, struct netstack *);
 int	 tcp_mss(struct tcpcb *, int);
 void	 tcp_mss_update(struct tcpcb *);
-void	 tcp_softlro_enqueue(struct ifnet *, struct mbuf_list *, struct mbuf *);
+void	 tcp_glue_enqueue(struct ifnet *, struct mbuf_list *, struct mbuf *);
 u_int	 tcp_hdrsz(struct tcpcb *);
 void	 tcp_mtudisc(struct inpcb *, int);
 void	 tcp_mtudisc_increase(struct inpcb *, int);
Index: usr.bin/netstat/inet.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.bin/netstat/inet.c,v
diff -u -p -r1.183 inet.c
--- usr.bin/netstat/inet.c	12 Aug 2024 06:22:36 -0000	1.183
+++ usr.bin/netstat/inet.c	16 Apr 2025 21:18:39 -0000
@@ -408,10 +408,13 @@ tcp_stats(char *name)
 	p(tcps_sndwinup, "\t\t%u window update packet%s\n");
 	p(tcps_sndctrl, "\t\t%u control packet%s\n");
 	p(tcps_outswcsum, "\t\t%u packet%s software-checksummed\n");
-	p(tcps_outswtso, "\t\t%u output TSO packet%s software chopped\n");
-	p(tcps_outhwtso, "\t\t%u output TSO packet%s hardware processed\n");
-	p(tcps_outpkttso, "\t\t%u output TSO packet%s generated\n");
-	p(tcps_outbadtso, "\t\t%u output TSO packet%s dropped\n");
+	p(tcps_outswtso,
+	    "\t\t%u output TSO large packet%s chopped in software\n");
+	p(tcps_outhwtso,
+	    "\t\t%u output TSO large packet%s to device\n");
+	p(tcps_outpkttso,
+	    "\t\t%u output TSO generated packet%s sent to network\n");
+	p(tcps_outbadtso, "\t\t%u bad TSO packet%s dropped\n");
 	p(tcps_rcvtotal, "\t%u packet%s received\n");
 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%u ack%s (for %llu byte%s)\n");
 	p(tcps_rcvdupack, "\t\t%u duplicate ack%s\n");
@@ -440,11 +443,12 @@ tcp_stats(char *name)
 	p(tcps_rcvbadsig, "\t\t%u bad/missing md5 checksum%s\n");
 	p(tcps_rcvgoodsig, "\t\t%llu good md5 checksum%s\n");
 	p(tcps_inswlro,
-	    "\t\t%u input LRO packet%s passed through pseudo device\n");
-	p(tcps_inhwlro, "\t\t%u input LRO generated packet%s from hardware\n");
+	    "\t\t%u input LRO generated packet%s glued in software\n");
+	p(tcps_inhwlro,
+	    "\t\t%u input LRO generated packet%s from device\n");
 	p(tcps_inpktlro,
-	    "\t\t%u input LRO coalesced packet%s by network device\n");
-	p(tcps_inbadlro, "\t\t%u input bad LRO packet%s dropped\n");
+	    "\t\t%u input LRO small packet%s received from network\n");
+	p(tcps_inbadlro, "\t\t%u bad LRO packet%s dropped\n");
 	p(tcps_connattempt, "\t%u connection request%s\n");
 	p(tcps_accepts, "\t%u connection accept%s\n");
 	p(tcps_connects, "\t%u connection%s established (including accepts)\n");