Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x86/pci Join Tx interrupt handler and Rx interrupt ...



details:   https://anonhg.NetBSD.org/src/rev/331d1fbc42f1
branches:  trunk
changeset: 458068:331d1fbc42f1
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Mon Jul 29 02:20:59 2019 +0000

description:
Join Tx interrupt handler and Rx interrupt handler of vmx(4).

That can reduce interrupt resources.

diffstat:

 sys/arch/x86/pci/if_vmx.c |  250 ++++++++++++++++++++-------------------------
 1 files changed, 112 insertions(+), 138 deletions(-)

diffs (truncated from 645 to 300 lines):

diff -r 3306f53c4ae9 -r 331d1fbc42f1 sys/arch/x86/pci/if_vmx.c
--- a/sys/arch/x86/pci/if_vmx.c Mon Jul 29 01:04:20 2019 +0000
+++ b/sys/arch/x86/pci/if_vmx.c Mon Jul 29 02:20:59 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_vmx.c,v 1.40 2019/07/24 10:17:52 knakahara Exp $    */
+/*     $NetBSD: if_vmx.c,v 1.41 2019/07/29 02:20:59 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.40 2019/07/24 10:17:52 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vmx.c,v 1.41 2019/07/29 02:20:59 knakahara Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -173,8 +173,6 @@
 struct vmxnet3_txqueue {
        kmutex_t *vxtxq_mtx;
        struct vmxnet3_softc *vxtxq_sc;
-       int vxtxq_id;
-       int vxtxq_intr_idx;
        int vxtxq_watchdog;
        pcq_t *vxtxq_interq;
        struct vmxnet3_txring vxtxq_cmd_ring;
@@ -196,8 +194,6 @@
 struct vmxnet3_rxqueue {
        kmutex_t *vxrxq_mtx;
        struct vmxnet3_softc *vxrxq_sc;
-       int vxrxq_id;
-       int vxrxq_intr_idx;
        struct mbuf *vxrxq_mhead;
        struct mbuf *vxrxq_mtail;
        struct vmxnet3_rxring vxrxq_cmd_ring[VMXNET3_RXRINGS_PERQ];
@@ -207,6 +203,14 @@
        char vxrxq_name[16];
 };
 
+struct vmxnet3_queue {
+       int vxq_id;
+       int vxq_intr_idx;
+
+       struct vmxnet3_txqueue vxq_txqueue;
+       struct vmxnet3_rxqueue vxq_rxqueue;
+};
+
 struct vmxnet3_statistics {
        uint32_t vmst_defragged;
        uint32_t vmst_defrag_failed;
@@ -224,8 +228,7 @@
 #define VMXNET3_FLAG_RSS       (1 << 1)
 #define VMXNET3_FLAG_ATTACHED  (1 << 2)
 
-       struct vmxnet3_txqueue *vmx_txq;
-       struct vmxnet3_rxqueue *vmx_rxq;
+       struct vmxnet3_queue *vmx_queue;
 
        struct pci_attach_args *vmx_pa;
        pci_chipset_tag_t vmx_pc;
@@ -349,8 +352,7 @@
     struct vmxnet3_rxcompdesc *, struct mbuf *);
 void vmxnet3_rxq_eof(struct vmxnet3_rxqueue *);
 int vmxnet3_legacy_intr(void *);
-int vmxnet3_txq_intr(void *);
-int vmxnet3_rxq_intr(void *);
+int vmxnet3_txrxq_intr(void *);
 int vmxnet3_event_intr(void *);
 
 void vmxnet3_txstop(struct vmxnet3_softc *, struct vmxnet3_txqueue *);
@@ -534,6 +536,7 @@
        struct pci_attach_args *pa = aux;
        pcireg_t preg;
        int error;
+       int candidate;
 
        sc->vmx_dev = self;
        sc->vmx_pa = pa;
@@ -552,10 +555,10 @@
        sc->vmx_mtx = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
        callout_init(&sc->vmx_tick, CALLOUT_MPSAFE);
 
-       sc->vmx_max_ntxqueues =
-           vmxnet3_calc_queue_size(MIN(VMXNET3_MAX_TX_QUEUES, ncpu));
-       sc->vmx_max_nrxqueues =
-           vmxnet3_calc_queue_size(MIN(VMXNET3_MAX_RX_QUEUES, ncpu));
+       candidate = MIN(MIN(VMXNET3_MAX_TX_QUEUES, VMXNET3_MAX_RX_QUEUES),
+           ncpu);
+       sc->vmx_max_ntxqueues = sc->vmx_max_nrxqueues =
+           vmxnet3_calc_queue_size(candidate);
        sc->vmx_ntxdescs = 512;
        sc->vmx_nrxdescs = 256;
        sc->vmx_max_rxsegs = VMXNET3_MAX_RX_SEGS;
@@ -723,7 +726,7 @@
                return (1);
 
        /* Allocate an additional vector for the events interrupt. */
