Commit 80fba3f4 authored by Alexander Duyck's avatar Alexander Duyck Committed by Jeff Kirsher

ixgbe: Disable RSC when ITR setting is too high to allow RSC

RSC will flush its descriptors every time the interrupt throttle timer
expires.  In addition there are known issues with RSC when the rx-usecs
value is set too low.  As such we are forced to clear the RSC_ENABLED bit
and reset the adapter when the rx-usecs value is set too low.

However we do not need to clear the NETIF_F_LRO flag because it is used to
indicate that the user wants to leave the LRO feature enabled, and in fact
with this change we will now re-enable RSC as soon as the rx-usecs value is
increased and the flag is still set.
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Tested-by: default avatarRoss Brattain <ross.b.brattain@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 73c4b7cd
......@@ -1975,6 +1975,41 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
return 0;
}
/*
* this function must be called before setting the new value of
* rx_itr_setting
*/
static bool ixgbe_update_rsc(struct ixgbe_adapter *adapter,
struct ethtool_coalesce *ec)
{
struct net_device *netdev = adapter->netdev;
if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE))
return false;
/* if interrupt rate is too high then disable RSC */
if (ec->rx_coalesce_usecs != 1 &&
ec->rx_coalesce_usecs <= 1000000/IXGBE_MAX_RSC_INT_RATE) {
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
e_info(probe, "rx-usecs set too low, "
"disabling RSC\n");
adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
return true;
}
} else {
/* check the feature flag value and enable RSC if necessary */
if ((netdev->features & NETIF_F_LRO) &&
!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) {
e_info(probe, "rx-usecs set to %d, "
"re-enabling RSC\n",
ec->rx_coalesce_usecs);
adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
return true;
}
}
return false;
}
static int ixgbe_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec)
{
......@@ -1992,17 +2027,14 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
adapter->tx_ring[0]->work_limit = ec->tx_max_coalesced_frames_irq;
if (ec->rx_coalesce_usecs > 1) {
u32 max_int;
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
max_int = IXGBE_MAX_RSC_INT_RATE;
else
max_int = IXGBE_MAX_INT_RATE;
/* check the limits */
if ((1000000/ec->rx_coalesce_usecs > max_int) ||
if ((1000000/ec->rx_coalesce_usecs > IXGBE_MAX_INT_RATE) ||
(1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE))
return -EINVAL;
/* check the old value and enable RSC if necessary */
need_reset = ixgbe_update_rsc(adapter, ec);
/* store the value in ints/second */
adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs;
......@@ -2011,32 +2043,21 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
/* clear the lower bit as its used for dynamic state */
adapter->rx_itr_setting &= ~1;
} else if (ec->rx_coalesce_usecs == 1) {
/* check the old value and enable RSC if necessary */
need_reset = ixgbe_update_rsc(adapter, ec);
/* 1 means dynamic mode */
adapter->rx_eitr_param = 20000;
adapter->rx_itr_setting = 1;
} else {
/* check the old value and enable RSC if necessary */
need_reset = ixgbe_update_rsc(adapter, ec);
/*
* any other value means disable eitr, which is best
* served by setting the interrupt rate very high
*/
adapter->rx_eitr_param = IXGBE_MAX_INT_RATE;
adapter->rx_itr_setting = 0;
/*
* if hardware RSC is enabled, disable it when
* setting low latency mode, to avoid errata, assuming
* that when the user set low latency mode they want
* it at the cost of anything else
*/
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
if (netdev->features & NETIF_F_LRO) {
netdev->features &= ~NETIF_F_LRO;
e_info(probe, "rx-usecs set to 0, "
"disabling RSC\n");
}
need_reset = true;
}
}
if (ec->tx_coalesce_usecs > 1) {
......@@ -2123,15 +2144,15 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
return rc;
/* if state changes we need to update adapter->flags and reset */
if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) {
/*
* cast both to bool and verify if they are set the same
* but only enable RSC if itr is non-zero, as
* itr=0 and RSC are mutually exclusive
*/
if (((!!(data & ETH_FLAG_LRO)) !=
(!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) &&
adapter->rx_itr_setting) {
if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) &&
(!!(data & ETH_FLAG_LRO) !=
!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) {
if ((data & ETH_FLAG_LRO) &&
(!adapter->rx_itr_setting ||
(adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE))) {
e_info(probe, "rx-usecs set too low, "
"not enabling RSC.\n");
} else {
adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED;
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
......@@ -2140,11 +2161,6 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
default:
break;
}
} else if (!adapter->rx_itr_setting) {
netdev->features &= ~NETIF_F_LRO;
if (data & ETH_FLAG_LRO)
e_info(probe, "rx-usecs set to 0, "
"LRO/RSC cannot be enabled.\n");
}
}
......
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