diff options
author | John Fastabend <john.r.fastabend@intel.com> | 2010-04-26 22:13:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-27 15:53:29 -0400 |
commit | c0dfb90e5b2d41c907de9b624657a6688541837e (patch) | |
tree | ce662b4bb4c737c4e398ea98e229784b396ac7f5 /drivers/net/ixgbe/ixgbe_main.c | |
parent | ff846f52935e6c8dfb0c97df7c2c1bf777454684 (diff) |
ixgbe: ixgbe_down needs to stop dev_watchdog
There is a small race between when the tx queues are stopped
and when netif_carrier_off() is called in ixgbe_down. If the
dev_watchdog() timer fires during this time it is possible for
a false tx timeout to occur.
This patch moves the netif_carrier_off() so that it is called before
the tx queues are stopped preventing the dev_watchdog timer from
detecting false tx timeouts. The race is seen occosionally when
FCoE or DCB settings are being configured or changed.
Testing note, running ifconfig up/down will not reproduce this
issue because dev_open/dev_close call dev_deactivate() and then
dev_activate().
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_main.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fe7e260e0157..5258b3d6405b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -3291,22 +3291,23 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
3291 | rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); | 3291 | rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); |
3292 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); | 3292 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); |
3293 | 3293 | ||
3294 | netif_tx_disable(netdev); | ||
3295 | |||
3296 | IXGBE_WRITE_FLUSH(hw); | 3294 | IXGBE_WRITE_FLUSH(hw); |
3297 | msleep(10); | 3295 | msleep(10); |
3298 | 3296 | ||
3299 | netif_tx_stop_all_queues(netdev); | 3297 | netif_tx_stop_all_queues(netdev); |
3300 | 3298 | ||
3301 | ixgbe_irq_disable(adapter); | ||
3302 | |||
3303 | ixgbe_napi_disable_all(adapter); | ||
3304 | |||
3305 | clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); | 3299 | clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); |
3306 | del_timer_sync(&adapter->sfp_timer); | 3300 | del_timer_sync(&adapter->sfp_timer); |
3307 | del_timer_sync(&adapter->watchdog_timer); | 3301 | del_timer_sync(&adapter->watchdog_timer); |
3308 | cancel_work_sync(&adapter->watchdog_task); | 3302 | cancel_work_sync(&adapter->watchdog_task); |
3309 | 3303 | ||
3304 | netif_carrier_off(netdev); | ||
3305 | netif_tx_disable(netdev); | ||
3306 | |||
3307 | ixgbe_irq_disable(adapter); | ||
3308 | |||
3309 | ixgbe_napi_disable_all(adapter); | ||
3310 | |||
3310 | if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || | 3311 | if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || |
3311 | adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) | 3312 | adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) |
3312 | cancel_work_sync(&adapter->fdir_reinit_task); | 3313 | cancel_work_sync(&adapter->fdir_reinit_task); |
@@ -3324,8 +3325,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
3324 | (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & | 3325 | (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & |
3325 | ~IXGBE_DMATXCTL_TE)); | 3326 | ~IXGBE_DMATXCTL_TE)); |
3326 | 3327 | ||
3327 | netif_carrier_off(netdev); | ||
3328 | |||
3329 | /* clear n-tuple filters that are cached */ | 3328 | /* clear n-tuple filters that are cached */ |
3330 | ethtool_ntuple_flush(netdev); | 3329 | ethtool_ntuple_flush(netdev); |
3331 | 3330 | ||