On Thu, May 18, 2023 at 12:01:44AM +0200, Alexander Bluhm wrote: > On Tue, May 16, 2023 at 09:11:48PM +0200, Jan Klemkow wrote: > > @@ -412,6 +412,10 @@ tcp_stats(char *name) > > 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_inhwlro, "\t\t%u input LRO generated packet%s from hardware\n"); > > + p(tcps_inpktlro, "\t\t%u input LRO coalesced packet%s from hardware\n"); > > ... coalesced packet%s by hardware
done > > + p(tcps_inbadlro, "\t\t%u input bad LRO packet%s from hardware\n"); > > + > > Move this down to the "packets received" section. You included it > in "packets sent". done > > + /* > > + * This function iterates over interleaved descriptors. > > + * Thus, we reuse ph_mss as global segment counter per > > + * TCP connection, insteat of introducing a new variable > > s/insteat/instead/ done ok? Thanks, Jan diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index 4119a2416dc..924a6d63236 100644 --- a/sys/dev/pci/if_ix.c +++ b/sys/dev/pci/if_ix.c @@ -3214,12 +3214,23 @@ ixgbe_rxeof(struct rx_ring *rxr) sendmp = rxbuf->fmp; rxbuf->buf = rxbuf->fmp = NULL; - if (sendmp != NULL) /* secondary frag */ + if (sendmp != NULL) { /* secondary frag */ sendmp->m_pkthdr.len += mp->m_len; - else { + + /* + * This function iterates over interleaved descriptors. + * Thus, we reuse ph_mss as global segment counter per + * TCP connection, instead of introducing a new variable + * in m_pkthdr. + */ + if (rsccnt) + sendmp->m_pkthdr.ph_mss += rsccnt - 1; + } else { /* first desc of a non-ps chain */ sendmp = mp; sendmp->m_pkthdr.len = mp->m_len; + if (rsccnt) + sendmp->m_pkthdr.ph_mss = rsccnt - 1; #if NVLAN > 0 if (sc->vlan_stripping && staterr & IXGBE_RXD_STAT_VP) { sendmp->m_pkthdr.ether_vtag = vtag; @@ -3241,6 +3252,21 @@ ixgbe_rxeof(struct rx_ring *rxr) SET(sendmp->m_pkthdr.csum_flags, M_FLOWID); } + if (sendmp->m_pkthdr.ph_mss == 1) + sendmp->m_pkthdr.ph_mss = 0; + + if (sendmp->m_pkthdr.ph_mss > 0) { + struct ether_extracted ext; + uint16_t pkts = sendmp->m_pkthdr.ph_mss; + + ether_extract_headers(sendmp, &ext); + if (ext.tcp) + tcpstat_inc(tcps_inhwlro); + else + tcpstat_inc(tcps_inbadlro); + tcpstat_add(tcps_inpktlro, pkts); + } + ml_enqueue(&ml, sendmp); } next_desc: diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 120e3cc5ea7..3970636cde1 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1340,6 +1340,9 @@ tcp_sysctl_tcpstat(void *oldp, size_t *oldlenp, void *newp) ASSIGN(tcps_outhwtso); ASSIGN(tcps_outpkttso); ASSIGN(tcps_outbadtso); + ASSIGN(tcps_inhwlro); + ASSIGN(tcps_inpktlro); + ASSIGN(tcps_inbadlro); #undef ASSIGN diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 0a9630d719f..e706fedd0e7 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -447,6 +447,9 @@ struct tcpstat { u_int32_t tcps_outhwtso; /* output tso processed by hardware */ u_int32_t tcps_outpkttso; /* packets generated by tso */ u_int32_t tcps_outbadtso; /* output tso failed, packet dropped */ + u_int32_t tcps_inhwlro; /* input lro from hardware */ + u_int32_t tcps_inpktlro; /* packets coalessed by hardware lro */ + u_int32_t tcps_inbadlro; /* input bad lro packets from hardware */ }; /* @@ -625,6 +628,9 @@ enum tcpstat_counters { tcps_outhwtso, tcps_outpkttso, tcps_outbadtso, + tcps_inhwlro, + tcps_inpktlro, + tcps_inbadlro, tcps_ncounters, }; diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index e04355ed078..6db14673b97 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -439,6 +439,9 @@ tcp_stats(char *name) p(tcps_inswcsum, "\t\t%u packet%s software-checksummed\n"); 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_inhwlro, "\t\t%u input LRO generated packet%s by hardware\n"); + p(tcps_inpktlro, "\t\t%u input LRO coalesced packet%s by hardware\n"); + p(tcps_inbadlro, "\t\t%u input bad LRO packet%s from hardware\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");