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 add vmx(4) basic statistics counters.



details:   https://anonhg.NetBSD.org/src/rev/5f411846b34a
branches:  trunk
changeset: 453595:5f411846b34a
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Mon Aug 19 05:25:38 2019 +0000

description:
add vmx(4) basic statistics counters.

Sorry, I have forgotten this TODO in r1.40 commit message.

diffstat:

 sys/arch/x86/pci/if_vmx.c |  145 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 141 insertions(+), 4 deletions(-)

diffs (285 lines):

diff -r f3210c7d6372 -r 5f411846b34a sys/arch/x86/pci/if_vmx.c
--- a/sys/arch/x86/pci/if_vmx.c Mon Aug 19 05:23:50 2019 +0000
+++ b/sys/arch/x86/pci/if_vmx.c Mon Aug 19 05:25:38 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_vmx.c,v 1.47 2019/08/19 05:23:50 knakahara Exp $    */
+/*     $NetBSD: if_vmx.c,v 1.48 2019/08/19 05:25:38 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.47 2019/08/19 05:23:50 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vmx.c,v 1.48 2019/08/19 05:25:38 knakahara Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -200,6 +200,13 @@
        char vxtxq_name[16];
 
        void *vxtxq_si;
+
+       struct evcnt vxtxq_intr;
+       struct evcnt vxtxq_defer;
+       struct evcnt vxtxq_deferreq;
+       struct evcnt vxtxq_pcqdrop;
+       struct evcnt vxtxq_transmitdef;
+       struct evcnt vxtxq_watchdogto;
 };
 
 struct vmxnet3_rxq_stats {
@@ -219,6 +226,10 @@
        struct vmxnet3_rxq_stats vxrxq_stats;
        struct vmxnet3_rxq_shared *vxrxq_rs;
        char vxrxq_name[16];
+
+       struct evcnt vxrxq_intr;
+       struct evcnt vxrxq_defer;
+       struct evcnt vxrxq_deferreq;
 };
 
 struct vmxnet3_queue {
@@ -271,6 +282,12 @@
        int vmx_max_rxsegs;
 
        struct vmxnet3_statistics vmx_stats;
+       struct evcnt vmx_event_intr;
+       struct evcnt vmx_event_link;
+       struct evcnt vmx_event_txqerror;
+       struct evcnt vmx_event_rxqerror;
+       struct evcnt vmx_event_dic;
+       struct evcnt vmx_event_debug;
 
        int vmx_intr_type;
        int vmx_intr_mask_mode;
@@ -349,6 +366,9 @@
 int vmxnet3_setup_interrupts(struct vmxnet3_softc *);
 int vmxnet3_setup_sysctl(struct vmxnet3_softc *);
 
+int vmxnet3_setup_stats(struct vmxnet3_softc *);
+void vmxnet3_teardown_stats(struct vmxnet3_softc *);
+
 int vmxnet3_init_rxq(struct vmxnet3_softc *, int);
 int vmxnet3_init_txq(struct vmxnet3_softc *, int);
 int vmxnet3_alloc_rxtx_queues(struct vmxnet3_softc *);
@@ -631,6 +651,10 @@
        if (error)
                return;
 
+       error = vmxnet3_setup_stats(sc);
+       if (error)
+               return;
+
        sc->vmx_flags |= VMXNET3_FLAG_ATTACHED;
 }
 
@@ -655,6 +679,7 @@
                if_detach(ifp);
        }
 
+       vmxnet3_teardown_stats(sc);
        sysctl_teardown(&sc->vmx_sysctllog);
 
        vmxnet3_free_interrupts(sc);
@@ -1923,6 +1948,93 @@
        return error;
 }
 
+int
+vmxnet3_setup_stats(struct vmxnet3_softc *sc)
+{
+       struct vmxnet3_queue *vmxq;
+       struct vmxnet3_txqueue *txq;
+       struct vmxnet3_rxqueue *rxq;
+       int i;
+
+       for (i = 0; i < sc->vmx_ntxqueues; i++) {
+               vmxq = &sc->vmx_queue[i];
+               txq = &vmxq->vxq_txqueue;
+               evcnt_attach_dynamic(&txq->vxtxq_intr, EVCNT_TYPE_INTR,
+                   NULL, txq->vxtxq_name, "Interrupt on queue");
+               evcnt_attach_dynamic(&txq->vxtxq_defer, EVCNT_TYPE_MISC,
+                   NULL, txq->vxtxq_name, "Handled queue in softint/workqueue");
+               evcnt_attach_dynamic(&txq->vxtxq_deferreq, EVCNT_TYPE_MISC,
+                   NULL, txq->vxtxq_name, "Requested in softint/workqueue");
+               evcnt_attach_dynamic(&txq->vxtxq_pcqdrop, EVCNT_TYPE_MISC,
+                   NULL, txq->vxtxq_name, "Dropped in pcq");
+               evcnt_attach_dynamic(&txq->vxtxq_transmitdef, EVCNT_TYPE_MISC,
+                   NULL, txq->vxtxq_name, "Deferred transmit");
+               evcnt_attach_dynamic(&txq->vxtxq_watchdogto, EVCNT_TYPE_MISC,
+                   NULL, txq->vxtxq_name, "Watchdog timeount");
+       }
+
+       for (i = 0; i < sc->vmx_nrxqueues; i++) {
+               vmxq = &sc->vmx_queue[i];
+               rxq = &vmxq->vxq_rxqueue;
+               evcnt_attach_dynamic(&rxq->vxrxq_intr, EVCNT_TYPE_INTR,
+                   NULL, rxq->vxrxq_name, "Interrupt on queue");
+               evcnt_attach_dynamic(&rxq->vxrxq_defer, EVCNT_TYPE_MISC,
+                   NULL, rxq->vxrxq_name, "Handled queue in softint/workqueue");
+               evcnt_attach_dynamic(&rxq->vxrxq_deferreq, EVCNT_TYPE_MISC,
+                   NULL, rxq->vxrxq_name, "Requested in softint/workqueue");
+       }
+
+       evcnt_attach_dynamic(&sc->vmx_event_intr, EVCNT_TYPE_INTR,
+           NULL, device_xname(sc->vmx_dev), "Interrupt for other events");
+       evcnt_attach_dynamic(&sc->vmx_event_link, EVCNT_TYPE_MISC,
+           NULL, device_xname(sc->vmx_dev), "Link status event");
+       evcnt_attach_dynamic(&sc->vmx_event_txqerror, EVCNT_TYPE_MISC,
+           NULL, device_xname(sc->vmx_dev), "Tx queue error event");
+       evcnt_attach_dynamic(&sc->vmx_event_rxqerror, EVCNT_TYPE_MISC,
+           NULL, device_xname(sc->vmx_dev), "Rx queue error event");
+       evcnt_attach_dynamic(&sc->vmx_event_dic, EVCNT_TYPE_MISC,
+           NULL, device_xname(sc->vmx_dev), "Device impl change event");
+       evcnt_attach_dynamic(&sc->vmx_event_debug, EVCNT_TYPE_MISC,
+           NULL, device_xname(sc->vmx_dev), "Debug event");
+
+       return 0;
+}
+
+void
+vmxnet3_teardown_stats(struct vmxnet3_softc *sc)
+{
+       struct vmxnet3_queue *vmxq;
+       struct vmxnet3_txqueue *txq;
+       struct vmxnet3_rxqueue *rxq;
+       int i;
+
+       for (i = 0; i < sc->vmx_ntxqueues; i++) {
+               vmxq = &sc->vmx_queue[i];
+               txq = &vmxq->vxq_txqueue;
+               evcnt_detach(&txq->vxtxq_intr);
+               evcnt_detach(&txq->vxtxq_defer);
+               evcnt_detach(&txq->vxtxq_deferreq);
+               evcnt_detach(&txq->vxtxq_pcqdrop);
+               evcnt_detach(&txq->vxtxq_transmitdef);
+               evcnt_detach(&txq->vxtxq_watchdogto);
+       }
+
+       for (i = 0; i < sc->vmx_nrxqueues; i++) {
+               vmxq = &sc->vmx_queue[i];
+               rxq = &vmxq->vxq_rxqueue;
+               evcnt_detach(&rxq->vxrxq_intr);
+               evcnt_detach(&rxq->vxrxq_defer);
+               evcnt_detach(&rxq->vxrxq_deferreq);
+       }
+
+       evcnt_detach(&sc->vmx_event_intr);
+       evcnt_detach(&sc->vmx_event_link);
+       evcnt_detach(&sc->vmx_event_txqerror);
+       evcnt_detach(&sc->vmx_event_rxqerror);
+       evcnt_detach(&sc->vmx_event_dic);
+       evcnt_detach(&sc->vmx_event_debug);
+}
+
 void
 vmxnet3_evintr(struct vmxnet3_softc *sc)
 {
@@ -1942,12 +2054,18 @@
        vmxnet3_write_bar1(sc, VMXNET3_BAR1_EVENT, event);
 
        if (event & VMXNET3_EVENT_LINK) {
+               sc->vmx_event_link.ev_count++;
                vmxnet3_link_status(sc);
                if (sc->vmx_link_active != 0)
                        if_schedule_deferred_start(&sc->vmx_ethercom.ec_if);
        }
 
        if (event & (VMXNET3_EVENT_TQERROR | VMXNET3_EVENT_RQERROR)) {
+               if (event & VMXNET3_EVENT_TQERROR)
+                       sc->vmx_event_txqerror.ev_count++;
+               if (event & VMXNET3_EVENT_RQERROR)
+                       sc->vmx_event_rxqerror.ev_count++;
+
                reset = 1;
                vmxnet3_read_cmd(sc, VMXNET3_CMD_GET_STATUS);
                ts = sc->vmx_queue[0].vxq_txqueue.vxtxq_ts;
@@ -1959,10 +2077,14 @@
                device_printf(dev, "Rx/Tx queue error event ... resetting\n");
        }
 
-       if (event & VMXNET3_EVENT_DIC)
+       if (event & VMXNET3_EVENT_DIC) {
+               sc->vmx_event_dic.ev_count++;
                device_printf(dev, "device implementation change event\n");
-       if (event & VMXNET3_EVENT_DEBUG)
+       }
+       if (event & VMXNET3_EVENT_DEBUG) {
+               sc->vmx_event_debug.ev_count++;
                device_printf(dev, "debug event\n");
+       }
 
        if (reset != 0)
                vmxnet3_init_locked(sc);
@@ -2419,10 +2541,12 @@
                vmxnet3_disable_intr(sc, vmxq->vxq_intr_idx);
 
        VMXNET3_TXQ_LOCK(txq);
+       txq->vxtxq_intr.ev_count++;
        txmore = vmxnet3_txq_eof(txq, txlimit);
        VMXNET3_TXQ_UNLOCK(txq);
 
        VMXNET3_RXQ_LOCK(rxq);
+       rxq->vxrxq_intr.ev_count++;
        rxmore = vmxnet3_rxq_eof(rxq, rxlimit);
        VMXNET3_RXQ_UNLOCK(rxq);
 
@@ -2458,7 +2582,10 @@
        rxlimit = sc->vmx_rx_process_limit;
 
        VMXNET3_TXQ_LOCK(txq);
+       txq->vxtxq_defer.ev_count++;
        txmore = vmxnet3_txq_eof(txq, txlimit);
+       if (txmore)
+               txq->vxtxq_deferreq.ev_count++;
        /* for ALTQ */
        if (vmxq->vxq_id == 0)
                if_schedule_deferred_start(&sc->vmx_ethercom.ec_if);
