aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2024-01-29 05:08:55 +0000
committerWarner Losh <imp@FreeBSD.org>2024-02-19 04:46:43 +0000
commit778eb6e1f6668864a6eddd2f6f9bcc2aa26344f3 (patch)
treed6acf4cb52ff39d5fc1a1ba2d8c490694d1d4936
parent898e02d740741d13a8948cbad4e0d969a768fd30 (diff)
downloadsrc-778eb6e1f6668864a6eddd2f6f9bcc2aa26344f3.tar.gz
src-778eb6e1f6668864a6eddd2f6f9bcc2aa26344f3.zip
vtnet: Adjust for ethernet alignment.
If the header that we add to the packet's size is 0 % 4 and we're strictly aligning, then we need to adjust where we store the header so the packet that follows will have it's struct ip header properly aligned. We do this on allocation (and when we check the length of the mbufs in the lro_nomrg case). We can't just adjust the clustersz in the softc, because it's also used to allocate the mbufs and it needs to be the proper size for that. Since we otherwise use the size of the mbuf (or sometimes the smaller size of the received packet) to compute how much we can buffer, this ensures no overflows. The 2 byte adjustment also does not affect how many packets we can receive in the lro_nomrg case. PR: 271288 Sponsored by: Netflix Reviewed by: bryanv Differential Revision: https://reviews.freebsd.org/D43224 (cherry picked from commit 3be59adbb5a2ae7600d46432d3bc82286e507e95)
-rw-r--r--sys/dev/virtio/network/if_vtnet.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index 9737e964a591..3945826f91a0 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -1545,6 +1545,15 @@ vtnet_rx_alloc_buf(struct vtnet_softc *sc, int nbufs, struct mbuf **m_tailp)
}
m->m_len = size;
+#ifndef __NO_STRICT_ALIGNMENT
+ /*
+ * Need to offset the mbuf if the header we're going to add
+ * will misalign.
+ */
+ if (sc->vtnet_hdr_size % 4 == 0) {
+ m_adj(m, ETHER_ALIGN);
+ }
+#endif
if (m_head != NULL) {
m_tail->m_next = m;
m_tail = m;
@@ -1571,6 +1580,14 @@ vtnet_rxq_replace_lro_nomrg_buf(struct vtnet_rxq *rxq, struct mbuf *m0,
sc = rxq->vtnrx_sc;
clustersz = sc->vtnet_rx_clustersz;
+#ifndef __NO_STRICT_ALIGNMENT
+ /*
+ * Need to offset the mbuf if the header we're going to add will
+ * misalign, account for that here.
+ */
+ if (sc->vtnet_hdr_size % 4 == 0)
+ clustersz -= ETHER_ALIGN;
+#endif
m_prev = NULL;
m_tail = NULL;
@@ -1694,6 +1711,10 @@ vtnet_rxq_enqueue_buf(struct vtnet_rxq *rxq, struct mbuf *m)
header_inlined = vtnet_modern(sc) ||
(sc->vtnet_flags & VTNET_FLAG_MRG_RXBUFS) != 0; /* TODO: ANY_LAYOUT */
+ /*
+ * Note: The mbuf has been already adjusted when we allocate it if we
+ * have to do strict alignment.
+ */
if (header_inlined)
error = sglist_append_mbuf(sg, m);
else {