Module Name: src
Committed By: skrll
Date: Sun Aug 14 09:03:05 UTC 2022
Modified Files:
src/sys/dev/pci: if_bge.c if_bgevar.h
Log Message:
bge: Mirror the bus_dma RX buffer changes in the OpenBSD driver
This change reduces the amount of work done in the interrupt handler.
To generate a diff of this commit:
cvs rdiff -u -r1.375 -r1.376 src/sys/dev/pci/if_bge.c
cvs rdiff -u -r1.33 -r1.34 src/sys/dev/pci/if_bgevar.h
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_bge.c
diff -u src/sys/dev/pci/if_bge.c:1.375 src/sys/dev/pci/if_bge.c:1.376
--- src/sys/dev/pci/if_bge.c:1.375 Sun Aug 14 09:01:25 2022
+++ src/sys/dev/pci/if_bge.c Sun Aug 14 09:03:05 2022
@@ -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 int bge_alloc_jumbo_mem(struct bg
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 @@ bge_jfree(struct mbuf *m, void *buf, siz
* 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;
+ const bus_dmamap_t dmamap = sc->bge_cdata.bge_rx_std_map[i];
+ struct mbuf *m;
- if (dmamap == NULL)
- dmamap = sc->bge_cdata.bge_rx_std_map[i];
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL)
+ return ENOBUFS;
- if (dmamap == NULL) {
- error = bus_dmamap_create(sc->bge_dmatag, MCLBYTES, 1,
- MCLBYTES, 0, BUS_DMA_NOWAIT, &dmamap);
- if (error != 0)
- return error;
+ MCLGET(m, M_DONTWAIT);
+ if (!(m->m_flags & M_EXT)) {
+ m_freem(m);
+ return ENOBUFS;
}
+ m->m_len = m->m_pkthdr.len = MCLBYTES;
- 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;
- }
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;
- sc->bge_cdata.bge_rx_std_chain[i] = m_new;
- r = &sc->bge_rdata->bge_rx_std_ring[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_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 @@ bge_newbuf_jumbo(struct bge_softc *sc, i
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 = 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)
{
- int i;
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 @@ bge_rxeof(struct bge_softc *sc)
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 @@ bge_rxeof(struct bge_softc *sc)
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_stop_locked(struct ifnet *ifp, int d
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))
Index: src/sys/dev/pci/if_bgevar.h
diff -u src/sys/dev/pci/if_bgevar.h:1.33 src/sys/dev/pci/if_bgevar.h:1.34
--- src/sys/dev/pci/if_bgevar.h:1.33 Sun Aug 14 09:01:25 2022
+++ src/sys/dev/pci/if_bgevar.h Sun Aug 14 09:03:05 2022
@@ -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 $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2001
@@ -308,6 +308,7 @@ struct bge_softc {
uint16_t bge_rx_saved_considx;
uint16_t bge_ev_saved_considx;
uint16_t bge_std; /* current std ring head */
+ uint16_t bge_std_cnt;
uint16_t bge_jumbo; /* current jumo ring head */
SLIST_HEAD(__bge_jfreehead, bge_jpool_entry) bge_jfree_listhead;
SLIST_HEAD(__bge_jinusehead, bge_jpool_entry) bge_jinuse_listhead;