Module Name: src Committed By: knakahara Date: Wed Oct 20 02:12:37 UTC 2021
Modified Files: src/sys/dev/pci: if_wm.c Log Message: Uniform INTx/MSI handler's Tx/Rx behavior to MSI-X's one. Because the difference has caused INTx/MSI own bugs. To generate a diff of this commit: cvs rdiff -u -r1.710 -r1.711 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.710 src/sys/dev/pci/if_wm.c:1.711 --- src/sys/dev/pci/if_wm.c:1.710 Wed Oct 20 02:05:15 2021 +++ src/sys/dev/pci/if_wm.c Wed Oct 20 02:12:36 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.710 2021/10/20 02:05:15 knakahara Exp $ */ +/* $NetBSD: if_wm.c,v 1.711 2021/10/20 02:12:36 knakahara Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -82,7 +82,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.710 2021/10/20 02:05:15 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.711 2021/10/20 02:12:36 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_net_mpsafe.h" @@ -9835,88 +9835,85 @@ wm_intr_legacy(void *arg) struct wm_queue *wmq = &sc->sc_queue[0]; struct wm_txqueue *txq = &wmq->wmq_txq; struct wm_rxqueue *rxq = &wmq->wmq_rxq; + u_int txlimit = sc->sc_tx_intr_process_limit; + u_int rxlimit = sc->sc_rx_intr_process_limit; uint32_t icr, rndval = 0; - int handled = 0; bool more = false; - while (1 /* CONSTCOND */) { - icr = CSR_READ(sc, WMREG_ICR); - if ((icr & sc->sc_icr) == 0) - break; - if (handled == 0) - DPRINTF(sc, WM_DEBUG_TX, - ("%s: INTx: got intr\n",device_xname(sc->sc_dev))); - if (rndval == 0) - rndval = icr; + icr = CSR_READ(sc, WMREG_ICR); + if ((icr & sc->sc_icr) == 0) + return 0; - mutex_enter(rxq->rxq_lock); + DPRINTF(sc, WM_DEBUG_TX, + ("%s: INTx: got intr\n",device_xname(sc->sc_dev))); + if (rndval == 0) + rndval = icr; - if (rxq->rxq_stopping) { - mutex_exit(rxq->rxq_lock); - break; - } + mutex_enter(rxq->rxq_lock); - handled = 1; + if (rxq->rxq_stopping) { + mutex_exit(rxq->rxq_lock); + return 0; + } #if defined(WM_DEBUG) || defined(WM_EVENT_COUNTERS) - if (icr & (ICR_RXDMT0 | ICR_RXT0)) { - DPRINTF(sc, WM_DEBUG_RX, - ("%s: RX: got Rx intr 0x%08x\n", - device_xname(sc->sc_dev), - icr & (ICR_RXDMT0 | ICR_RXT0))); - WM_Q_EVCNT_INCR(rxq, intr); - } + if (icr & (ICR_RXDMT0 | ICR_RXT0)) { + DPRINTF(sc, WM_DEBUG_RX, + ("%s: RX: got Rx intr 0x%08x\n", + device_xname(sc->sc_dev), + icr & (ICR_RXDMT0 | ICR_RXT0))); + WM_Q_EVCNT_INCR(rxq, intr); + } #endif - /* - * wm_rxeof() does *not* call upper layer functions directly, - * as if_percpuq_enqueue() just call softint_schedule(). - * So, we can call wm_rxeof() in interrupt context. - */ - more = wm_rxeof(rxq, UINT_MAX); + /* + * wm_rxeof() does *not* call upper layer functions directly, + * as if_percpuq_enqueue() just call softint_schedule(). + * So, we can call wm_rxeof() in interrupt context. + */ + more = wm_rxeof(rxq, rxlimit); - mutex_exit(rxq->rxq_lock); - mutex_enter(txq->txq_lock); + mutex_exit(rxq->rxq_lock); + mutex_enter(txq->txq_lock); - if (txq->txq_stopping) { - mutex_exit(txq->txq_lock); - break; - } + if (txq->txq_stopping) { + mutex_exit(txq->txq_lock); + return 0; + } #if defined(WM_DEBUG) || defined(WM_EVENT_COUNTERS) - if (icr & ICR_TXDW) { - DPRINTF(sc, WM_DEBUG_TX, - ("%s: TX: got TXDW interrupt\n", - device_xname(sc->sc_dev))); - WM_Q_EVCNT_INCR(txq, txdw); - } + if (icr & ICR_TXDW) { + DPRINTF(sc, WM_DEBUG_TX, + ("%s: TX: got TXDW interrupt\n", + device_xname(sc->sc_dev))); + WM_Q_EVCNT_INCR(txq, txdw); + } #endif - more |= wm_txeof(txq, UINT_MAX); - if (!IF_IS_EMPTY(&ifp->if_snd)) - more = true; + more |= wm_txeof(txq, txlimit); + if (!IF_IS_EMPTY(&ifp->if_snd)) + more = true; - mutex_exit(txq->txq_lock); - WM_CORE_LOCK(sc); + mutex_exit(txq->txq_lock); + WM_CORE_LOCK(sc); - if (sc->sc_core_stopping) { - WM_CORE_UNLOCK(sc); - break; - } + if (sc->sc_core_stopping) { + WM_CORE_UNLOCK(sc); + return 0; + } - if (icr & (ICR_LSC | ICR_RXSEQ)) { - WM_EVCNT_INCR(&sc->sc_ev_linkintr); - wm_linkintr(sc, icr); - } - if ((icr & ICR_GPI(0)) != 0) - device_printf(sc->sc_dev, "got module interrupt\n"); + if (icr & (ICR_LSC | ICR_RXSEQ)) { + WM_EVCNT_INCR(&sc->sc_ev_linkintr); + wm_linkintr(sc, icr); + } + if ((icr & ICR_GPI(0)) != 0) + device_printf(sc->sc_dev, "got module interrupt\n"); - WM_CORE_UNLOCK(sc); + WM_CORE_UNLOCK(sc); - if (icr & ICR_RXO) { + if (icr & ICR_RXO) { #if defined(WM_DEBUG) - log(LOG_WARNING, "%s: Receive overrun\n", - device_xname(sc->sc_dev)); + log(LOG_WARNING, "%s: Receive overrun\n", + device_xname(sc->sc_dev)); #endif /* defined(WM_DEBUG) */ - } } rnd_add_uint32(&sc->rnd_source, rndval); @@ -9928,7 +9925,7 @@ wm_intr_legacy(void *arg) wm_sched_handle_queue(sc, wmq); } - return handled; + return 1; } static inline void