Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57ca2a4f authored by Emil Tantilov's avatar Emil Tantilov Committed by Jeff Kirsher
Browse files

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: default avatarEmil Tantilov <emil.s.tantilov@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent ee95053f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -653,7 +653,6 @@ struct ixgbe_adapter {
#define IXGBE_FLAG2_TEMP_SENSOR_EVENT		BIT(3)
#define IXGBE_FLAG2_SEARCH_FOR_SFP		BIT(4)
#define IXGBE_FLAG2_SFP_NEEDS_RESET		BIT(5)
#define IXGBE_FLAG2_RESET_REQUESTED		BIT(6)
#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT	BIT(7)
#define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP		BIT(8)
#define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP		BIT(9)
@@ -840,6 +839,7 @@ enum ixgbe_state_t {
	__IXGBE_IN_SFP_INIT,
	__IXGBE_PTP_RUNNING,
	__IXGBE_PTP_TX_IN_PROGRESS,
	__IXGBE_RESET_REQUESTED,
};

struct ixgbe_cb {
+7 −9
Original line number Diff line number Diff line
@@ -1103,7 +1103,7 @@ 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;
		set_bit(__IXGBE_RESET_REQUESTED, &adapter->state);
		e_warn(drv, "initiating reset due to tx timeout\n");
		ixgbe_service_event_schedule(adapter);
	}
@@ -2777,7 +2777,7 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data)
		}
		if (eicr & IXGBE_EICR_ECC) {
			e_info(link, "Received ECC Err, initiating reset\n");
			adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
			set_bit(__IXGBE_RESET_REQUESTED, &adapter->state);
			ixgbe_service_event_schedule(adapter);
			IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC);
		}
@@ -3007,7 +3007,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
	case ixgbe_mac_x550em_a:
		if (eicr & IXGBE_EICR_ECC) {
			e_info(link, "Received ECC Err, initiating reset\n");
			adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
			set_bit(__IXGBE_RESET_REQUESTED, &adapter->state);
			ixgbe_service_event_schedule(adapter);
			IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC);
		}
@@ -5500,8 +5500,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)

	ixgbe_napi_disable_all(adapter);

	adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
			     IXGBE_FLAG2_RESET_REQUESTED);
	clear_bit(__IXGBE_RESET_REQUESTED, &adapter->state);
	adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
	adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;

	del_timer_sync(&adapter->service_timer);
@@ -6921,7 +6921,7 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)
			 * (Do the reset outside of interrupt context).
			 */
			e_warn(drv, "initiating reset to clear Tx work after link loss\n");
			adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
			set_bit(__IXGBE_RESET_REQUESTED, &adapter->state);
		}
	}
}
@@ -7187,11 +7187,9 @@ static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter)

static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
{
	if (!(adapter->flags2 & IXGBE_FLAG2_RESET_REQUESTED))
	if (!test_and_clear_bit(__IXGBE_RESET_REQUESTED, &adapter->state))
		return;

	adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED;

	/* If we're already down, removing or resetting, just bail */
	if (test_bit(__IXGBE_DOWN, &adapter->state) ||
	    test_bit(__IXGBE_REMOVING, &adapter->state) ||