Commit 2e6d218c authored by Jedrzej Jagielski's avatar Jedrzej Jagielski Committed by Tony Nguyen

i40e: Fix creation of first queue by omitting it if is not power of two

Reject TCs creation with proper message if the first queue
assignment is not equal to the power of two.
The first queue number was checked too late in the second queue
iteration, if second queue was configured at all. Now if first queue value
is not a power of two, then trying to create qdisc will be rejected.

Fixes: 8f88b303 ("i40e: Add infrastructure for queue channel support")
Signed-off-by: default avatarGrzegorz Szczurek <grzegorzx.szczurek@intel.com>
Signed-off-by: default avatarJedrzej Jagielski <jedrzej.jagielski@intel.com>
Tested-by: default avatarTony Brelinski <tony.brelinski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 3a3b311e
......@@ -5786,24 +5786,6 @@ static void i40e_remove_queue_channels(struct i40e_vsi *vsi)
INIT_LIST_HEAD(&vsi->ch_list);
}
/**
* i40e_is_any_channel - channel exist or not
* @vsi: ptr to VSI to which channels are associated with
*
* Returns true or false if channel(s) exist for associated VSI or not
**/
static bool i40e_is_any_channel(struct i40e_vsi *vsi)
{
struct i40e_channel *ch, *ch_tmp;
list_for_each_entry_safe(ch, ch_tmp, &vsi->ch_list, list) {
if (ch->initialized)
return true;
}
return false;
}
/**
* i40e_get_max_queues_for_channel
* @vsi: ptr to VSI to which channels are associated with
......@@ -6310,26 +6292,15 @@ int i40e_create_queue_channel(struct i40e_vsi *vsi,
/* By default we are in VEPA mode, if this is the first VF/VMDq
* VSI to be added switch to VEB mode.
*/
if ((!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) ||
(!i40e_is_any_channel(vsi))) {
if (!is_power_of_2(vsi->tc_config.tc_info[0].qcount)) {
dev_dbg(&pf->pdev->dev,
"Failed to create channel. Override queues (%u) not power of 2\n",
vsi->tc_config.tc_info[0].qcount);
return -EINVAL;
}
if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) {
pf->flags |= I40E_FLAG_VEB_MODE_ENABLED;
if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) {
pf->flags |= I40E_FLAG_VEB_MODE_ENABLED;
if (vsi->type == I40E_VSI_MAIN) {
if (pf->flags & I40E_FLAG_TC_MQPRIO)
i40e_do_reset(pf, I40E_PF_RESET_FLAG,
true);
else
i40e_do_reset_safe(pf,
I40E_PF_RESET_FLAG);
}
if (vsi->type == I40E_VSI_MAIN) {
if (pf->flags & I40E_FLAG_TC_MQPRIO)
i40e_do_reset(pf, I40E_PF_RESET_FLAG, true);
else
i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG);
}
/* now onwards for main VSI, number of queues will be value
* of TC0's queue count
......@@ -7982,12 +7953,20 @@ static int i40e_setup_tc(struct net_device *netdev, void *type_data)
vsi->seid);
need_reset = true;
goto exit;
} else {
dev_info(&vsi->back->pdev->dev,
"Setup channel (id:%u) utilizing num_queues %d\n",
vsi->seid, vsi->tc_config.tc_info[0].qcount);
} else if (enabled_tc &&
(!is_power_of_2(vsi->tc_config.tc_info[0].qcount))) {
netdev_info(netdev,
"Failed to create channel. Override queues (%u) not power of 2\n",
vsi->tc_config.tc_info[0].qcount);
ret = -EINVAL;
need_reset = true;
goto exit;
}
dev_info(&vsi->back->pdev->dev,
"Setup channel (id:%u) utilizing num_queues %d\n",
vsi->seid, vsi->tc_config.tc_info[0].qcount);
if (pf->flags & I40E_FLAG_TC_MQPRIO) {
if (vsi->mqprio_qopt.max_rate[0]) {
u64 max_tx_rate = vsi->mqprio_qopt.max_rate[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