-       required = sc->vmx_max_nrxqueues + sc->vmx_max_ntxqueues + 1;
+       required = MIN(sc->vmx_max_ntxqueues, sc->vmx_max_nrxqueues) + 1;
 
        if (pci_msix_count(pa->pa_pc, pa->pa_tag) < required)
                return (1);
@@ -825,11 +828,10 @@
 vmxnet3_setup_msix_interrupts(struct vmxnet3_softc *sc)
 {
        pci_chipset_tag_t pc = sc->vmx_pa->pa_pc;
-       struct vmxnet3_txqueue *txq;
-       struct vmxnet3_rxqueue *rxq;
+       struct vmxnet3_queue *vmxq;
        pci_intr_handle_t *intr;
        void **ihs;
-       int intr_idx, i;
+       int intr_idx, i, use_queues;
        const char *intrstr;
        char intrbuf[PCI_INTRSTR_LEN];
        char xnamebuf[32];
@@ -838,44 +840,26 @@
        intr_idx = 0;
        ihs = sc->vmx_ihs;
 
-       for (i = 0; i < sc->vmx_ntxqueues; i++, intr++, ihs++, intr_idx++) {
-               snprintf(xnamebuf, 32, "%s: tx %d", device_xname(sc->vmx_dev), i);
-
-               txq = &sc->vmx_txq[i];
+       /* See vmxnet3_alloc_msix_interrupts() */
+       use_queues = MIN(sc->vmx_max_ntxqueues, sc->vmx_max_nrxqueues);
+       for (i = 0; i < use_queues; i++, intr++, ihs++, intr_idx++) {
+               snprintf(xnamebuf, 32, "%s: txrx %d", device_xname(sc->vmx_dev), i);
+
+               vmxq = &sc->vmx_queue[i];
 
                intrstr = pci_intr_string(pc, *intr, intrbuf, sizeof(intrbuf));
 
                pci_intr_setattr(pc, intr, PCI_INTR_MPSAFE, true);
                *ihs = pci_intr_establish_xname(pc, *intr, IPL_NET,
-                   vmxnet3_txq_intr, txq, xnamebuf);
+                   vmxnet3_txrxq_intr, vmxq, xnamebuf);
                if (*ihs == NULL) {
                        aprint_error_dev(sc->vmx_dev,
-                           "unable to establish tx interrupt at %s\n", intrstr);
+                           "unable to establish txrx interrupt at %s\n", intrstr);
                        return (-1);
                }
-               aprint_normal_dev(sc->vmx_dev, "tx interrupting at %s\n", intrstr);
-
-               txq->vxtxq_intr_idx = intr_idx;
-       }
-
-       for (i = 0; i < sc->vmx_nrxqueues; i++, intr++, ihs++, intr_idx++) {
-               snprintf(xnamebuf, 32, "%s: rx %d", device_xname(sc->vmx_dev), i);
-
-               rxq = &sc->vmx_rxq[i];
-
-               intrstr = pci_intr_string(pc, *intr, intrbuf, sizeof(intrbuf));
-
-               pci_intr_setattr(pc, intr, PCI_INTR_MPSAFE, true);
-               *ihs = pci_intr_establish_xname(pc, *intr, IPL_NET,
-                   vmxnet3_rxq_intr, rxq, xnamebuf);
-               if (*ihs == NULL) {
-                       aprint_error_dev(sc->vmx_dev,
-                           "unable to establish rx interrupt at %s\n", intrstr);
-                       return (-1);
-               }
-               aprint_normal_dev(sc->vmx_dev, "rx interrupting at %s\n", intrstr);
-
-               rxq->vxrxq_intr_idx = intr_idx;
+               aprint_normal_dev(sc->vmx_dev, "txrx interrupting at %s\n", intrstr);
+
+               vmxq->vxq_intr_idx = intr_idx;
        }
 
        intrstr = pci_intr_string(pc, *intr, intrbuf, sizeof(intrbuf));
@@ -923,10 +907,8 @@
        }
        aprint_normal_dev(sc->vmx_dev, "interrupting at %s\n", intrstr);
 
-       for (i = 0; i < sc->vmx_ntxqueues; i++)
-               sc->vmx_txq[i].vxtxq_intr_idx = 0;
-       for (i = 0; i < sc->vmx_nrxqueues; i++)
-               sc->vmx_rxq[i].vxrxq_intr_idx = 0;
+       for (i = 0; i < MIN(sc->vmx_nrxqueues, sc->vmx_nrxqueues); i++)
+               sc->vmx_queue[i].vxq_intr_idx = 0;
        sc->vmx_event_intr_idx = 0;
 
        return (0);
@@ -959,10 +941,8 @@
        }
        aprint_normal_dev(sc->vmx_dev, "interrupting at %s\n", intrstr);
 
