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;

Reply via email to