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();