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