From: Alexander Bluhm Subject: names for TSO and LRO To: tech@openbsd.org Date: Wed, 16 Apr 2025 23:39:21 +0200 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");