Skip to content

Commit

Permalink
bnx2: Prevent "scheduling while atomic" warning with cnic, bonding an…
Browse files Browse the repository at this point in the history
…d 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>
  • Loading branch information
Michael Chan authored and David S. Miller committed Apr 27, 2010
1 parent c441b8d commit 212f993
Showing 1 changed file with 20 additions and 18 deletions.
38 changes: 20 additions & 18 deletions drivers/net/bnx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,9 +651,10 @@ bnx2_napi_enable(struct bnx2 *bp)
}

static void
bnx2_netif_stop(struct bnx2 *bp)
bnx2_netif_stop(struct bnx2 *bp, bool stop_cnic)
{
bnx2_cnic_stop(bp);
if (stop_cnic)
bnx2_cnic_stop(bp);
if (netif_running(bp->dev)) {
int i;

Expand All @@ -671,14 +672,15 @@ bnx2_netif_stop(struct bnx2 *bp)
}

static void
bnx2_netif_start(struct bnx2 *bp)
bnx2_netif_start(struct bnx2 *bp, bool start_cnic)
{
if (atomic_dec_and_test(&bp->intr_sem)) {
if (netif_running(bp->dev)) {
netif_tx_wake_all_queues(bp->dev);
bnx2_napi_enable(bp);
bnx2_enable_int(bp);
bnx2_cnic_start(bp);
if (start_cnic)
bnx2_cnic_start(bp);
}
}
}
Expand Down Expand Up @@ -6277,12 +6279,12 @@ bnx2_reset_task(struct work_struct *work)
return;
}

bnx2_netif_stop(bp);
bnx2_netif_stop(bp, true);

bnx2_init_nic(bp, 1);

atomic_set(&bp->intr_sem, 1);
bnx2_netif_start(bp);
bnx2_netif_start(bp, true);
rtnl_unlock();
}

Expand Down Expand Up @@ -6324,7 +6326,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
struct bnx2 *bp = netdev_priv(dev);

if (netif_running(dev))
bnx2_netif_stop(bp);
bnx2_netif_stop(bp, false);

bp->vlgrp = vlgrp;

Expand All @@ -6335,7 +6337,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);

bnx2_netif_start(bp);
bnx2_netif_start(bp, false);
}
#endif

Expand Down Expand Up @@ -7055,9 +7057,9 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
bp->stats_ticks &= BNX2_HC_STATS_TICKS_HC_STAT_TICKS;

if (netif_running(bp->dev)) {
bnx2_netif_stop(bp);
bnx2_netif_stop(bp, true);
bnx2_init_nic(bp, 0);
bnx2_netif_start(bp);
bnx2_netif_start(bp, true);
}

return 0;
Expand Down Expand Up @@ -7087,7 +7089,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
/* Reset will erase chipset stats; save them */
bnx2_save_stats(bp);

bnx2_netif_stop(bp);
bnx2_netif_stop(bp, true);
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
bnx2_free_skbs(bp);
bnx2_free_mem(bp);
Expand Down Expand Up @@ -7115,7 +7117,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
bnx2_setup_cnic_irq_info(bp);
mutex_unlock(&bp->cnic_lock);
#endif
bnx2_netif_start(bp);
bnx2_netif_start(bp, true);
}
return 0;
}
Expand Down Expand Up @@ -7368,7 +7370,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
if (etest->flags & ETH_TEST_FL_OFFLINE) {
int i;

bnx2_netif_stop(bp);
bnx2_netif_stop(bp, true);
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
bnx2_free_skbs(bp);

Expand All @@ -7387,7 +7389,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
bnx2_shutdown_chip(bp);
else {
bnx2_init_nic(bp, 1);
bnx2_netif_start(bp);
bnx2_netif_start(bp, true);
}

/* wait for link up */
Expand Down Expand Up @@ -8381,7 +8383,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;

flush_scheduled_work();
bnx2_netif_stop(bp);
bnx2_netif_stop(bp, true);
netif_device_detach(dev);
del_timer_sync(&bp->timer);
bnx2_shutdown_chip(bp);
Expand All @@ -8403,7 +8405,7 @@ bnx2_resume(struct pci_dev *pdev)
bnx2_set_power_state(bp, PCI_D0);
netif_device_attach(dev);
bnx2_init_nic(bp, 1);
bnx2_netif_start(bp);
bnx2_netif_start(bp, true);
return 0;
}

Expand All @@ -8430,7 +8432,7 @@ static pci_ers_result_t bnx2_io_error_detected(struct pci_dev *pdev,
}

if (netif_running(dev)) {
bnx2_netif_stop(bp);
bnx2_netif_stop(bp, true);
del_timer_sync(&bp->timer);
bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
}
Expand Down Expand Up @@ -8487,7 +8489,7 @@ static void bnx2_io_resume(struct pci_dev *pdev)

rtnl_lock();
if (netif_running(dev))
bnx2_netif_start(bp);
bnx2_netif_start(bp, true);

netif_device_attach(dev);
rtnl_unlock();
Expand Down

0 comments on commit 212f993

Please sign in to comment.