@@ -2466,7 +2593,10 @@
        VMXNET3_TXQ_UNLOCK(txq);
 
        VMXNET3_RXQ_LOCK(rxq);
+       rxq->vxrxq_defer.ev_count++;
        rxmore = vmxnet3_rxq_eof(rxq, rxlimit);
+       if (rxmore)
+               rxq->vxrxq_deferreq.ev_count++;
        VMXNET3_RXQ_UNLOCK(rxq);
 
        if (txmore || rxmore)
@@ -2494,6 +2624,8 @@
        if (sc->vmx_intr_mask_mode == VMXNET3_IMM_ACTIVE)
                vmxnet3_disable_intr(sc, sc->vmx_event_intr_idx);
 
+       sc->vmx_event_intr.ev_count++;
+
        if (sc->vmx_ds->event != 0)
                vmxnet3_evintr(sc);
 
@@ -3123,6 +3255,9 @@
        txq = &sc->vmx_queue[qid].vxq_txqueue;
 
        if (__predict_false(!pcq_put(txq->vxtxq_interq, m))) {
+               VMXNET3_TXQ_LOCK(txq);
+               txq->vxtxq_pcqdrop.ev_count++;
+               VMXNET3_TXQ_UNLOCK(txq);
                m_freem(m);
                return ENOBUFS;
        }
@@ -3145,6 +3280,7 @@
        struct ifnet *ifp = &sc->vmx_ethercom.ec_if;
 
        VMXNET3_TXQ_LOCK(txq);
+       txq->vxtxq_transmitdef.ev_count++;
        if (pcq_peek(txq->vxtxq_interq) != NULL)
                vmxnet3_transmit_locked(ifp, txq);
        VMXNET3_TXQ_UNLOCK(txq);
@@ -3327,6 +3463,7 @@
                VMXNET3_TXQ_UNLOCK(txq);
                return (0);
        }
+       txq->vxtxq_watchdogto.ev_count++;
        VMXNET3_TXQ_UNLOCK(txq);
 
        device_printf(sc->vmx_dev, "watchdog timeout on queue %d\n",



Home | Main Index | Thread Index | Old Index