Commit 58e7cd24 authored by Mark Rustad's avatar Mark Rustad Committed by Jeff Kirsher

ixgbe: Limit SFP polling rate

Reduce the frequency of polling for SFP modules. Because the
service task sometimes runs at high rates, we can poll for
SFPs too often. When an SFP is not present, the I2C timeouts
that result are very costly. So, prevent SFP polling from
being done more than once every two seconds. To reduce latency,
the poll time is cleared in a couple of cases to permit the
next service task execution to poll the SFP module.
Signed-off-by: default avatarMark Rustad <mark.d.rustad@intel.com>
Tested-by: default avatarPhil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 69eec0c2
...@@ -594,6 +594,7 @@ struct ixgbe_mac_addr { ...@@ -594,6 +594,7 @@ struct ixgbe_mac_addr {
/* default to trying for four seconds */ /* default to trying for four seconds */
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ) #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
#define IXGBE_SFP_POLL_JIFFIES (2 * HZ) /* SFP poll every 2 seconds */
/* board specific private data structure */ /* board specific private data structure */
struct ixgbe_adapter { struct ixgbe_adapter {
...@@ -707,6 +708,7 @@ struct ixgbe_adapter { ...@@ -707,6 +708,7 @@ struct ixgbe_adapter {
u32 link_speed; u32 link_speed;
bool link_up; bool link_up;
unsigned long sfp_poll_time;
unsigned long link_check_timeout; unsigned long link_check_timeout;
struct timer_list service_timer; struct timer_list service_timer;
......
...@@ -2509,6 +2509,7 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr) ...@@ -2509,6 +2509,7 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask);
if (!test_bit(__IXGBE_DOWN, &adapter->state)) { if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
adapter->sfp_poll_time = 0;
ixgbe_service_event_schedule(adapter); ixgbe_service_event_schedule(adapter);
} }
} }
...@@ -4804,6 +4805,7 @@ static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter) ...@@ -4804,6 +4805,7 @@ static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
adapter->sfp_poll_time = 0;
} }
/** /**
...@@ -6709,10 +6711,16 @@ static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter) ...@@ -6709,10 +6711,16 @@ static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter)
!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET)) !(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
return; return;
if (adapter->sfp_poll_time &&
time_after(adapter->sfp_poll_time, jiffies))
return; /* If not yet time to poll for SFP */
/* someone else is in init, wait until next service event */ /* someone else is in init, wait until next service event */
if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state)) if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
return; return;
adapter->sfp_poll_time = jiffies + IXGBE_SFP_POLL_JIFFIES - 1;
err = hw->phy.ops.identify_sfp(hw); err = hw->phy.ops.identify_sfp(hw);
if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
goto sfp_out; goto sfp_out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment