Commit 06b2decd authored by Alan Brady's avatar Alan Brady Committed by Jeff Kirsher

i40e: prevent changing ITR if adaptive-rx/tx enabled

Currently the driver allows the user to change (or even disable)
interrupt moderation if adaptive-rx/tx is enabled when this should
not be the case.

Adaptive RX/TX will not respect the user's ITR settings so
allowing the user to change it is weird.  This bug would also
allow the user to disable interrupt moderation with adaptive-rx/tx
enabled which doesn't make much sense either.

This patch makes it such that if adaptive-rx/tx is enabled, the user
cannot make any manual adjustments to interrupt moderation.  It also
makes it so that if ITR is disabled but adaptive-rx/tx is then
enabled, ITR will be re-enabled.
Signed-off-by: default avatarAlan Brady <alan.brady@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 7e4d01e7
...@@ -2194,14 +2194,29 @@ static int __i40e_set_coalesce(struct net_device *netdev, ...@@ -2194,14 +2194,29 @@ static int __i40e_set_coalesce(struct net_device *netdev,
int queue) int queue)
{ {
struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_netdev_priv *np = netdev_priv(netdev);
u16 intrl_reg, cur_rx_itr, cur_tx_itr;
struct i40e_vsi *vsi = np->vsi; struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back; struct i40e_pf *pf = vsi->back;
u16 intrl_reg;
int i; int i;
if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq) if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
vsi->work_limit = ec->tx_max_coalesced_frames_irq; vsi->work_limit = ec->tx_max_coalesced_frames_irq;
if (queue < 0) {
cur_rx_itr = vsi->rx_rings[0]->rx_itr_setting;
cur_tx_itr = vsi->tx_rings[0]->tx_itr_setting;
} else if (queue < vsi->num_queue_pairs) {
cur_rx_itr = vsi->rx_rings[queue]->rx_itr_setting;
cur_tx_itr = vsi->tx_rings[queue]->tx_itr_setting;
} else {
netif_info(pf, drv, netdev, "Invalid queue value, queue range is 0 - %d\n",
vsi->num_queue_pairs - 1);
return -EINVAL;
}
cur_tx_itr &= ~I40E_ITR_DYNAMIC;
cur_rx_itr &= ~I40E_ITR_DYNAMIC;
/* tx_coalesce_usecs_high is ignored, use rx-usecs-high instead */ /* tx_coalesce_usecs_high is ignored, use rx-usecs-high instead */
if (ec->tx_coalesce_usecs_high != vsi->int_rate_limit) { if (ec->tx_coalesce_usecs_high != vsi->int_rate_limit) {
netif_info(pf, drv, netdev, "tx-usecs-high is not used, please program rx-usecs-high\n"); netif_info(pf, drv, netdev, "tx-usecs-high is not used, please program rx-usecs-high\n");
...@@ -2214,15 +2229,34 @@ static int __i40e_set_coalesce(struct net_device *netdev, ...@@ -2214,15 +2229,34 @@ static int __i40e_set_coalesce(struct net_device *netdev,
return -EINVAL; return -EINVAL;
} }
if (ec->rx_coalesce_usecs == 0) { if (ec->rx_coalesce_usecs != cur_rx_itr &&
if (ec->use_adaptive_rx_coalesce) ec->use_adaptive_rx_coalesce) {
netif_info(pf, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n"); netif_info(pf, drv, netdev, "RX interrupt moderation cannot be changed if adaptive-rx is enabled.\n");
} else if ((ec->rx_coalesce_usecs < (I40E_MIN_ITR << 1)) || return -EINVAL;
(ec->rx_coalesce_usecs > (I40E_MAX_ITR << 1))) { }
if (ec->rx_coalesce_usecs > (I40E_MAX_ITR << 1)) {
netif_info(pf, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n"); netif_info(pf, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n");
return -EINVAL; return -EINVAL;
} }
if (ec->tx_coalesce_usecs != cur_tx_itr &&
ec->use_adaptive_tx_coalesce) {
netif_info(pf, drv, netdev, "TX interrupt moderation cannot be changed if adaptive-tx is enabled.\n");
return -EINVAL;
}
if (ec->tx_coalesce_usecs > (I40E_MAX_ITR << 1)) {
netif_info(pf, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n");
return -EINVAL;
}
if (ec->use_adaptive_rx_coalesce && !cur_rx_itr)
ec->rx_coalesce_usecs = I40E_MIN_ITR << 1;
if (ec->use_adaptive_tx_coalesce && !cur_tx_itr)
ec->tx_coalesce_usecs = I40E_MIN_ITR << 1;
intrl_reg = i40e_intrl_usec_to_reg(ec->rx_coalesce_usecs_high); intrl_reg = i40e_intrl_usec_to_reg(ec->rx_coalesce_usecs_high);
vsi->int_rate_limit = INTRL_REG_TO_USEC(intrl_reg); vsi->int_rate_limit = INTRL_REG_TO_USEC(intrl_reg);
if (vsi->int_rate_limit != ec->rx_coalesce_usecs_high) { if (vsi->int_rate_limit != ec->rx_coalesce_usecs_high) {
...@@ -2230,27 +2264,14 @@ static int __i40e_set_coalesce(struct net_device *netdev, ...@@ -2230,27 +2264,14 @@ static int __i40e_set_coalesce(struct net_device *netdev,
vsi->int_rate_limit); vsi->int_rate_limit);
} }
if (ec->tx_coalesce_usecs == 0) {
if (ec->use_adaptive_tx_coalesce)
netif_info(pf, drv, netdev, "tx-usecs=0, need to disable adaptive-tx for a complete disable\n");
} else if ((ec->tx_coalesce_usecs < (I40E_MIN_ITR << 1)) ||
(ec->tx_coalesce_usecs > (I40E_MAX_ITR << 1))) {
netif_info(pf, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n");
return -EINVAL;
}
/* rx and tx usecs has per queue value. If user doesn't specify the queue, /* rx and tx usecs has per queue value. If user doesn't specify the queue,
* apply to all queues. * apply to all queues.
*/ */
if (queue < 0) { if (queue < 0) {
for (i = 0; i < vsi->num_queue_pairs; i++) for (i = 0; i < vsi->num_queue_pairs; i++)
i40e_set_itr_per_queue(vsi, ec, i); i40e_set_itr_per_queue(vsi, ec, i);
} else if (queue < vsi->num_queue_pairs) {
i40e_set_itr_per_queue(vsi, ec, queue);
} else { } else {
netif_info(pf, drv, netdev, "Invalid queue value, queue range is 0 - %d\n", i40e_set_itr_per_queue(vsi, ec, queue);
vsi->num_queue_pairs - 1);
return -EINVAL;
} }
return 0; return 0;
......
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