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 01:57:39 -0000 @@ -317,7 +317,8 @@ vmxnet3_attach(struct device *parent, st isr = vmxnet3_intr_event; sc->sc_intrmap = intrmap_create(&sc->sc_dev, - msix, VMX_MAX_QUEUES, INTRMAP_POWEROF2); + msix, min(VMX_MAX_QUEUES, net_sn_count()), + INTRMAP_POWEROF2); sc->sc_nqueues = intrmap_count(sc->sc_intrmap); } break; @@ -1628,6 +1629,19 @@ vmxnet3_tx_offload(struct vmxnet3_txdesc m->m_pkthdr.ph_mss - 1) / m->m_pkthdr.ph_mss); } +static inline unsigned int +vmxnet3_txring_free(struct vmxnet3_txring *ring, unsigned int prod) +{ + unsigned int free; + + free = ring->cons; + if (free <= prod) + free += NTXDESC; + free -= prod; + + return (free); +} + void vmxnet3_start(struct ifqueue *ifq) { @@ -1646,11 +1660,8 @@ vmxnet3_start(struct ifqueue *ifq) struct mbuf *m; - free = ring->cons; prod = ring->prod; - if (free <= prod) - free += NTXDESC; - free -= prod; + free = vmxnet3_txring_free(ring, prod); bus_dmamap_sync(sc->sc_dmat, VMX_DMA_MAP(&ring->dmamem), 0, VMX_DMA_LEN(&ring->dmamem), BUS_DMASYNC_POSTWRITE); @@ -1660,8 +1671,13 @@ vmxnet3_start(struct ifqueue *ifq) for (;;) { int hdrlen; - if (free <= NTXSEGS) - break; + if (free <= NTXSEGS + 1) { + free = vmxnet3_txring_free(ring, prod); + if (free <= NTXSEGS + 1) { + ifq_set_oactive(ifq); + break; + } + } m = ifq_dequeue(ifq); if (m == NULL) @@ -1714,10 +1730,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]; @@ -1739,7 +1751,9 @@ vmxnet3_start(struct ifqueue *ifq) vmxnet3_tx_offload(sop, m); + free -= map->dm_nsegs; ring->prod = prod; + /* 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),