From fa95960535b3c306963dd973a721c2ce20428aca Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 10 Dec 2010 18:10:22 -0800 Subject: [PATCH] kernel - Adjustments to if_igb * 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 | 13 +++++++++---- sys/dev/netif/e1000/if_igb.h | 33 +++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/sys/dev/netif/e1000/if_igb.c b/sys/dev/netif/e1000/if_igb.c index c58577913c..732411f4dc 100644 --- a/sys/dev/netif/e1000/if_igb.c +++ b/sys/dev/netif/e1000/if_igb.c @@ -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); diff --git a/sys/dev/netif/e1000/if_igb.h b/sys/dev/netif/e1000/if_igb.h index d6108a3afb..5bae9671f7 100644 --- a/sys/dev/netif/e1000/if_igb.h +++ b/sys/dev/netif/e1000/if_igb.h @@ -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_ */ -- 2.41.0