aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2010-06-01 11:05:36 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-02 05:26:40 -0400
commitf048fa9c8686119c3858a463cab6121dced7c0bf (patch)
treec68dd0cc095559c348c8916b6e3372b4e0610e9a /drivers/net/bnx2.c
parentfafeeb6c80e3842c6dc19d05de09a23f23eef0d8 (diff)
bnx2: Fix hang during rmmod bnx2.
The regression is caused by: commit 4327ba435a56ada13eedf3eb332e583c7a0586a9 bnx2: Fix netpoll crash. If ->open() and ->close() are called multiple times, the same napi structs will be added to dev->napi_list multiple times, corrupting the dev->napi_list. This causes free_netdev() to hang during rmmod. We fix this by calling netif_napi_del() during ->close(). Also, bnx2_init_napi() must not be in the __devinit section since it is called by ->open(). Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: Benjamin Li <benli@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r--drivers/net/bnx2.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 188e356c30a3..949d7a9dcf92 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -247,6 +247,7 @@ static const struct flash_spec flash_5709 = {
247MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); 247MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
248 248
249static void bnx2_init_napi(struct bnx2 *bp); 249static void bnx2_init_napi(struct bnx2 *bp);
250static void bnx2_del_napi(struct bnx2 *bp);
250 251
251static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) 252static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
252{ 253{
@@ -6270,6 +6271,7 @@ open_err:
6270 bnx2_free_skbs(bp); 6271 bnx2_free_skbs(bp);
6271 bnx2_free_irq(bp); 6272 bnx2_free_irq(bp);
6272 bnx2_free_mem(bp); 6273 bnx2_free_mem(bp);
6274 bnx2_del_napi(bp);
6273 return rc; 6275 return rc;
6274} 6276}
6275 6277
@@ -6537,6 +6539,7 @@ bnx2_close(struct net_device *dev)
6537 bnx2_free_irq(bp); 6539 bnx2_free_irq(bp);
6538 bnx2_free_skbs(bp); 6540 bnx2_free_skbs(bp);
6539 bnx2_free_mem(bp); 6541 bnx2_free_mem(bp);
6542 bnx2_del_napi(bp);
6540 bp->link_up = 0; 6543 bp->link_up = 0;
6541 netif_carrier_off(bp->dev); 6544 netif_carrier_off(bp->dev);
6542 bnx2_set_power_state(bp, PCI_D3hot); 6545 bnx2_set_power_state(bp, PCI_D3hot);
@@ -8227,7 +8230,16 @@ bnx2_bus_string(struct bnx2 *bp, char *str)
8227 return str; 8230 return str;
8228} 8231}
8229 8232
8230static void __devinit 8233static void
8234bnx2_del_napi(struct bnx2 *bp)
8235{
8236 int i;
8237
8238 for (i = 0; i < bp->irq_nvecs; i++)
8239 netif_napi_del(&bp->bnx2_napi[i].napi);
8240}
8241
8242static void
8231bnx2_init_napi(struct bnx2 *bp) 8243bnx2_init_napi(struct bnx2 *bp)
8232{ 8244{
8233 int i; 8245 int i;