git: dc00f118405e - main - Revert "virtio_net: Use bus_dma for rxq/txq buffers"

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Tue, 05 May 2026 09:33:17 UTC
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=dc00f118405e8638ceb13b288e14164a8a9ba669

commit dc00f118405e8638ceb13b288e14164a8a9ba669
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2026-05-05 09:17:51 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2026-05-05 09:18:14 +0000

    Revert "virtio_net: Use bus_dma for rxq/txq buffers"
    
    This reverts commit c16c95192f01237a876eb7bc336e3bbda9310171.
    
    Revert until we can fix reported issues
---
 sys/dev/virtio/network/if_vtnet.c    | 275 +++--------------------------------
 sys/dev/virtio/network/if_vtnetvar.h |  10 --
 2 files changed, 17 insertions(+), 268 deletions(-)

diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index e88602a44664..ef01833b9e03 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -96,17 +96,6 @@
 #define VTNET_ETHER_ALIGN ETHER_ALIGN
 #endif
 
-/*
- * Worst case offset to ensure header doesn't share any cache lines with
- * payload.
- */
-#define VTNET_RX_BUFFER_HEADER_OFFSET 128
-
-struct vtnet_rx_buffer_header {
-	bus_addr_t   addr;
-	bus_dmamap_t dmap;
-};
-
 static int	vtnet_modevent(module_t, int, void *);
 
 static int	vtnet_probe(device_t);
@@ -395,17 +384,6 @@ MODULE_DEPEND(vtnet, netmap, 1, 1, 1);
 
 VIRTIO_SIMPLE_PNPINFO(vtnet, VIRTIO_ID_NETWORK, "VirtIO Networking Adapter");
 
-static struct vtnet_rx_buffer_header *
-vtnet_mbuf_to_rx_buffer_header(struct vtnet_softc *sc, struct mbuf *m)
-{
-	if (VTNET_ETHER_ALIGN != 0 && sc->vtnet_hdr_size % 4 == 0)
-		return (struct vtnet_rx_buffer_header *)((uintptr_t)m->m_data -
-		    VTNET_RX_BUFFER_HEADER_OFFSET - VTNET_ETHER_ALIGN);
-	else
-		return (struct vtnet_rx_buffer_header *)((uintptr_t)m->m_data -
-		    VTNET_RX_BUFFER_HEADER_OFFSET);
-}
-
 static int
 vtnet_modevent(module_t mod __unused, int type, void *unused __unused)
 {
@@ -479,60 +457,6 @@ vtnet_attach(device_t dev)
 		goto fail;
 	}
 
