diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2011-04-27 11:21:16 +0200 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-05-15 03:04:28 +0200 |
commit | c83c6cbdbff360e5323748720dfb2b000c0ae491 (patch) | |
tree | d4fc5dea8dde49b6439516e7f9c054102c5a6701 /drivers/net/ixgbe/ixgbe_main.c | |
parent | ixgbe: Merge watchdog functionality into service task (diff) | |
download | linux-c83c6cbdbff360e5323748720dfb2b000c0ae491.tar.xz linux-c83c6cbdbff360e5323748720dfb2b000c0ae491.zip |
ixgbe: merge reset task into service task
This change is meant to further help to reduce possible configuration
collisions between the various tasklets. This change combines the device
reset with the service task. As a result it is now not possible to be
updating the link on the device while also resetting the part.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Evan Swanson <evan.swanson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_main.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 60 |
1 files changed, 37 insertions, 23 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index d1e52b5cebfa..dbb20e57f660 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -833,7 +833,19 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring) #define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \ MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */ -static void ixgbe_tx_timeout(struct net_device *netdev); +/** + * ixgbe_tx_timeout_reset - initiate reset due to Tx timeout + * @adapter: driver private struct + **/ +static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter) +{ + + /* Do the reset outside of interrupt context */ + if (!test_bit(__IXGBE_DOWN, &adapter->state)) { + adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; + ixgbe_service_event_schedule(adapter); + } +} /** * ixgbe_clean_tx_irq - Reclaim resources after transmit completes @@ -915,7 +927,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, adapter->tx_timeout_count + 1, tx_ring->queue_index); /* schedule immediate reset if we believe we hung */ - ixgbe_tx_timeout(adapter->netdev); + ixgbe_tx_timeout_reset(adapter); /* the adapter is about to reset, no point in enabling stuff */ return true; @@ -4186,6 +4198,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ixgbe_napi_disable_all(adapter); + adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED; adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; del_timer_sync(&adapter->service_timer); @@ -4288,25 +4301,8 @@ static void ixgbe_tx_timeout(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - adapter->tx_timeout_count++; - /* Do the reset outside of interrupt context */ - schedule_work(&adapter->reset_task); -} - -static void ixgbe_reset_task(struct work_struct *work) -{ - struct ixgbe_adapter *adapter; - adapter = container_of(work, struct ixgbe_adapter, reset_task); - - /* If we're already down or resetting, just bail */ - if (test_bit(__IXGBE_DOWN, &adapter->state) || - test_bit(__IXGBE_RESETTING, &adapter->state)) - return; - - ixgbe_dump(adapter); - netdev_err(adapter->netdev, "Reset adapter\n"); - ixgbe_reinit_locked(adapter); + ixgbe_tx_timeout_reset(adapter); } /** @@ -6174,7 +6170,7 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter) * to get done, so reset controller to flush Tx. * (Do the reset outside of interrupt context). */ - schedule_work(&adapter->reset_task); + adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; } } } @@ -6341,6 +6337,25 @@ static void ixgbe_service_timer(unsigned long data) ixgbe_service_event_schedule(adapter); } +static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter) +{ + if (!(adapter->flags2 & IXGBE_FLAG2_RESET_REQUESTED)) + return; + + adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED; + + /* If we're already down or resetting, just bail */ + if (test_bit(__IXGBE_DOWN, &adapter->state) || + test_bit(__IXGBE_RESETTING, &adapter->state)) + return; + + ixgbe_dump(adapter); + netdev_err(adapter->netdev, "Reset adapter\n"); + adapter->tx_timeout_count++; + + ixgbe_reinit_locked(adapter); +} + /** * ixgbe_service_task - manages and runs subtasks * @work: pointer to work_struct containing our data @@ -6351,6 +6366,7 @@ static void ixgbe_service_task(struct work_struct *work) struct ixgbe_adapter, service_task); + ixgbe_reset_subtask(adapter); ixgbe_sfp_detection_subtask(adapter); ixgbe_sfp_link_config_subtask(adapter); ixgbe_watchdog_subtask(adapter); @@ -7533,8 +7549,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, setup_timer(&adapter->service_timer, &ixgbe_service_timer, (unsigned long) adapter); - INIT_WORK(&adapter->reset_task, ixgbe_reset_task); - INIT_WORK(&adapter->service_task, ixgbe_service_task); clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state); |