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

Reply via email to