Index: if_vmx.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_vmx.c,v diff -u -p -r1.92 if_vmx.c --- if_vmx.c 5 Mar 2025 06:51:25 -0000 1.92 +++ if_vmx.c 15 Jun 2025 09:58:02 -0000 @@ -1635,7 +1635,7 @@ vmxnet3_start(struct ifqueue *ifq) struct vmxnet3_softc *sc = ifp->if_softc; struct vmxnet3_txqueue *tq = ifq->ifq_softc; struct vmxnet3_txring *ring = &tq->cmd_ring; - struct vmxnet3_txdesc *txd, *sop; + struct vmxnet3_txdesc *txd, *sor, *sop; bus_dmamap_t map; unsigned int prod, free, i; unsigned int post = 0; @@ -1656,12 +1656,16 @@ vmxnet3_start(struct ifqueue *ifq) 0, VMX_DMA_LEN(&ring->dmamem), BUS_DMASYNC_POSTWRITE); rgen = ring->gen; + gen = rgen ^ VMX_TX_GEN; + sor = &ring->txd[prod]; for (;;) { int hdrlen; - if (free <= NTXSEGS) + if (free <= NTXSEGS + 1) { + ifq_set_oactive(ifq); break; + } m = ifq_dequeue(ifq); if (m == NULL) @@ -1714,12 +1718,6 @@ vmxnet3_start(struct ifqueue *ifq) bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, BUS_DMASYNC_PREWRITE); - free -= map->dm_nsegs; - /* set oactive here since txintr may be triggered in parallel */ - if (free <= NTXSEGS) - ifq_set_oactive(ifq); - - gen = rgen ^ VMX_TX_GEN; sop = &ring->txd[prod]; for (i = 0; i < map->dm_nsegs; i++) { txd = &ring->txd[prod]; @@ -1739,25 +1737,27 @@ vmxnet3_start(struct ifqueue *ifq) vmxnet3_tx_offload(sop, m); - ring->prod = prod; + free -= map->dm_nsegs; + + post = 1; + } + + if (post) { /* Change the ownership by flipping the "generation" bit */ bus_dmamap_sync(sc->sc_dmat, VMX_DMA_MAP(&ring->dmamem), 0, VMX_DMA_LEN(&ring->dmamem), BUS_DMASYNC_PREWRITE|BUS_DMASYNC_POSTWRITE); - sop->tx_word2 ^= VMX_TX_GEN; + sor->tx_word2 ^= VMX_TX_GEN; - post = 1; + ring->gen = rgen; + ring->prod = prod; } bus_dmamap_sync(sc->sc_dmat, VMX_DMA_MAP(&ring->dmamem), 0, VMX_DMA_LEN(&ring->dmamem), BUS_DMASYNC_PREWRITE); - if (!post) - return; - - ring->gen = rgen; - - WRITE_BAR0(sc, VMXNET3_BAR0_TXH(tq->queue), prod); + if (post) + WRITE_BAR0(sc, VMXNET3_BAR0_TXH(tq->queue), prod); } void