Commit 59826d9b authored by Jacob Keller's avatar Jacob Keller Committed by Jeff Kirsher

i40e: don't allow reduction of channels below active FD rules

If a driver is unable to maintain all current user supplied settings
from ethtool (or other sources), it is not ok for a user request to
succeed and silently trample over previous configuration.

To that end, if you change the number of channels, it must not be
allowed to reduce the number of channels (queues) below the current
flow director filter rules targets. In this case, return -EINVAL when
a request to reduce the number of channels would do so. In addition
log a warning to the kernel buffer explaining why we failed, and report
the rules which prevent us from lowering the number of channels.

Change-ID: If41464d63d7aab11cedf09e4f3aa1a69e21ffd88
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 52a08caa
...@@ -2744,11 +2744,15 @@ static void i40e_get_channels(struct net_device *dev, ...@@ -2744,11 +2744,15 @@ static void i40e_get_channels(struct net_device *dev,
static int i40e_set_channels(struct net_device *dev, static int i40e_set_channels(struct net_device *dev,
struct ethtool_channels *ch) struct ethtool_channels *ch)
{ {
const u8 drop = I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET;
struct i40e_netdev_priv *np = netdev_priv(dev); struct i40e_netdev_priv *np = netdev_priv(dev);
unsigned int count = ch->combined_count; unsigned int count = ch->combined_count;
struct i40e_vsi *vsi = np->vsi; struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back; struct i40e_pf *pf = vsi->back;
struct i40e_fdir_filter *rule;
struct hlist_node *node2;
int new_count; int new_count;
int err = 0;
/* We do not support setting channels for any other VSI at present */ /* We do not support setting channels for any other VSI at present */
if (vsi->type != I40E_VSI_MAIN) if (vsi->type != I40E_VSI_MAIN)
...@@ -2766,6 +2770,26 @@ static int i40e_set_channels(struct net_device *dev, ...@@ -2766,6 +2770,26 @@ static int i40e_set_channels(struct net_device *dev,
if (count > i40e_max_channels(vsi)) if (count > i40e_max_channels(vsi))
return -EINVAL; return -EINVAL;
/* verify that the number of channels does not invalidate any current
* flow director rules
*/
hlist_for_each_entry_safe(rule, node2,
&pf->fdir_filter_list, fdir_node) {
if (rule->dest_ctl != drop && count <= rule->q_index) {
dev_warn(&pf->pdev->dev,
"Existing user defined filter %d assigns flow to queue %d\n",
rule->fd_id, rule->q_index);
err = -EINVAL;
}
}
if (err) {
dev_err(&pf->pdev->dev,
"Existing filter rules must be deleted to reduce combined channel count to %d\n",
count);
return err;
}
/* update feature limits from largest to smallest supported values */ /* update feature limits from largest to smallest supported values */
/* TODO: Flow director limit, DCB etc */ /* TODO: Flow director limit, DCB etc */
......
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