kernel - Adjustments to if_igb
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 11 Dec 2010 02:10:22 +0000 (18:10 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 11 Dec 2010 02:10:22 +0000 (18:10 -0800)
* Change the spin lock to a token.  A spinlock is inappropriate here because
  the thread can block with it held (resulting in a panic).

* Use rid 0 when allocating a legacy interrupt, fixing an issue where
  the interrupt bus resource could not be allocated.

sys/dev/netif/e1000/if_igb.c
sys/dev/netif/e1000/if_igb.h

index c585779..732411f 100644 (file)
@@ -303,7 +303,7 @@ TUNABLE_INT("hw.igb.enable_aim", &igb_enable_aim);
  * MSIX should be the default for best performance,
  * but this allows it to be forced off for testing.
  */         
-static int igb_enable_msix = 1;
+static int igb_enable_msix = 0;
 TUNABLE_INT("hw.igb.enable_msix", &igb_enable_msix);
 
 /*
@@ -2125,10 +2125,12 @@ igb_allocate_legacy(struct adapter *adapter)
        /* Turn off all interrupts */
        E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
 
+#if 0
        /* MSI RID is 1 */
        if (adapter->msix == 1)
                rid = 1;
-
+#endif
+       rid = 0;
        /* We allocate a single interrupt resource */
        adapter->res = bus_alloc_resource_any(dev,
            SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
@@ -2883,7 +2885,7 @@ igb_allocate_queues(struct adapter *adapter)
                ksnprintf(txr->spin_name, sizeof(txr->spin_name), "%s:tx(%d)",
                    device_get_nameunit(dev), txr->me);
 
-               spin_init(&txr->tx_spin);
+               IGB_TX_LOCK_INIT(txr);
 
                if (igb_dma_malloc(adapter, tsize,
                        &txr->txdma, BUS_DMA_NOWAIT)) {
@@ -2923,7 +2925,7 @@ igb_allocate_queues(struct adapter *adapter)
                ksnprintf(rxr->spin_name, sizeof(rxr->spin_name), "%s:rx(%d)",
                    device_get_nameunit(dev), txr->me);
 
-               spin_init(&rxr->rx_spin);
+               IGB_RX_LOCK_INIT(rxr);
 
                if (igb_dma_malloc(adapter, rsize,
                        &rxr->rxdma, BUS_DMA_NOWAIT)) {
@@ -4076,11 +4078,14 @@ igb_free_receive_structures(struct adapter *adapter)
 #ifdef NET_LRO 
                struct lro_ctrl *lro = &rxr->lro;
 #endif
+               IGB_RX_LOCK(rxr);
                igb_free_receive_buffers(rxr);
 #ifdef NET_LRO
                tcp_lro_free(lro);
 #endif
                igb_dma_free(adapter, &rxr->rxdma);
+               IGB_RX_UNLOCK(rxr);
+               IGB_RX_LOCK_DESTROY(rxr);
        }
 
        kfree(adapter->rx_rings, M_DEVBUF);
index d6108a3..5bae967 100644 (file)
@@ -297,7 +297,7 @@ struct igb_queue {
 struct tx_ring {
        struct adapter          *adapter;
        u32                     me;
-       struct spinlock         tx_spin;
+       struct lwkt_token       tx_token;
        char                    spin_name[16];
        struct igb_dma_alloc    txdma;
        struct e1000_tx_desc    *tx_base;
@@ -333,7 +333,7 @@ struct rx_ring {
        bool                    lro_enabled;
        bool                    hdr_split;
        bool                    discard;
-       struct spinlock         rx_spin;
+       struct lwkt_token       rx_token;
        char                    spin_name[16];
        u32                     last_cleaned;
        u32                     next_to_check;
@@ -384,7 +384,7 @@ struct adapter {
        int             if_flags;
        int             max_frame_size;
        int             min_frame_size;
-       struct spinlock core_spin;
+       struct lwkt_token core_token;
        int             igb_insert_vlan_header;
        struct task     rxtx_task;
        struct taskqueue *tq;   /* adapter task queue */
@@ -479,21 +479,26 @@ struct igb_rx_buf {
        bus_dmamap_t    pack_map;       /* bus_dma map for packet */
 };
 
-#define        IGB_CORE_LOCK_INIT(_sc, _name)  spin_init(&(_sc)->core_spin)
-#define        IGB_CORE_LOCK_DESTROY(_sc)      spin_uninit(&(_sc)->core_spin)
-#define        IGB_CORE_LOCK(_sc)              spin_lock(&(_sc)->core_spin)
-#define        IGB_CORE_UNLOCK(_sc)            spin_unlock(&(_sc)->core_spin)
+#define        IGB_CORE_LOCK_INIT(_sc, _name)  lwkt_token_init(&(_sc)->core_token, \
+                                                       1, "igb")
+#define        IGB_CORE_LOCK_DESTROY(_sc)      lwkt_token_uninit(&(_sc)->core_token)
+#define        IGB_CORE_LOCK(_sc)              lwkt_gettoken(&(_sc)->core_token)
+#define        IGB_CORE_UNLOCK(_sc)            lwkt_reltoken(&(_sc)->core_token)
 #define        IGB_CORE_LOCK_ASSERT(_sc)       
 
-#define        IGB_TX_LOCK_DESTROY(_sc)        spin_uninit(&(_sc)->tx_spin)
-#define        IGB_TX_LOCK(_sc)                spin_lock(&(_sc)->tx_spin)
-#define        IGB_TX_UNLOCK(_sc)              spin_unlock(&(_sc)->tx_spin)
-#define        IGB_TX_TRYLOCK(_sc)             spin_trylock(&(_sc)->tx_spin)
+#define        IGB_TX_LOCK_INIT(_sc)           lwkt_token_init(&(_sc)->tx_token, \
+                                                       1, "igbtx")
+#define        IGB_TX_LOCK_DESTROY(_sc)        lwkt_token_uninit(&(_sc)->tx_token)
+#define        IGB_TX_LOCK(_sc)                lwkt_gettoken(&(_sc)->tx_token)
+#define        IGB_TX_UNLOCK(_sc)              lwkt_reltoken(&(_sc)->tx_token)
+#define        IGB_TX_TRYLOCK(_sc)             lwkt_trytoken(&(_sc)->tx_token)
 #define        IGB_TX_LOCK_ASSERT(_sc)         
 
-#define        IGB_RX_LOCK_DESTROY(_sc)        spin_uninit(&(_sc)->rx_spin)
-#define        IGB_RX_LOCK(_sc)                spin_lock(&(_sc)->rx_spin)
-#define        IGB_RX_UNLOCK(_sc)              spin_unlock(&(_sc)->rx_spin)
+#define        IGB_RX_LOCK_INIT(_sc)           lwkt_token_init(&(_sc)->rx_token, \
+                                                       1, "igbrx")
+#define        IGB_RX_LOCK_DESTROY(_sc)        lwkt_token_uninit(&(_sc)->rx_token)
+#define        IGB_RX_LOCK(_sc)                lwkt_gettoken(&(_sc)->rx_token)
+#define        IGB_RX_UNLOCK(_sc)              lwkt_reltoken(&(_sc)->rx_token)
 #define        IGB_TX_LOCK_ASSERT(_sc)         
 
 #endif /* _IGB_H_DEFINED_ */