diff options
author | Emil Tantilov <emil.s.tantilov@intel.com> | 2016-07-29 17:46:31 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2016-08-19 01:47:52 -0400 |
commit | 57ca2a4fed520ee85a8fe809ff1947ec7c25aec9 (patch) | |
tree | 10ad11c6c68fccc3cd549e217244a8f7c7b1863f /drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |
parent | ee95053f78ee6883a6aeb75e346346adc0f4aded (diff) |
ixgbe: use atomic bitwise operations when handling reset requests
Use atomic bitwise operations when setting and checking reset
requests. This should help with possible races in the service task.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_main.c')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index bbbc5b836923..6bf131faa65e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -1103,7 +1103,7 @@ static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter) | |||
1103 | 1103 | ||
1104 | /* Do the reset outside of interrupt context */ | 1104 | /* Do the reset outside of interrupt context */ |
1105 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) { | 1105 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) { |
1106 | adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; | 1106 | set_bit(__IXGBE_RESET_REQUESTED, &adapter->state); |
1107 | e_warn(drv, "initiating reset due to tx timeout\n"); | 1107 | e_warn(drv, "initiating reset due to tx timeout\n"); |
1108 | ixgbe_service_event_schedule(adapter); | 1108 | ixgbe_service_event_schedule(adapter); |
1109 | } | 1109 | } |
@@ -2777,7 +2777,7 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data) | |||
2777 | } | 2777 | } |
2778 | if (eicr & IXGBE_EICR_ECC) { | 2778 | if (eicr & IXGBE_EICR_ECC) { |
2779 | e_info(link, "Received ECC Err, initiating reset\n"); | 2779 | e_info(link, "Received ECC Err, initiating reset\n"); |
2780 | adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; | 2780 | set_bit(__IXGBE_RESET_REQUESTED, &adapter->state); |
2781 | ixgbe_service_event_schedule(adapter); | 2781 | ixgbe_service_event_schedule(adapter); |
2782 | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); | 2782 | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); |
2783 | } | 2783 | } |
@@ -3007,7 +3007,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data) | |||
3007 | case ixgbe_mac_x550em_a: | 3007 | case ixgbe_mac_x550em_a: |
3008 | if (eicr & IXGBE_EICR_ECC) { | 3008 | if (eicr & IXGBE_EICR_ECC) { |
3009 | e_info(link, "Received ECC Err, initiating reset\n"); | 3009 | e_info(link, "Received ECC Err, initiating reset\n"); |
3010 | adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; | 3010 | set_bit(__IXGBE_RESET_REQUESTED, &adapter->state); |
3011 | ixgbe_service_event_schedule(adapter); | 3011 | ixgbe_service_event_schedule(adapter); |
3012 | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); | 3012 | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); |
3013 | } | 3013 | } |
@@ -5500,8 +5500,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
5500 | 5500 | ||
5501 | ixgbe_napi_disable_all(adapter); | 5501 | ixgbe_napi_disable_all(adapter); |
5502 | 5502 | ||
5503 | adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT | | 5503 | clear_bit(__IXGBE_RESET_REQUESTED, &adapter->state); |
5504 | IXGBE_FLAG2_RESET_REQUESTED); | 5504 | adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT; |
5505 | adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; | 5505 | adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; |
5506 | 5506 | ||
5507 | del_timer_sync(&adapter->service_timer); | 5507 | del_timer_sync(&adapter->service_timer); |
@@ -6921,7 +6921,7 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter) | |||
6921 | * (Do the reset outside of interrupt context). | 6921 | * (Do the reset outside of interrupt context). |
6922 | */ | 6922 | */ |
6923 | e_warn(drv, "initiating reset to clear Tx work after link loss\n"); | 6923 | e_warn(drv, "initiating reset to clear Tx work after link loss\n"); |
6924 | adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; | 6924 | set_bit(__IXGBE_RESET_REQUESTED, &adapter->state); |
6925 | } | 6925 | } |
6926 | } | 6926 | } |
6927 | } | 6927 | } |
@@ -7187,11 +7187,9 @@ static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter) | |||
7187 | 7187 | ||
7188 | static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter) | 7188 | static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter) |
7189 | { | 7189 | { |
7190 | if (!(adapter->flags2 & IXGBE_FLAG2_RESET_REQUESTED)) | 7190 | if (!test_and_clear_bit(__IXGBE_RESET_REQUESTED, &adapter->state)) |
7191 | return; | 7191 | return; |
7192 | 7192 | ||
7193 | adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED; | ||
7194 | |||
7195 | /* If we're already down, removing or resetting, just bail */ | 7193 | /* If we're already down, removing or resetting, just bail */ |
7196 | if (test_bit(__IXGBE_DOWN, &adapter->state) || | 7194 | if (test_bit(__IXGBE_DOWN, &adapter->state) || |
7197 | test_bit(__IXGBE_REMOVING, &adapter->state) || | 7195 | test_bit(__IXGBE_REMOVING, &adapter->state) || |