Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci implement polling mode for multiqueue. It can su...



details:   https://anonhg.NetBSD.org/src/rev/e3b43a66a382
branches:  trunk
changeset: 822134:e3b43a66a382
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Fri Mar 03 07:32:36 2017 +0000

description:
implement polling mode for multiqueue. It can suppress performance degration at high load.

e.g. I354 IP forwarding throughput performance
    + before
      - 133Mbps forwarding performance at 200Mbps input load
      - 41Mbps forwarding performance at 800Mbps input load
    + after
      - 150Mbps forwarding performance at 200Mbps input load
      - 150Mbps forwarding performance at 800Mbps input load

diffstat:

 sys/dev/pci/if_wm.c |  33 ++++++++++++++++++++++++---------
 1 files changed, 24 insertions(+), 9 deletions(-)

diffs (129 lines):

diff -r 339b706e274c -r e3b43a66a382 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Fri Mar 03 07:13:06 2017 +0000
+++ b/sys/dev/pci/if_wm.c       Fri Mar 03 07:32:36 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.492 2017/03/03 03:33:44 knakahara Exp $    */
+/*     $NetBSD: if_wm.c,v 1.493 2017/03/03 07:32:36 knakahara Exp $    */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -84,7 +84,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.492 2017/03/03 03:33:44 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.493 2017/03/03 07:32:36 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -213,6 +213,9 @@
 #define        WM_NEXTRX(x)            (((x) + 1) & WM_NRXDESC_MASK)
 #define        WM_PREVRX(x)            (((x) - 1) & WM_NRXDESC_MASK)
 
+#define        WM_RX_PROCESS_LIMIT_DEFAULT             100U
+#define        WM_RX_INTR_PROCESS_LIMIT_DEFAULT        0U
+
 typedef union txdescs {
        wiseman_txdesc_t sctxu_txdescs[WM_NTXDESC_82544];
        nq_txdesc_t      sctxu_nq_txdescs[WM_NTXDESC_82544];
@@ -485,6 +488,8 @@
 
        int sc_nqueues;
        struct wm_queue *sc_queue;
+       u_int sc_rx_process_limit;      /* Rx processing repeat limit in softint */
+       u_int sc_rx_intr_process_limit; /* Rx processing repeat limit in H/W intr */
 
        int sc_affinity_offset;
 
@@ -715,7 +720,7 @@
 static void    wm_handle_queue(void *);
 /* Interrupt */
 static int     wm_txeof(struct wm_softc *, struct wm_txqueue *);
-static void    wm_rxeof(struct wm_rxqueue *);
+static void    wm_rxeof(struct wm_rxqueue *, u_int);
 static void    wm_linkintr_gmii(struct wm_softc *, uint32_t);
 static void    wm_linkintr_tbi(struct wm_softc *, uint32_t);
 static void    wm_linkintr_serdes(struct wm_softc *, uint32_t);
@@ -2639,6 +2644,9 @@
                ifp->if_capabilities |= IFCAP_TSOv6;
        }
 
+       sc->sc_rx_process_limit = WM_RX_PROCESS_LIMIT_DEFAULT;
+       sc->sc_rx_intr_process_limit = WM_RX_INTR_PROCESS_LIMIT_DEFAULT;
+
 #ifdef WM_MPSAFE
        sc->sc_core_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
 #else
@@ -7812,7 +7820,7 @@
  *     Helper; handle receive interrupts.
  */
 static void
-wm_rxeof(struct wm_rxqueue *rxq)
+wm_rxeof(struct wm_rxqueue *rxq, u_int limit)
 {
        struct wm_softc *sc = rxq->rxq_sc;
        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
@@ -7826,6 +7834,11 @@
        KASSERT(mutex_owned(rxq->rxq_lock));
 
        for (i = rxq->rxq_ptr;; i = WM_NEXTRX(i)) {
+               if (limit-- == 0) {
+                       rxq->rxq_ptr = i;
+                       break;
+               }
+
                rxs = &rxq->rxq_soft[i];
 
                DPRINTF(WM_DEBUG_RX,
@@ -8310,7 +8323,7 @@
                        WM_Q_EVCNT_INCR(rxq, rxintr);
                }
 #endif
-               wm_rxeof(rxq);
+               wm_rxeof(rxq, UINT_MAX);
 
                mutex_exit(rxq->rxq_lock);
                mutex_enter(txq->txq_lock);
@@ -8396,6 +8409,7 @@
        struct wm_txqueue *txq = &wmq->wmq_txq;
        struct wm_rxqueue *rxq = &wmq->wmq_rxq;
        struct wm_softc *sc = txq->txq_sc;
+       u_int limit = sc->sc_rx_intr_process_limit;
 
        KASSERT(wmq->wmq_intr_idx == wmq->wmq_id);
 
@@ -8426,13 +8440,11 @@
        }
 
        WM_Q_EVCNT_INCR(rxq, rxintr);
-       wm_rxeof(rxq);
+       wm_rxeof(rxq, limit);
        mutex_exit(rxq->rxq_lock);
 
        softint_schedule(wmq->wmq_si);
 
-       wm_txrxintr_enable(wmq);
-
        return 1;
 }
 
@@ -8443,6 +8455,7 @@
        struct wm_txqueue *txq = &wmq->wmq_txq;
        struct wm_rxqueue *rxq = &wmq->wmq_rxq;
        struct wm_softc *sc = txq->txq_sc;
+       u_int limit = sc->sc_rx_process_limit;
 
        mutex_enter(txq->txq_lock);
        if (txq->txq_stopping) {
@@ -8459,8 +8472,10 @@
                return;
        }
        WM_Q_EVCNT_INCR(rxq, rxintr);
-       wm_rxeof(rxq);
+       wm_rxeof(rxq, limit);
        mutex_exit(rxq->rxq_lock);
+
+       wm_txrxintr_enable(wmq);
 }
 
 /*



Home | Main Index | Thread Index | Old Index