aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_main.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2011-04-27 09:21:16 +0000
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-05-14 18:04:28 -0700
commitc83c6cbdbff360e5323748720dfb2b000c0ae491 (patch)
treed4fc5dea8dde49b6439516e7f9c054102c5a6701 /drivers/net/ixgbe/ixgbe_main.c
parentixgbe: Merge watchdog functionality into service task (diff)
downloadlinux-dev-c83c6cbdbff360e5323748720dfb2b000c0ae491.tar.xz
linux-dev-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.c60
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);