Download raw body.
igc(4) tso
On Tue 12/03/2024 16:29, Moritz Buhl wrote:
> The VLAN_HWTAGGING diff works for me.
> Tested with Intel I225-V with PPPoE over VLAN
> and Intel I225-LM with IPv4,6 and TCP,UDP over VLAN.
Great! Anyone willing to OK the VLAN_HWTAGGING diff?
Included with this mail are the TSO bits, which I have been using for
the last 2 weeks on a system with several igc(4) interfaces (Intel
I225-V rev 0x03). System has been running stable.
As stated in one of my previous mails the initial diff resulted in
interfaces locking up. After looking into recent changes in other
network drivers, i.e., ix(4), I found a commit from bluhm@ that does
some sanity checks in ether_extract_headers() with length values to
prevent that invalid values from evil packets get stored into hardware
registers [0]. This commit also touched sys/dev/pci/if_igc.c.
Changing
hdrsize += ext.tcp->th_off << 2;
in the initial diff into
hdrsize += ext.tcphlen;
seems to fix the issue.
Note that this diff should be applied after the VLAN_HWTAGGING diff has
been applied.
[0] https://codeberg.org/OpenBSD/src/commit/e78a66e5775d3e9cf59b16f193be327ae6d56426
diff --git sys/dev/pci/if_igc.c sys/dev/pci/if_igc.c
index 159051d8124..4287706d1d7 100644
--- sys/dev/pci/if_igc.c
+++ sys/dev/pci/if_igc.c
@@ -44,12 +44,16 @@
#include <net/if.h>
#include <net/if_media.h>
+#include <net/route.h>
#include <net/toeplitz.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
#if NBPFILTER > 0
#include <net/bpf.h>
@@ -798,6 +802,7 @@ igc_setup_interface(struct igc_softc *sc)
ifp->if_capabilities |= IFCAP_CSUM_IPv4;
ifp->if_capabilities |= IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
ifp->if_capabilities |= IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6;
+ ifp->if_capabilities |= IFCAP_TSOv4 | IFCAP_TSOv6;
/* Initialize ifmedia structures. */
ifmedia_init(&sc->media, IFM_IMASK, igc_media_change, igc_media_status);
@@ -995,8 +1000,6 @@ igc_start(struct ifqueue *ifq)
continue;
}
- olinfo_status = m->m_pkthdr.len << IGC_ADVTXD_PAYLEN_SHIFT;
-
bus_dmamap_sync(txr->txdma.dma_tag, map, 0,
map->dm_mapsize, BUS_DMASYNC_PREWRITE);
@@ -1009,6 +1012,9 @@ igc_start(struct ifqueue *ifq)
prod++;
prod &= mask;
free--;
+ } else {
+ olinfo_status =
+ m->m_pkthdr.len << IGC_ADVTXD_PAYLEN_SHIFT;
}
for (i = 0; i < map->dm_nsegs; i++) {
@@ -2023,12 +2029,15 @@ igc_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, int prod,
{
struct ether_extracted ext;
struct igc_adv_tx_context_desc *txdesc;
+ uint32_t mss_l4len_idx = 0;
uint32_t type_tucmd_mlhl = 0;
uint32_t vlan_macip_lens = 0;
int off = 0;
- ether_extract_headers(mp, &ext);
- vlan_macip_lens |= (sizeof(*ext.eh) << IGC_ADVTXD_MACLEN_SHIFT);
+ if (mp->m_pkthdr.csum_flags & M_TCP_TSO)
+ *olinfo_status = 0;
+ else
+ *olinfo_status = mp->m_pkthdr.len << IGC_ADVTXD_PAYLEN_SHIFT;
/*
* In advanced descriptors the vlan tag must
@@ -2044,6 +2053,10 @@ igc_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, int prod,
}
#endif
+ ether_extract_headers(mp, &ext);
+
+ vlan_macip_lens |= (sizeof(*ext.eh) << IGC_ADVTXD_MACLEN_SHIFT);
+
if (ext.ip4) {
type_tucmd_mlhl |= IGC_ADVTXD_TUCMD_IPV4;
if (ISSET(mp->m_pkthdr.csum_flags, M_IPV4_CSUM_OUT)) {
@@ -2054,6 +2067,9 @@ igc_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, int prod,
} else if (ext.ip6) {
type_tucmd_mlhl |= IGC_ADVTXD_TUCMD_IPV6;
#endif
+ } else {
+ if (mp->m_pkthdr.csum_flags & M_TCP_TSO)
+ tcpstat_inc(tcps_outbadtso);
}
vlan_macip_lens |= ext.iphlen;
@@ -2073,6 +2089,29 @@ igc_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, int prod,
}
}
+ if (mp->m_pkthdr.csum_flags & M_TCP_TSO) {
+ if (ext.tcp) {
+ uint32_t hdrlen, thlen, paylen, outlen;
+
+ thlen = ext.tcphlen;
+
+ outlen = mp->m_pkthdr.ph_mss;
+ mss_l4len_idx |= outlen << IGC_ADVTXD_MSS_SHIFT;
+ mss_l4len_idx |= thlen << IGC_ADVTXD_L4LEN_SHIFT;
+
+ hdrlen = sizeof(*ext.eh) + ext.iphlen + thlen;
+ paylen = mp->m_pkthdr.len - hdrlen;
+ *olinfo_status |= paylen << IGC_ADVTXD_PAYLEN_SHIFT;
+
+ *cmd_type_len |= IGC_ADVTXD_DCMD_TSE;
+ off = 1;
+
+ tcpstat_add(tcps_outpkttso,
+ (paylen + outlen - 1) / outlen);
+ } else
+ tcpstat_inc(tcps_outbadtso);
+ }
+
if (off == 0)
return 0;
@@ -2083,7 +2122,7 @@ igc_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, int prod,
htolem32(&txdesc->vlan_macip_lens, vlan_macip_lens);
htolem32(&txdesc->type_tucmd_mlhl, type_tucmd_mlhl);
htolem32(&txdesc->seqnum_seed, 0);
- htolem32(&txdesc->mss_l4len_idx, 0);
+ htolem32(&txdesc->mss_l4len_idx, mss_l4len_idx);
return 1;
}
igc(4) tso