Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci bge: Mirror the bus_dma RX buffer changes in the...



details:   https://anonhg.NetBSD.org/src/rev/893e9de5e8e8
branches:  trunk
changeset: 368950:893e9de5e8e8
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sun Aug 14 09:03:05 2022 +0000

description:
bge: Mirror the bus_dma RX buffer changes in the OpenBSD driver

This change reduces the amount of work done in the interrupt handler.

diffstat:

 sys/dev/pci/if_bge.c    |  187 +++++++++++++++++++++++++----------------------
 sys/dev/pci/if_bgevar.h |    3 +-
 2 files changed, 102 insertions(+), 88 deletions(-)

diffs (truncated from 311 to 300 lines):

diff -r 1c9b6c5c59d1 -r 893e9de5e8e8 sys/dev/pci/if_bge.c
--- a/sys/dev/pci/if_bge.c      Sun Aug 14 09:01:25 2022 +0000
+++ b/sys/dev/pci/if_bge.c      Sun Aug 14 09:03:05 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bge.c,v 1.375 2022/08/14 09:01:25 skrll Exp $       */
+/*     $NetBSD: if_bge.c,v 1.376 2022/08/14 09:03:05 skrll Exp $       */
 
 /*
  * Copyright (c) 2001 Wind River Systems
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.375 2022/08/14 09:01:25 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.376 2022/08/14 09:03:05 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -230,13 +230,15 @@
 static void bge_free_jumbo_mem(struct bge_softc *);
 static void *bge_jalloc(struct bge_softc *);
 static void bge_jfree(struct mbuf *, void *, size_t, void *);
-static int bge_newbuf_std(struct bge_softc *, int, struct mbuf *,
-                              bus_dmamap_t);
 static int bge_newbuf_jumbo(struct bge_softc *, int, struct mbuf *);
-static int bge_init_rx_ring_std(struct bge_softc *);
-static void bge_free_rx_ring_std(struct bge_softc *m, bool);
 static int bge_init_rx_ring_jumbo(struct bge_softc *);
 static void bge_free_rx_ring_jumbo(struct bge_softc *);
+
+static int bge_newbuf_std(struct bge_softc *, int);
+static int bge_init_rx_ring_std(struct bge_softc *);
+static void bge_fill_rx_ring_std(struct bge_softc *);
+static void bge_free_rx_ring_std(struct bge_softc *m);
+
 static void bge_free_tx_ring(struct bge_softc *m, bool);
 static int bge_init_tx_ring(struct bge_softc *);
 
@@ -1479,64 +1481,52 @@
  * Initialize a standard receive ring descriptor.
  */
 static int
-bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m,
-    bus_dmamap_t dmamap)
+bge_newbuf_std(struct bge_softc *sc, int i)
 {
-       struct mbuf             *m_new = NULL;
-       struct bge_rx_bd        *r;
-       int                     error;
-
-       if (dmamap == NULL)
-               dmamap = sc->bge_cdata.bge_rx_std_map[i];
-
-       if (dmamap == NULL) {
-               error = bus_dmamap_create(sc->bge_dmatag, MCLBYTES, 1,
-                   MCLBYTES, 0, BUS_DMA_NOWAIT, &dmamap);
-               if (error != 0)
-                       return error;
-       }
-
-       sc->bge_cdata.bge_rx_std_map[i] = dmamap;
-
-       if (m == NULL) {
-               MGETHDR(m_new, M_DONTWAIT, MT_DATA);
-               if (m_new == NULL)
-                       return ENOBUFS;
-
-               MCLGET(m_new, M_DONTWAIT);
-               if (!(m_new->m_flags & M_EXT)) {
-                       m_freem(m_new);
-                       return ENOBUFS;
-               }
-               m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
-
-       } else {
-               m_new = m;
-               m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
-               m_new->m_data = m_new->m_ext.ext_buf;
-       }
+       const bus_dmamap_t dmamap = sc->bge_cdata.bge_rx_std_map[i];
+       struct mbuf *m;
+
+       MGETHDR(m, M_DONTWAIT, MT_DATA);
+       if (m == NULL)
+               return ENOBUFS;
+
+       MCLGET(m, M_DONTWAIT);
+       if (!(m->m_flags & M_EXT)) {
+               m_freem(m);
+               return ENOBUFS;
+       }
+       m->m_len = m->m_pkthdr.len = MCLBYTES;
+
        if (!(sc->bge_flags & BGEF_RX_ALIGNBUG))
-           m_adj(m_new, ETHER_ALIGN);
-       if (bus_dmamap_load_mbuf(sc->bge_dmatag, dmamap, m_new,
+           m_adj(m, ETHER_ALIGN);
+       if (bus_dmamap_load_mbuf(sc->bge_dmatag, dmamap, m,
            BUS_DMA_READ | BUS_DMA_NOWAIT)) {
-               m_freem(m_new);
+               m_freem(m);
                return ENOBUFS;
        }
        bus_dmamap_sync(sc->bge_dmatag, dmamap, 0, dmamap->dm_mapsize,
            BUS_DMASYNC_PREREAD);
-
-       sc->bge_cdata.bge_rx_std_chain[i] = m_new;
-       r = &sc->bge_rdata->bge_rx_std_ring[i];
+       sc->bge_cdata.bge_rx_std_chain[i] = m;
+
+       bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
+           offsetof(struct bge_ring_data, bge_rx_std_ring) +
+               i * sizeof(struct bge_rx_bd),
+           sizeof(struct bge_rx_bd),
+           BUS_DMASYNC_POSTWRITE);
+
+       struct bge_rx_bd * const r = &sc->bge_rdata->bge_rx_std_ring[i];
        BGE_HOSTADDR(r->bge_addr, dmamap->dm_segs[0].ds_addr);
        r->bge_flags = BGE_RXBDFLAG_END;
-       r->bge_len = m_new->m_len;
+       r->bge_len = m->m_len;
        r->bge_idx = i;
 
        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
            offsetof(struct bge_ring_data, bge_rx_std_ring) +
                i * sizeof(struct bge_rx_bd),
            sizeof(struct bge_rx_bd),
-           BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
+           BUS_DMASYNC_PREWRITE);
+
+       sc->bge_std_cnt++;
 
        return 0;
 }
@@ -1601,51 +1591,84 @@
        return 0;
 }
 
