Module Name: src Committed By: knakahara Date: Fri Mar 3 07:32:36 UTC 2017
Modified Files: src/sys/dev/pci: if_wm.c Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.492 -r1.493 src/sys/dev/pci/if_wm.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/dev/pci/if_wm.c diff -u src/sys/dev/pci/if_wm.c:1.492 src/sys/dev/pci/if_wm.c:1.493 --- src/sys/dev/pci/if_wm.c:1.492 Fri Mar 3 03:33:44 2017 +++ src/sys/dev/pci/if_wm.c Fri Mar 3 07:32:36 2017 @@ -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 @@ int wm_debug = WM_DEBUG_TX | WM_DEBUG_RX #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 @@ struct wm_softc { 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_deferred_start_locked(str 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 @@ alloc_retry: 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 @@ wm_rxdesc_ensure_checksum(struct wm_rxqu * 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 @@ wm_rxeof(struct wm_rxqueue *rxq) 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_intr_legacy(void *arg) 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 @@ wm_txrxintr_msix(void *arg) 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_txrxintr_msix(void *arg) } 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 @@ wm_handle_queue(void *arg) 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 @@ wm_handle_queue(void *arg) return; } WM_Q_EVCNT_INCR(rxq, rxintr); - wm_rxeof(rxq); + wm_rxeof(rxq, limit); mutex_exit(rxq->rxq_lock); + + wm_txrxintr_enable(wmq); } /*