Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Uniform INTx/MSI handler's Tx/Rx behavior to MSI...
details: https://anonhg.NetBSD.org/src/rev/97ba429b7546
branches: trunk
changeset: 1024345:97ba429b7546
user: knakahara <knakahara%NetBSD.org@localhost>
date: Wed Oct 20 02:12:36 2021 +0000
description:
Uniform INTx/MSI handler's Tx/Rx behavior to MSI-X's one.
Because the difference has caused INTx/MSI own bugs.
diffstat:
sys/dev/pci/if_wm.c | 147 +++++++++++++++++++++++++--------------------------
1 files changed, 72 insertions(+), 75 deletions(-)
diffs (185 lines):
diff -r bb139fddab61 -r 97ba429b7546 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Wed Oct 20 02:05:15 2021 +0000
+++ b/sys/dev/pci/if_wm.c Wed Oct 20 02:12:36 2021 +0000
@@ -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 @@
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;
-
- mutex_enter(rxq->rxq_lock);
-
- if (rxq->rxq_stopping) {
- mutex_exit(rxq->rxq_lock);
- break;
- }
-
- handled = 1;
+ icr = CSR_READ(sc, WMREG_ICR);
+ if ((icr & sc->sc_icr) == 0)
+ return 0;
+
+ DPRINTF(sc, WM_DEBUG_TX,
+ ("%s: INTx: got intr\n",device_xname(sc->sc_dev)));
+ if (rndval == 0)
+ rndval = icr;
+
+ mutex_enter(rxq->rxq_lock);
+
+ 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);
- }
-#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);
-
- mutex_exit(rxq->rxq_lock);
- mutex_enter(txq->txq_lock);
-
- if (txq->txq_stopping) {
- mutex_exit(txq->txq_lock);
- break;
- }
+ 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, rxlimit);
+
+ mutex_exit(rxq->rxq_lock);
+ mutex_enter(txq->txq_lock);
+
+ 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);
- }
-#endif
- more |= wm_txeof(txq, UINT_MAX);
- if (!IF_IS_EMPTY(&ifp->if_snd))
- more = true;
-
- mutex_exit(txq->txq_lock);
- WM_CORE_LOCK(sc);
-
- if (sc->sc_core_stopping) {
- WM_CORE_UNLOCK(sc);
- break;
- }
-
- 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_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, txlimit);
+ if (!IF_IS_EMPTY(&ifp->if_snd))
+ more = true;
+
+ mutex_exit(txq->txq_lock);
+ WM_CORE_LOCK(sc);
+
+ if (sc->sc_core_stopping) {
WM_CORE_UNLOCK(sc);
-
- if (icr & ICR_RXO) {
+ 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");
+
+ WM_CORE_UNLOCK(sc);
+
+ 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_sched_handle_queue(sc, wmq);
}
- return handled;
+ return 1;
}
static inline void
Home |
Main Index |
Thread Index |
Old Index