-/*
- * The standard receive ring has 512 entries in it. At 2K per mbuf cluster,
- * that's 1MB or memory, which is a lot. For now, we fill only the first
- * 256 ring entries and hope that our CPU is fast enough to keep up with
- * the NIC.
- */
 static int
 bge_init_rx_ring_std(struct bge_softc *sc)
 {
-       int i;
+       bus_dmamap_t dmamap;
+       int error = 0;
+       u_int i;
 
        if (sc->bge_flags & BGEF_RXRING_VALID)
                return 0;
 
-       for (i = 0; i < BGE_SSLOTS; i++) {
-               if (bge_newbuf_std(sc, i, NULL, 0) == ENOBUFS)
-                       return ENOBUFS;
+       for (i = 0; i < BGE_STD_RX_RING_CNT; i++) {
+               error = bus_dmamap_create(sc->bge_dmatag, MCLBYTES, 1,
+                   MCLBYTES, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &dmamap);
+               if (error)
+                       goto uncreate;
+
+               sc->bge_cdata.bge_rx_std_map[i] = dmamap;
+               memset(&sc->bge_rdata->bge_rx_std_ring[i], 0,
+                   sizeof(struct bge_rx_bd));
        }
 
        sc->bge_std = i - 1;
-       bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
+       sc->bge_std_cnt = 0;
+       bge_fill_rx_ring_std(sc);
 
        sc->bge_flags |= BGEF_RXRING_VALID;
 
        return 0;
+
+uncreate:
+       while (--i) {
+               bus_dmamap_destroy(sc->bge_dmatag,
+                   sc->bge_cdata.bge_rx_std_map[i]);
+       }
+       return error;
 }
 
 static void
-bge_free_rx_ring_std(struct bge_softc *sc, bool disable)
+bge_fill_rx_ring_std(struct bge_softc *sc)
 {
-       int i;
+       int i = sc->bge_std;
+       bool post = false;
+
+       while (sc->bge_std_cnt < BGE_STD_RX_RING_CNT) {
+               BGE_INC(i, BGE_STD_RX_RING_CNT);
+
+               if (bge_newbuf_std(sc, i) != 0)
+                       break;
+
+               sc->bge_std = i;
+               post = true;
+       }
+
+       if (post)
+               bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
+}
+
+
+static void
+bge_free_rx_ring_std(struct bge_softc *sc)
+{
 
        if (!(sc->bge_flags & BGEF_RXRING_VALID))
                return;
 
-       for (i = 0; i < BGE_STD_RX_RING_CNT; i++) {
-               if (sc->bge_cdata.bge_rx_std_chain[i] != NULL) {
-                       m_freem(sc->bge_cdata.bge_rx_std_chain[i]);
+       for (u_int i = 0; i < BGE_STD_RX_RING_CNT; i++) {
+               const bus_dmamap_t dmap = sc->bge_cdata.bge_rx_std_map[i];
+               struct mbuf * const m = sc->bge_cdata.bge_rx_std_chain[i];
+               if (m != NULL) {
+                       bus_dmamap_sync(sc->bge_dmatag, dmap, 0,
+                           dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+                       bus_dmamap_unload(sc->bge_dmatag, dmap);
+                       m_freem(m);
                        sc->bge_cdata.bge_rx_std_chain[i] = NULL;
-                       if (disable) {
-                               bus_dmamap_destroy(sc->bge_dmatag,
-                                   sc->bge_cdata.bge_rx_std_map[i]);
-                               sc->bge_cdata.bge_rx_std_map[i] = NULL;
-                       }
                }
+               bus_dmamap_destroy(sc->bge_dmatag,
+                   sc->bge_cdata.bge_rx_std_map[i]);
+               sc->bge_cdata.bge_rx_std_map[i] = NULL;
                memset((char *)&sc->bge_rdata->bge_rx_std_ring[i], 0,
                    sizeof(struct bge_rx_bd));
        }
@@ -4503,30 +4526,20 @@
                                continue;
                        }
                } else {
-                       BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT);
                        m = sc->bge_cdata.bge_rx_std_chain[rxidx];
-
                        sc->bge_cdata.bge_rx_std_chain[rxidx] = NULL;
+
                        stdcnt++;
+                       sc->bge_std_cnt--;
+
                        dmamap = sc->bge_cdata.bge_rx_std_map[rxidx];
-                       sc->bge_cdata.bge_rx_std_map[rxidx] = NULL;
-                       if (dmamap == NULL) {
-                               if_statinc(ifp, if_ierrors);
-                               bge_newbuf_std(sc, sc->bge_std, m, dmamap);
-                               continue;
-                       }
                        bus_dmamap_sync(sc->bge_dmatag, dmamap, 0,
                            dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
                        bus_dmamap_unload(sc->bge_dmatag, dmamap);
+
                        if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) {
+                               m_free(m);
                                if_statinc(ifp, if_ierrors);
-                               bge_newbuf_std(sc, sc->bge_std, m, dmamap);
-                               continue;
-                       }
-                       if (bge_newbuf_std(sc, sc->bge_std,
-                           NULL, dmamap) == ENOBUFS) {
-                               if_statinc(ifp, if_ierrors);
-                               bge_newbuf_std(sc, sc->bge_std, m, dmamap);
                                continue;
                        }
                }
@@ -4562,7 +4575,7 @@
        sc->bge_rx_saved_considx = rx_cons;
        bge_writembx(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
        if (stdcnt)
-               bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
+               bge_fill_rx_ring_std(sc);
        if (jumbocnt)
                bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
 }
@@ -6197,7 +6210,7 @@
                BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
 
        /* Free the RX lists. */
-       bge_free_rx_ring_std(sc, disable);
+       bge_free_rx_ring_std(sc);
 
        /* Free jumbo RX list. */
        if (BGE_IS_JUMBO_CAPABLE(sc))
diff -r 1c9b6c5c59d1 -r 893e9de5e8e8 sys/dev/pci/if_bgevar.h
--- a/sys/dev/pci/if_bgevar.h   Sun Aug 14 09:01:25 2022 +0000
+++ b/sys/dev/pci/if_bgevar.h   Sun Aug 14 09:03:05 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bgevar.h,v 1.33 2022/08/14 09:01:25 skrll Exp $     */
+/*     $NetBSD: if_bgevar.h,v 1.34 2022/08/14 09:03:05 skrll Exp $     */



Home | Main Index | Thread Index | Old Index