-       for (i = 0; i < sc->vmx_ntxqueues; i++)
-               sc->vmx_txq[i].vxtxq_intr_idx = 0;
-       for (i = 0; i < sc->vmx_nrxqueues; i++)
-               sc->vmx_rxq[i].vxrxq_intr_idx = 0;
+       for (i = 0; i < MIN(sc->vmx_nrxqueues, sc->vmx_nrxqueues); i++)
+               sc->vmx_queue[i].vxq_intr_idx = 0;
        sc->vmx_event_intr_idx = 0;
 
        return (0);
@@ -971,6 +951,7 @@
 void
 vmxnet3_set_interrupt_idx(struct vmxnet3_softc *sc)
 {
+       struct vmxnet3_queue *vmxq;
        struct vmxnet3_txqueue *txq;
        struct vmxnet3_txq_shared *txs;
        struct vmxnet3_rxqueue *rxq;
@@ -980,15 +961,17 @@
        sc->vmx_ds->evintr = sc->vmx_event_intr_idx;
 
        for (i = 0; i < sc->vmx_ntxqueues; i++) {
-               txq = &sc->vmx_txq[i];
+               vmxq = &sc->vmx_queue[i];
+               txq = &vmxq->vxq_txqueue;
                txs = txq->vxtxq_ts;
-               txs->intr_idx = txq->vxtxq_intr_idx;
+               txs->intr_idx = vmxq->vxq_intr_idx;
        }
 
        for (i = 0; i < sc->vmx_nrxqueues; i++) {
-               rxq = &sc->vmx_rxq[i];
+               vmxq = &sc->vmx_queue[i];
+               rxq = &vmxq->vxq_rxqueue;
                rxs = rxq->vxrxq_rs;
-               rxs->intr_idx = rxq->vxrxq_intr_idx;
+               rxs->intr_idx = vmxq->vxq_intr_idx;
        }
 }
 
@@ -1025,14 +1008,13 @@
        struct vmxnet3_rxring *rxr;
        int i;
 
-       rxq = &sc->vmx_rxq[q];
+       rxq = &sc->vmx_queue[q].vxq_rxqueue;
 
        snprintf(rxq->vxrxq_name, sizeof(rxq->vxrxq_name), "%s-rx%d",
            device_xname(sc->vmx_dev), q);
        rxq->vxrxq_mtx = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET /* XXX */);
 
        rxq->vxrxq_sc = sc;
-       rxq->vxrxq_id = q;
 
        for (i = 0; i < VMXNET3_RXRINGS_PERQ; i++) {
                rxr = &rxq->vxrxq_cmd_ring[i];
@@ -1053,7 +1035,7 @@
        struct vmxnet3_txqueue *txq;
        struct vmxnet3_txring *txr;
 
-       txq = &sc->vmx_txq[q];
+       txq = &sc->vmx_queue[q].vxq_txqueue;
        txr = &txq->vxtxq_cmd_ring;
 
        snprintf(txq->vxtxq_name, sizeof(txq->vxtxq_name), "%s-tx%d",
@@ -1061,7 +1043,6 @@
        txq->vxtxq_mtx = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET /* XXX */);
 
        txq->vxtxq_sc = sc;
-       txq->vxtxq_id = q;
 
        txq->vxtxq_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
            vmxnet3_deferred_transmit, txq);
@@ -1080,7 +1061,7 @@
 int
 vmxnet3_alloc_rxtx_queues(struct vmxnet3_softc *sc)
 {
-       int i, error;
+       int i, error, max_nqueues;
 
        KASSERT(!cpu_intr_p());
        KASSERT(!cpu_softintr_p());
@@ -1100,10 +1081,14 @@
                sc->vmx_max_ntxqueues = 1;
        }
 
-       sc->vmx_rxq = kmem_zalloc(
-           sizeof(struct vmxnet3_rxqueue) * sc->vmx_max_nrxqueues, KM_SLEEP);
-       sc->vmx_txq = kmem_zalloc(
-           sizeof(struct vmxnet3_txqueue) * sc->vmx_max_ntxqueues, KM_SLEEP);
+       max_nqueues = MAX(sc->vmx_max_ntxqueues, sc->vmx_max_nrxqueues);
+       sc->vmx_queue = kmem_zalloc(sizeof(struct vmxnet3_queue) * max_nqueues,
+           KM_SLEEP);
+
+       for (i = 0; i < max_nqueues; i++) {
+               struct vmxnet3_queue *vmxq = &sc->vmx_queue[i];
+               vmxq->vxq_id = i;
+       }
 
        for (i = 0; i < sc->vmx_max_nrxqueues; i++) {
                error = vmxnet3_init_rxq(sc, i);
@@ -1127,7 +1112,6 @@
        int i;
 
        rxq->vxrxq_sc = NULL;
-       rxq->vxrxq_id = -1;
 
        for (i = 0; i < VMXNET3_RXRINGS_PERQ; i++) {
                rxr = &rxq->vxrxq_cmd_ring[i];
@@ -1152,7 +1136,6 @@
        txr = &txq->vxtxq_cmd_ring;



Home | Main Index | Thread Index | Old Index