Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic Improve handling of receive overflows. When we g...



details:   https://anonhg.NetBSD.org/src/rev/dc71945f7ef5
branches:  trunk
changeset: 950738:dc71945f7ef5
user:      jdc <jdc%NetBSD.org@localhost>
date:      Sat Jan 30 07:53:01 2021 +0000

description:
Improve handling of receive overflows.  When we get an overflow, don't
reset the chip if we are still receiving packets.  Real overflows can
happen when network and CPU(s) are loaded, so the reset is not needed
in this case.
Add a counter to track receive overflows (when GEM_COUNTERS is defined).

This reverts some changes (always reset on overflow) from
PR port-sparc64/46260.

diffstat:

 sys/dev/ic/gem.c    |  44 +++++++++++++++++++++++++++++---------------
 sys/dev/ic/gemvar.h |   3 ++-
 2 files changed, 31 insertions(+), 16 deletions(-)

diffs (120 lines):

diff -r c5f1e68cedea -r dc71945f7ef5 sys/dev/ic/gem.c
--- a/sys/dev/ic/gem.c  Sat Jan 30 01:23:08 2021 +0000
+++ b/sys/dev/ic/gem.c  Sat Jan 30 07:53:01 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gem.c,v 1.132 2020/09/15 08:33:40 mrg Exp $ */
+/*     $NetBSD: gem.c,v 1.133 2021/01/30 07:53:01 jdc Exp $ */
 
 /*
  *
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gem.c,v 1.132 2020/09/15 08:33:40 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gem.c,v 1.133 2021/01/30 07:53:01 jdc Exp $");
 
 #include "opt_inet.h"
 
@@ -169,6 +169,7 @@
                evcnt_detach(&sc->sc_ev_rxfull);
                evcnt_detach(&sc->sc_ev_rxint);
                evcnt_detach(&sc->sc_ev_txint);
+               evcnt_detach(&sc->sc_ev_rxoverflow);
 #endif
                evcnt_detach(&sc->sc_ev_intr);
 
@@ -596,6 +597,8 @@
            &sc->sc_ev_rxint, device_xname(sc->sc_dev), "rx ring full");
        evcnt_attach_dynamic(&sc->sc_ev_rxnobuf, EVCNT_TYPE_INTR,
            &sc->sc_ev_rxint, device_xname(sc->sc_dev), "rx malloc failure");
+       evcnt_attach_dynamic(&sc->sc_ev_rxoverflow, EVCNT_TYPE_INTR,
+           &sc->sc_ev_rxint, device_xname(sc->sc_dev), "rx overflow");
        evcnt_attach_dynamic(&sc->sc_ev_rxhist[0], EVCNT_TYPE_INTR,
            &sc->sc_ev_rxint, device_xname(sc->sc_dev), "rx 0desc");
        evcnt_attach_dynamic(&sc->sc_ev_rxhist[1], EVCNT_TYPE_INTR,
@@ -1803,8 +1806,8 @@
 
                if (rxstat & GEM_RD_BAD_CRC) {
                        if_statinc(ifp, if_ierrors);
-                       aprint_error_dev(sc->sc_dev,
-                           "receive error: CRC error\n");
+                       DPRINTF(sc, ("%s: receive error: CRC error\n",
+                           device_xname(sc->sc_dev)));
                        GEM_INIT_RXDESC(sc, i);
                        continue;
                }
@@ -2215,8 +2218,11 @@
                 */
                if (rxstat & GEM_MAC_RX_OVERFLOW) {
                        if_statinc(ifp, if_ierrors);
+                       GEM_COUNTER_INCR(sc, sc_ev_rxoverflow);
+#ifdef GEM_DEBUG
                        aprint_error_dev(sc->sc_dev,
                            "receive error: RX overflow sc->rxptr %d, complete %d\n", sc->sc_rxptr, bus_space_read_4(t, h, GEM_RX_COMPLETION));
+#endif
                        sc->sc_rx_fifo_wr_ptr =
                                bus_space_read_4(t, h, GEM_RX_FIFO_WR_PTR);
                        sc->sc_rx_fifo_rd_ptr =
@@ -2282,25 +2288,33 @@
                    "receiver stuck in overflow, resetting\n");
                gem_init(ifp);
        } else {
+               int needreset = 1;
                if ((state & GEM_MAC_STATE_OVERFLOW) != GEM_MAC_STATE_OVERFLOW) {
-                       aprint_error_dev(sc->sc_dev,
-                               "rx_watchdog: not in overflow state: 0x%x\n",
-                               state);
+                       DPRINTF(sc,
+                           ("%s: rx_watchdog: not in overflow state: 0x%x\n",
+                           device_xname(sc->sc_dev), state));
                }
                if (rx_fifo_wr_ptr != rx_fifo_rd_ptr) {
-                       aprint_error_dev(sc->sc_dev,
-                               "rx_watchdog: wr & rd ptr different\n");
+                       DPRINTF(sc,
+                           ("%s: rx_watchdog: wr & rd ptr different\n",
+                           device_xname(sc->sc_dev), state));
+                       needreset = 0;
                }
                if (sc->sc_rx_fifo_wr_ptr != rx_fifo_wr_ptr) {
-                       aprint_error_dev(sc->sc_dev,
-                               "rx_watchdog: wr pointer != saved\n");
+                       DPRINTF(sc, ("%s: rx_watchdog: wr pointer != saved\n",
+                           device_xname(sc->sc_dev), state));
+                       needreset = 0;
                }
                if (sc->sc_rx_fifo_rd_ptr != rx_fifo_rd_ptr) {
-                       aprint_error_dev(sc->sc_dev,
-                               "rx_watchdog: rd pointer != saved\n");
+                       DPRINTF(sc, ("%s: rx_watchdog: rd pointer != saved\n",
+                           device_xname(sc->sc_dev), state));
+                       needreset = 0;
                }
-               aprint_error_dev(sc->sc_dev, "resetting anyway\n");
-               gem_init(ifp);
+               if (needreset) {
+                       aprint_error_dev(sc->sc_dev,
+                           "rx_watchdog: resetting anyway\n");
+                       gem_init(ifp);
+               }
        }
 }
 
diff -r c5f1e68cedea -r dc71945f7ef5 sys/dev/ic/gemvar.h
--- a/sys/dev/ic/gemvar.h       Sat Jan 30 01:23:08 2021 +0000
+++ b/sys/dev/ic/gemvar.h       Sat Jan 30 07:53:01 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gemvar.h,v 1.27 2020/03/01 05:50:56 thorpej Exp $ */
+/*     $NetBSD: gemvar.h,v 1.28 2021/01/30 07:53:01 jdc Exp $ */
 
 /*
  *
@@ -219,6 +219,7 @@
 #ifdef GEM_COUNTERS
        struct evcnt sc_ev_txint;
        struct evcnt sc_ev_rxint;
+       struct evcnt sc_ev_rxoverflow;
        struct evcnt sc_ev_rxnobuf;
        struct evcnt sc_ev_rxfull;
        struct evcnt sc_ev_rxhist[9];



Home | Main Index | Thread Index | Old Index