Module Name: src Committed By: knakahara Date: Wed Jul 24 10:17:52 UTC 2019
Modified Files: src/sys/arch/x86/pci: if_vmx.c Log Message: vmx(4) support if_transmit and Tx multiqueue (2/2). Fix Tx interrupt handler. I tested on ESXi 5.5. TODO: add statistics counters To generate a diff of this commit: cvs rdiff -u -r1.39 -r1.40 src/sys/arch/x86/pci/if_vmx.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/pci/if_vmx.c diff -u src/sys/arch/x86/pci/if_vmx.c:1.39 src/sys/arch/x86/pci/if_vmx.c:1.40 --- src/sys/arch/x86/pci/if_vmx.c:1.39 Wed Jul 24 10:15:23 2019 +++ src/sys/arch/x86/pci/if_vmx.c Wed Jul 24 10:17:52 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_vmx.c,v 1.39 2019/07/24 10:15:23 knakahara Exp $ */ +/* $NetBSD: if_vmx.c,v 1.40 2019/07/24 10:17:52 knakahara Exp $ */ /* $OpenBSD: if_vmx.c,v 1.16 2014/01/22 06:04:17 brad Exp $ */ /* @@ -19,7 +19,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_vmx.c,v 1.39 2019/07/24 10:15:23 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_vmx.c,v 1.40 2019/07/24 10:17:52 knakahara Exp $"); #include <sys/param.h> #include <sys/cpu.h> @@ -105,6 +105,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_vmx.c,v 1 mutex_owned((_rxq)->vxrxq_mtx) #define VMXNET3_TXQ_LOCK(_txq) mutex_enter((_txq)->vxtxq_mtx) +#define VMXNET3_TXQ_TRYLOCK(_txq) mutex_tryenter((_txq)->vxtxq_mtx) #define VMXNET3_TXQ_UNLOCK(_txq) mutex_exit((_txq)->vxtxq_mtx) #define VMXNET3_TXQ_LOCK_ASSERT(_txq) \ mutex_owned((_txq)->vxtxq_mtx) @@ -181,6 +182,8 @@ struct vmxnet3_txqueue { struct vmxnet3_txq_stats vxtxq_stats; struct vmxnet3_txq_shared *vxtxq_ts; char vxtxq_name[16]; + + void *vxtxq_si; }; struct vmxnet3_rxq_stats { @@ -375,6 +378,7 @@ void vmxnet3_start_locked(struct ifnet * void vmxnet3_start(struct ifnet *); void vmxnet3_transmit_locked(struct ifnet *, struct vmxnet3_txqueue *); int vmxnet3_transmit(struct ifnet *, struct mbuf *); +void vmxnet3_deferred_transmit(void *); void vmxnet3_set_rxfilter(struct vmxnet3_softc *); int vmxnet3_ioctl(struct ifnet *, u_long, void *); @@ -1059,6 +1063,9 @@ vmxnet3_init_txq(struct vmxnet3_softc *s txq->vxtxq_sc = sc; txq->vxtxq_id = q; + txq->vxtxq_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, + vmxnet3_deferred_transmit, txq); + txr->vxtxr_ndesc = sc->vmx_ntxdescs; txr->vxtxr_txbuf = kmem_zalloc(txr->vxtxr_ndesc * sizeof(struct vmxnet3_txbuf), KM_SLEEP); @@ -1147,6 +1154,8 @@ vmxnet3_destroy_txq(struct vmxnet3_txque txq->vxtxq_sc = NULL; txq->vxtxq_id = -1; + softint_disestablish(txq->vxtxq_si); + while ((m = pcq_get(txq->vxtxq_interq)) != NULL) m_freem(m); pcq_destroy(txq->vxtxq_interq); @@ -2209,7 +2218,10 @@ vmxnet3_txq_intr(void *xtxq) VMXNET3_TXQ_LOCK(txq); vmxnet3_txq_eof(txq); - if_schedule_deferred_start(&sc->vmx_ethercom.ec_if); + /* for ALTQ */ + if (txq->vxtxq_id == 0) + if_schedule_deferred_start(&sc->vmx_ethercom.ec_if); + softint_schedule(txq->vxtxq_si); VMXNET3_TXQ_UNLOCK(txq); vmxnet3_enable_intr(sc, txq->vxtxq_intr_idx); @@ -2880,14 +2892,30 @@ vmxnet3_transmit(struct ifnet *ifp, stru return ENOBUFS; } - VMXNET3_TXQ_LOCK(txq); - vmxnet3_transmit_locked(ifp, txq); - VMXNET3_TXQ_UNLOCK(txq); + if (VMXNET3_TXQ_TRYLOCK(txq)) { + vmxnet3_transmit_locked(ifp, txq); + VMXNET3_TXQ_UNLOCK(txq); + } else { + softint_schedule(txq->vxtxq_si); + } return 0; } void +vmxnet3_deferred_transmit(void *arg) +{ + struct vmxnet3_txqueue *txq = arg; + struct vmxnet3_softc *sc = txq->vxtxq_sc; + struct ifnet *ifp = &sc->vmx_ethercom.ec_if; + + VMXNET3_TXQ_LOCK(txq); + if (pcq_peek(txq->vxtxq_interq) != NULL) + vmxnet3_transmit_locked(ifp, txq); + VMXNET3_TXQ_UNLOCK(txq); +} + +void vmxnet3_set_rxfilter(struct vmxnet3_softc *sc) { struct ifnet *ifp = &sc->vmx_ethercom.ec_if;