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