Just playing around with the bnx driver. If I attach via MSI, I get
watchdog errors (but that is a different issue). After the watchdog
errors, I get 8 or so splasserts.
This diff stops the splasserts from happening.
- don't bother with read/write lock
- put pool_init into bnx_attach instead of bnx_init, since it really
only needs to be called once.
- Change pool_get to not PR_NOWAIT.
I am using this diff in production currently passing 450Mbps both in and
out.
Thoughts?
Index: if_bnx.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_bnx.c,v
retrieving revision 1.100
diff -N -u -p if_bnx.c
--- if_bnx.c 13 Jan 2013 05:45:10 -0000 1.100
+++ if_bnx.c 22 Jan 2013 14:40:01 -0000
@@ -388,10 +388,10 @@ void bnx_iff(struct bnx_softc *);
void bnx_stats_update(struct bnx_softc *);
void bnx_tick(void *);
-struct rwlock bnx_tx_pool_lk = RWLOCK_INITIALIZER("bnxplinit");
-struct pool *bnx_tx_pool = NULL;
+struct pool *bnx_tx_pool;
void bnx_alloc_pkts(void *, void *);
+
/****************************************************************************/
/* OpenBSD device dispatch table. */
/****************************************************************************/
@@ -654,6 +654,16 @@ bnx_attach(struct device *parent, struct device *self,
sc->bnx_pa = *pa;
+ if (bnx_tx_pool == NULL) {
+ bnx_tx_pool = malloc(sizeof(*bnx_tx_pool), M_DEVBUF, M_NOWAIT);
+ if (bnx_tx_pool == NULL) {
+ printf(": unable to allocate tx pool\n");
+ goto bnx_attach_fail;
+ }
+ pool_init(bnx_tx_pool, sizeof(struct bnx_pkt), 0, 0, 0,
+ "bnxpkts", &pool_allocator_nointr);
+ }
+
/*
* Map control/status registers.
*/
@@ -3766,13 +3776,13 @@ bnx_alloc_pkts(void *xsc, void *arg)
int s;
for (i = 0; i < 4; i++) { /* magic! */
- pkt = pool_get(bnx_tx_pool, PR_WAITOK);
+ pkt = pool_get(bnx_tx_pool, PR_NOWAIT | PR_ZERO);
if (pkt == NULL)
break;
if (bus_dmamap_create(sc->bnx_dmatag,
MCLBYTES * BNX_MAX_SEGMENTS, USABLE_TX_BD,
- MCLBYTES, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
+ MCLBYTES, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
&pkt->pkt_dmamap) != 0)
goto put;
@@ -4743,25 +4753,9 @@ bnx_init(void *xsc)
struct bnx_softc *sc = (struct bnx_softc *)xsc;
struct ifnet *ifp = &sc->arpcom.ac_if;
u_int32_t ether_mtu;
- int txpl = 1;
int s;
DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
-
- if (rw_enter(&bnx_tx_pool_lk, RW_WRITE | RW_INTR) != 0)
- return;
- if (bnx_tx_pool == NULL) {
- bnx_tx_pool = malloc(sizeof(*bnx_tx_pool), M_DEVBUF, M_WAITOK);
- if (bnx_tx_pool != NULL) {
- pool_init(bnx_tx_pool, sizeof(struct bnx_pkt),
- 0, 0, 0, "bnxpkts", &pool_allocator_nointr);
- } else
- txpl = 0;
- }
- rw_exit(&bnx_tx_pool_lk);
-
- if (!txpl)
- return;
s = splnet();