aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2010-04-27 07:28:10 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-27 17:38:16 -0400
commit212f9934afccf9c97399216b694a7f452526d6da (patch)
treeb759229660e9fe5848bd04f9b15816f15e8c1972
parentc441b8d2cb2194b05550a558d6d95d8944e56a84 (diff)
bnx2: Prevent "scheduling while atomic" warning with cnic, bonding and vlan.
The bonding driver calls ndo_vlan_rx_register() while holding bond->lock. The bnx2 driver calls bnx2_netif_stop() to stop the rx handling while changing the vlgrp. The call also stops the cnic driver which sleeps while the bond->lock is held and cause the warning. This code path only needs to stop the NAPI rx handling while we are changing the vlgrp. Since no reset is going to occur, there is no need to stop cnic in this case. By adding a parameter to bnx2_netif_stop() to skip stopping cnic, we can avoid the warning. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bnx2.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 4c1e51ee8ede..35eec2defadc 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -651,9 +651,10 @@ bnx2_napi_enable(struct bnx2 *bp)
651} 651}
652 652
653static void 653static void
654bnx2_netif_stop(struct bnx2 *bp) 654bnx2_netif_stop(struct bnx2 *bp, bool stop_cnic)
655{ 655{
656 bnx2_cnic_stop(bp); 656 if (stop_cnic)
657 bnx2_cnic_stop(bp);
657 if (netif_running(bp->dev)) { 658 if (netif_running(bp->dev)) {
658 int i; 659 int i;
659 660
@@ -671,14 +672,15 @@ bnx2_netif_stop(struct bnx2 *bp)
671} 672}
672 673
673static void 674static void
674bnx2_netif_start(struct bnx2 *bp) 675bnx2_netif_start(struct bnx2 *bp, bool start_cnic)
675{ 676{
676 if (atomic_dec_and_test(&bp->intr_sem)) { 677 if (atomic_dec_and_test(&bp->intr_sem)) {
677 if (netif_running(bp->dev)) { 678 if (netif_running(bp->dev)) {
678 netif_tx_wake_all_queues(bp->dev); 679 netif_tx_wake_all_queues(bp->dev);
679 bnx2_napi_enable(bp); 680 bnx2_napi_enable(bp);
680 bnx2_enable_int(bp); 681 bnx2_enable_int(bp);
681 bnx2_cnic_start(bp); 682 if (start_cnic)
683 bnx2_cnic_start(bp);
682 } 684 }
683 } 685 }
684} 686}
@@ -6277,12 +6279,12 @@ bnx2_reset_task(struct work_struct *work)
6277 return; 6279 return;
6278 } 6280 }
6279 6281
6280 bnx2_netif_stop(bp); 6282 bnx2_netif_stop(bp, true);
6281 6283
6282 bnx2_init_nic(bp, 1); 6284 bnx2_init_nic(bp, 1);
6283 6285
6284 atomic_set(&bp->intr_sem, 1); 6286 atomic_set(&bp->intr_sem, 1);
6285 bnx2_netif_start(bp); 6287 bnx2_netif_start(bp, true);
6286 rtnl_unlock(); 6288 rtnl_unlock();
6287} 6289}
6288 6290
@@ -6324,7 +6326,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
6324 struct bnx2 *bp = netdev_priv(dev); 6326 struct bnx2 *bp = netdev_priv(dev);
6325 6327
6326 if (netif_running(dev)) 6328 if (netif_running(dev))
6327 bnx2_netif_stop(bp); 6329 bnx2_netif_stop(bp, false);
6328 6330
6329 bp->vlgrp = vlgrp; 6331 bp->vlgrp = vlgrp;
6330 6332
@@ -6335,7 +6337,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
6335 if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) 6337 if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
6336 bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1); 6338 bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
6337 6339
6338 bnx2_netif_start(bp); 6340 bnx2_netif_start(bp, false);
6339} 6341}
6340#endif 6342#endif
6341 6343
@@ -7055,9 +7057,9 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
7055 bp->stats_ticks &= BNX2_HC_STATS_TICKS_HC_STAT_TICKS; 7057 bp->stats_ticks &= BNX2_HC_STATS_TICKS_HC_STAT_TICKS;
7056 7058
7057 if (netif_running(bp->dev)) { 7059 if (netif_running(bp->dev)) {
7058 bnx2_netif_stop(bp); 7060 bnx2_netif_stop(bp, true);
7059 bnx2_init_nic(bp, 0); 7061 bnx2_init_nic(bp, 0);
7060 bnx2_netif_start(bp); 7062 bnx2_netif_start(bp, true);
7061 } 7063 }
7062 7064
7063 return 0; 7065 return 0;
@@ -7087,7 +7089,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
7087 /* Reset will erase chipset stats; save them */ 7089 /* Reset will erase chipset stats; save them */
7088 bnx2_save_stats(bp); 7090 bnx2_save_stats(bp);
7089 7091
7090 bnx2_netif_stop(bp); 7092 bnx2_netif_stop(bp, true);
7091 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); 7093 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
7092 bnx2_free_skbs(bp); 7094 bnx2_free_skbs(bp);
7093 bnx2_free_mem(bp); 7095 bnx2_free_mem(bp);
@@ -7115,7 +7117,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
7115 bnx2_setup_cnic_irq_info(bp); 7117 bnx2_setup_cnic_irq_info(bp);
7116 mutex_unlock(&bp->cnic_lock); 7118 mutex_unlock(&bp->cnic_lock);
7117#endif 7119#endif
7118 bnx2_netif_start(bp); 7120 bnx2_netif_start(bp, true);
7119 } 7121 }
7120 return 0; 7122 return 0;
7121} 7123}
@@ -7368,7 +7370,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
7368 if (etest->flags & ETH_TEST_FL_OFFLINE) { 7370 if (etest->flags & ETH_TEST_FL_OFFLINE) {
7369 int i; 7371 int i;
7370 7372
7371 bnx2_netif_stop(bp); 7373 bnx2_netif_stop(bp, true);
7372 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG); 7374 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
7373 bnx2_free_skbs(bp); 7375 bnx2_free_skbs(bp);
7374 7376
@@ -7387,7 +7389,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
7387 bnx2_shutdown_chip(bp); 7389 bnx2_shutdown_chip(bp);
7388 else { 7390 else {
7389 bnx2_init_nic(bp, 1); 7391 bnx2_init_nic(bp, 1);
7390 bnx2_netif_start(bp); 7392 bnx2_netif_start(bp, true);
7391 } 7393 }
7392 7394
7393 /* wait for link up */ 7395 /* wait for link up */
@@ -8381,7 +8383,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
8381 return 0; 8383 return 0;
8382 8384
8383 flush_scheduled_work(); 8385 flush_scheduled_work();
8384 bnx2_netif_stop(bp); 8386 bnx2_netif_stop(bp, true);
8385 netif_device_detach(dev); 8387 netif_device_detach(dev);
8386 del_timer_sync(&bp->timer); 8388 del_timer_sync(&bp->timer);
8387 bnx2_shutdown_chip(bp); 8389 bnx2_shutdown_chip(bp);
@@ -8403,7 +8405,7 @@ bnx2_resume(struct pci_dev *pdev)
8403 bnx2_set_power_state(bp, PCI_D0); 8405 bnx2_set_power_state(bp, PCI_D0);
8404 netif_device_attach(dev); 8406 netif_device_attach(dev);
8405 bnx2_init_nic(bp, 1); 8407 bnx2_init_nic(bp, 1);
8406 bnx2_netif_start(bp); 8408 bnx2_netif_start(bp, true);
8407 return 0; 8409 return 0;
8408} 8410}
8409 8411
@@ -8430,7 +8432,7 @@ static pci_ers_result_t bnx2_io_error_detected(struct pci_dev *pdev,
8430 } 8432 }
8431 8433
8432 if (netif_running(dev)) { 8434 if (netif_running(dev)) {
8433 bnx2_netif_stop(bp); 8435 bnx2_netif_stop(bp, true);
8434 del_timer_sync(&bp->timer); 8436 del_timer_sync(&bp->timer);
8435 bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET); 8437 bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
8436 } 8438 }
@@ -8487,7 +8489,7 @@ static void bnx2_io_resume(struct pci_dev *pdev)
8487 8489
8488 rtnl_lock(); 8490 rtnl_lock();
8489 if (netif_running(dev)) 8491 if (netif_running(dev))
8490 bnx2_netif_start(bp); 8492 bnx2_netif_start(bp, true);
8491 8493
8492 netif_device_attach(dev); 8494 netif_device_attach(dev);
8493 rtnl_unlock(); 8495 rtnl_unlock();