-	mtx_init(&sc->vtnet_rx_mtx, device_get_nameunit(dev),
-	    "VirtIO Net RX lock", MTX_DEF);
-
-	error = bus_dma_tag_create(
-	    bus_get_dma_tag(dev),		/* parent */
-	    sizeof(uint16_t),			/* alignment */
-	    0,					/* boundary */
-	    BUS_SPACE_MAXADDR,			/* lowaddr */
-	    BUS_SPACE_MAXADDR,			/* highaddr */
-	    NULL, NULL,				/* filter, filterarg */
-	    MJUM9BYTES,				/* max request size */
-	    1,					/* max # segments */
-	    MJUM9BYTES,				/* maxsegsize - worst case */
-	    BUS_DMA_COHERENT,			/* flags */
-	    busdma_lock_mutex,			/* lockfunc */
-	    &sc->vtnet_rx_mtx,			/* lockarg */
-	    &sc->vtnet_rx_dmat);
-	if (error) {
-		device_printf(dev, "cannot create bus_dma_tag\n");
-		goto fail;
-	}
-
-	mtx_init(&sc->vtnet_tx_mtx, device_get_nameunit(dev),
-	    "VirtIO Net TX lock", MTX_DEF);
-
-	error = bus_dma_tag_create(
-	    bus_get_dma_tag(dev),		/* parent */
-	    sizeof(uint16_t),			/* alignment */
-	    0,					/* boundary */
-	    BUS_SPACE_MAXADDR,			/* lowaddr */
-	    BUS_SPACE_MAXADDR,			/* highaddr */
-	    NULL, NULL,				/* filter, filterarg */
-	    sc->vtnet_tx_nsegs * MJUM9BYTES,	/* max request size */
-	    sc->vtnet_tx_nsegs,			/* max # segments */
-	    MJUM9BYTES,				/* maxsegsize */
-	    BUS_DMA_COHERENT,			/* flags */
-	    busdma_lock_mutex,			/* lockfunc */
-	    &sc->vtnet_tx_mtx,			/* lockarg */
-	    &sc->vtnet_tx_dmat);
-	if (error) {
-		device_printf(dev, "cannot create bus_dma_tag\n");
-		goto fail;
-	}
-
-#ifdef __powerpc__
-        /*
-         * Virtio uses physical addresses rather than bus addresses, so we
-         * need to ask busdma to skip the iommu physical->bus mapping.  At
-         * present, this is only a thing on the powerpc architectures.
-         */
-        bus_dma_tag_set_iommu(sc->vtnet_rx_dmat, NULL, NULL);
-        bus_dma_tag_set_iommu(sc->vtnet_tx_dmat, NULL, NULL);
-#endif
-
 	error = vtnet_alloc_rx_filters(sc);
 	if (error) {
 		device_printf(dev, "cannot allocate Rx filters\n");
@@ -1621,11 +1545,6 @@ static struct mbuf *
 vtnet_rx_alloc_buf(struct vtnet_softc *sc, int nbufs, struct mbuf **m_tailp)
 {
 	struct mbuf *m_head, *m_tail, *m;
-	struct vtnet_rx_buffer_header *vthdr;
-	bus_dma_segment_t segs[1];
-	bus_dmamap_t dmap;
-	int nsegs;
-	int err;
 	int i, size;
 
 	m_head = NULL;
@@ -1643,43 +1562,13 @@ vtnet_rx_alloc_buf(struct vtnet_softc *sc, int nbufs, struct mbuf **m_tailp)
 		}
 
 		m->m_len = size;
-		vthdr = (struct vtnet_rx_buffer_header *)m->m_data;
-
-		/* Reserve space for header */
-		m_adj(m, VTNET_RX_BUFFER_HEADER_OFFSET);
-
 		/*
 		 * Need to offset the mbuf if the header we're going to add
 		 * will misalign.
 		 */
-		if (VTNET_ETHER_ALIGN != 0 && sc->vtnet_hdr_size % 4 == 0)
+		if (VTNET_ETHER_ALIGN != 0 && sc->vtnet_hdr_size % 4 == 0) {
 			m_adj(m, VTNET_ETHER_ALIGN);
-
-		err = bus_dmamap_create(sc->vtnet_rx_dmat, 0, &dmap);
-		if (err) {
-			printf("Failed to create dmamap, err :%d\n",
-			    err);
-			m_freem(m);
-			return (NULL);
 		}
-
-		nsegs = 0;
-		err = bus_dmamap_load_mbuf_sg(sc->vtnet_rx_dmat, dmap, m, segs,
-		    &nsegs, BUS_DMA_NOWAIT);
-		if (err != 0) {
-			printf("Failed to map mbuf into DMA visible memory, err: %d\n",
-			    err);
-			m_freem(m);
-			bus_dmamap_destroy(sc->vtnet_rx_dmat, dmap);
-			return (NULL);
-		}
-		KASSERT(nsegs == 1,
-		    ("%s: unexpected number of DMA segments for rx buffer: %d",
-		    __func__, nsegs));
-
-		vthdr->addr = segs[0].ds_addr;
-		vthdr->dmap = dmap;
-
 		if (m_head != NULL) {
 			m_tail->m_next = m;
 			m_tail = m;
@@ -1705,7 +1594,7 @@ vtnet_rxq_replace_lro_nomrg_buf(struct vtnet_rxq *rxq, struct mbuf *m0,
 	int len, clustersz, nreplace, error;
 
 	sc = rxq->vtnrx_sc;
-	clustersz = sc->vtnet_rx_clustersz - VTNET_RX_BUFFER_HEADER_OFFSET;
+	clustersz = sc->vtnet_rx_clustersz;
 	/*
 	 * Need to offset the mbuf if the header we're going to add will
 	 * misalign, account for that here.
@@ -1820,12 +1709,9 @@ vtnet_rxq_replace_buf(struct vtnet_rxq *rxq, struct mbuf *m, int len)
 static int
 vtnet_rxq_enqueue_buf(struct vtnet_rxq *rxq, struct mbuf *m)
 {
-	struct vtnet_rx_buffer_header *hdr;
 	struct vtnet_softc *sc;
 	struct sglist *sg;
 	int header_inlined, error;
-	bus_addr_t paddr;
-	struct mbuf *mp;
 
 	sc = rxq->vtnrx_sc;
 	sg = rxq->vtnrx_sg;
@@ -1838,38 +1724,28 @@ 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 */
 
-	hdr = vtnet_mbuf_to_rx_buffer_header(sc, m);
-	paddr = hdr->addr;
-
 	/*
 	 * Note: The mbuf has been already adjusted when we allocate it if we
 	 * have to do strict alignment.
 	 */
-	if (header_inlined) {
-		error = sglist_append_phys(sg, paddr, m->m_len);
-	} else {
+	if (header_inlined)
+		error = sglist_append_mbuf(sg, m);
+	else {
+		struct vtnet_rx_header *rxhdr =
+		    mtod(m, struct vtnet_rx_header *);
 		MPASS(sc->vtnet_hdr_size == sizeof(struct virtio_net_hdr));
 
 		/* Append the header and remaining mbuf data. */
-		error = sglist_append_phys(sg, paddr, sc->vtnet_hdr_size);
+		error = sglist_append(sg, &rxhdr->vrh_hdr, sc->vtnet_hdr_size);
 		if (error)
 			return (error);
-		error = sglist_append_phys(sg,
-		    paddr + sizeof(struct vtnet_rx_header),
+		error = sglist_append(sg, &rxhdr[1],
 		    m->m_len - sizeof(struct vtnet_rx_header));
 		if (error)
 			return (error);
 
-		mp = m->m_next;
-		while (mp) {
-			hdr = vtnet_mbuf_to_rx_buffer_header(sc, mp);
-			paddr = hdr->addr;
-			error = sglist_append_phys(sg, paddr, mp->m_len);
-			if (error)
-				return (error);
-
-			mp = mp->m_next;
-		}
+		if (m->m_next != NULL)
+			error = sglist_append_mbuf(sg, m->m_next);
 	}
 
 	if (error)
@@ -2055,7 +1931,6 @@ vtnet_rxq_merged_eof(struct vtnet_rxq *rxq, struct mbuf *m_head, int nbufs)
 	m_tail = m_head;
 
 	while (--nbufs > 0) {
-		struct vtnet_rx_buffer_header *vthdr;
 		struct mbuf *m;
 		uint32_t len;
 
@@ -2065,10 +1940,6 @@ vtnet_rxq_merged_eof(struct vtnet_rxq *rxq, struct mbuf *m_head, int nbufs)
 			goto fail;
 		}
 
-		vthdr = vtnet_mbuf_to_rx_buffer_header(sc, m);
-		bus_dmamap_sync(sc->vtnet_rx_dmat, vthdr->dmap,
-		    BUS_DMASYNC_POSTREAD);
-
 		if (vtnet_rxq_new_buf(rxq) != 0) {
 			rxq->vtnrx_stats.vrxs_iqdrops++;
 			vtnet_rxq_discard_buf(rxq, m);
@@ -2189,7 +2060,6 @@ static int
 vtnet_rxq_eof(struct vtnet_rxq *rxq)
 {
 	struct virtio_net_hdr lhdr, *hdr;
-	struct vtnet_rx_buffer_header *vthdr;
 	struct vtnet_softc *sc;
 	if_t ifp;
 	struct virtqueue *vq;
@@ -2205,31 +2075,14 @@ vtnet_rxq_eof(struct vtnet_rxq *rxq)
 
 	CURVNET_SET(if_getvnet(ifp));
 	while (count-- > 0) {
-		struct mbuf *m, *mp;
+		struct mbuf *m;
 		uint32_t len, nbufs, adjsz;
-		uint32_t synced;
 
 		m = virtqueue_dequeue(vq, &len);
 		if (m == NULL)
 			break;
 		deq++;
 
-		mp = m;
-
-		/*
-		 * Sync all mbufs in this packet. There will only be a single
-		 * mbuf unless LRO is in use.
-		 */
-		synced = 0;
-		while (mp && synced < len) {
-			vthdr = vtnet_mbuf_to_rx_buffer_header(sc, mp);
-			bus_dmamap_sync(sc->vtnet_rx_dmat, vthdr->dmap,
-			    BUS_DMASYNC_POSTREAD);
-
-			synced += mp->m_len;
-			mp = mp->m_next;
-		}
-
 		if (len < sc->vtnet_hdr_size + ETHER_HDR_LEN) {
 			rxq->vtnrx_stats.vrxs_ierrors++;
 			vtnet_rxq_discard_buf(rxq, m);
@@ -2489,14 +2342,6 @@ vtnet_txq_free_mbufs(struct vtnet_txq *txq)
 
 	while ((txhdr = virtqueue_drain(vq, &last)) != NULL) {
 		if (kring == NULL) {
-			bus_dmamap_unload(txq->vtntx_sc->vtnet_tx_dmat,
-			    txhdr->dmap);
-			bus_dmamap_destroy(txq->vtntx_sc->vtnet_tx_dmat,
-			    txhdr->dmap);
-			bus_dmamap_unload(txq->vtntx_sc->vtnet_tx_dmat,
-			    txhdr->hdr_dmap);
-			bus_dmamap_destroy(txq->vtntx_sc->vtnet_tx_dmat,
-			    txhdr->hdr_dmap);
 			m_freem(txhdr->vth_mbuf);
 			uma_zfree(vtnet_tx_header_zone, txhdr);
 		}
@@ -2666,36 +2511,15 @@ drop:
 	return (NULL);
 }
 
-static void
-vtnet_txq_enqueue_callback(void *arg, bus_dma_segment_t *segs,
-    int nsegs, int error)
-{
-	vm_paddr_t *hdr_paddr;
-
-	if (error != 0)
-		return;
-
-	KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
-
-	hdr_paddr = (vm_paddr_t *)arg;
-	*hdr_paddr = segs[0].ds_addr;
-}
-
 static int
 vtnet_txq_enqueue_buf(struct vtnet_txq *txq, struct mbuf **m_head,
     struct vtnet_tx_header *txhdr)
 {
-	bus_dma_segment_t segs[VTNET_TX_SEGS_MAX];
-	int nsegs;
 	struct vtnet_softc *sc;
 	struct virtqueue *vq;
 	struct sglist *sg;
 	struct mbuf *m;
 	int error;
-	vm_paddr_t hdr_paddr;
-	bus_dmamap_t hdr_dmap;
-	bus_dmamap_t dmap;
-	int i;
 
 	sc = txq->vtntx_sc;
 	vq = txq->vtntx_vq;
@@ -2703,55 +2527,15 @@ vtnet_txq_enqueue_buf(struct vtnet_txq *txq, struct mbuf **m_head,
 	m = *m_head;
 
 	sglist_reset(sg);
-
-	error = bus_dmamap_create(sc->vtnet_tx_dmat, 0, &hdr_dmap);
-	if (error)
-	    goto fail;
-
-	error = bus_dmamap_load(sc->vtnet_tx_dmat, hdr_dmap, &txhdr->vth_uhdr,
-	    sc->vtnet_hdr_size, vtnet_txq_enqueue_callback, &hdr_paddr,
-	    BUS_DMA_NOWAIT);
-	if (error)
-		goto fail_hdr_dmamap_destroy;
-
-	error = sglist_append_phys(sg, hdr_paddr, sc->vtnet_hdr_size);
+	error = sglist_append(sg, &txhdr->vth_uhdr, sc->vtnet_hdr_size);
 	if (error != 0 || sg->sg_nseg != 1) {
 		KASSERT(0, ("%s: cannot add header to sglist error %d nseg %d",
 		    __func__, error, sg->sg_nseg));
-		goto fail_hdr_dmamap_unload;
+		goto fail;
 	}
 
-	bus_dmamap_sync(sc->vtnet_tx_dmat, hdr_dmap, BUS_DMASYNC_PREWRITE);
-
-	error = bus_dmamap_create(sc->vtnet_tx_dmat, 0, &dmap);
-	if (error)
-		goto fail_hdr_dmamap_unload;
-
-	nsegs = 0;
-	error = bus_dmamap_load_mbuf_sg(sc->vtnet_tx_dmat, dmap, m, segs,
-	    &nsegs, BUS_DMA_NOWAIT);
-	if (error != 0)
-		goto fail_dmamap_destroy;
-	KASSERT(nsegs <= sc->vtnet_tx_nsegs,
-	    ("%s: unexpected number of DMA segments for tx buffer: %d (max %d)",
-	    __func__, nsegs, sc->vtnet_tx_nsegs));
-
-	bus_dmamap_sync(sc->vtnet_tx_dmat, dmap, BUS_DMASYNC_PREWRITE);
-
-	for (i = 0; i < nsegs && !error; i++)
-		error = sglist_append_phys(sg, segs[i].ds_addr, segs[i].ds_len);
-
+	error = sglist_append_mbuf(sg, m);
 	if (error) {
-		sglist_reset(sg);
-		bus_dmamap_unload(sc->vtnet_tx_dmat, dmap);
-
-		error = sglist_append_phys(sg, hdr_paddr, sc->vtnet_hdr_size);
-		if (error != 0 || sg->sg_nseg != 1) {
-			KASSERT(0, ("%s: cannot add header to sglist error %d nseg %d",
-			    __func__, error, sg->sg_nseg));
-			goto fail_dmamap_destroy;
-		}
-
 		m = m_defrag(m, M_NOWAIT);
 		if (m == NULL) {
 			sc->vtnet_stats.tx_defrag_failed++;
@@ -2761,41 +2545,16 @@ vtnet_txq_enqueue_buf(struct vtnet_txq *txq, struct mbuf **m_head,
 		*m_head = m;
 		sc->vtnet_stats.tx_defragged++;
 
-		nsegs = 0;
-		error = bus_dmamap_load_mbuf_sg(sc->vtnet_tx_dmat, dmap, m,
-		    segs, &nsegs, BUS_DMA_NOWAIT);
-		if (error != 0)
-			goto fail_dmamap_destroy;
-		KASSERT(nsegs <= sc->vtnet_tx_nsegs,
-		    ("%s: unexpected number of DMA segments for tx buffer: %d (max %d)",
-		    __func__, nsegs, sc->vtnet_tx_nsegs));
-
-		bus_dmamap_sync(sc->vtnet_tx_dmat, dmap, BUS_DMASYNC_PREWRITE);
-
-		for (i = 0; i < nsegs && !error; i++)
-			error = sglist_append_phys(sg, segs[i].ds_addr,
-			    segs[i].ds_len);
-
+		error = sglist_append_mbuf(sg, m);
 		if (error)
-			goto fail_dmamap_unload;
+			goto fail;
 	}
 
 	txhdr->vth_mbuf = m;
-	txhdr->dmap = dmap;
-	txhdr->hdr_dmap = hdr_dmap;
-
 	error = virtqueue_enqueue(vq, txhdr, sg, sg->sg_nseg, 0);
 
 	return (error);
 
-fail_dmamap_unload:
-	bus_dmamap_unload(sc->vtnet_tx_dmat, dmap);
-fail_dmamap_destroy:
-	bus_dmamap_destroy(sc->vtnet_tx_dmat, dmap);
-fail_hdr_dmamap_unload:
-	bus_dmamap_unload(sc->vtnet_tx_dmat, hdr_dmap);
-fail_hdr_dmamap_destroy:
-	bus_dmamap_destroy(sc->vtnet_tx_dmat, hdr_dmap);
 fail:
 	m_freem(*m_head);
 	*m_head = NULL;
diff --git a/sys/dev/virtio/network/if_vtnetvar.h b/sys/dev/virtio/network/if_vtnetvar.h
index 6cafe827d733..eb5e6784b07f 100644
--- a/sys/dev/virtio/network/if_vtnetvar.h
+++ b/sys/dev/virtio/network/if_vtnetvar.h
@@ -190,12 +190,6 @@ struct vtnet_softc {
 	struct mtx		 vtnet_mtx;
 	char			 vtnet_mtx_name[16];
 	uint8_t			 vtnet_hwaddr[ETHER_ADDR_LEN];
-
-	bus_dma_tag_t		 vtnet_rx_dmat;
-	struct mtx		 vtnet_rx_mtx;
-
-	bus_dma_tag_t		 vtnet_tx_dmat;
-	struct mtx		 vtnet_tx_mtx;
 };
 /* vtnet flag descriptions for use with printf(9) %b identifier. */
 #define VTNET_FLAGS_BITS \
@@ -279,10 +273,6 @@ struct vtnet_tx_header {
 	} vth_uhdr;
 
 	struct mbuf *vth_mbuf;
-
-	bus_dmamap_t dmap;
-
-	bus_dmamap_t hdr_dmap;
 };
 
 /*