Commit bc7d338f authored by Anjali Singhai Jain's avatar Anjali Singhai Jain Committed by Jeff Kirsher

i40e: reinit flow for the main VSI

This patch is the first in a 3 series patchset to implement
dynamically changing the queue count for the main VSI.

This patch starts by adding a reinit flow. This flow is designed
to be able to change just the queue count and not the number of
interrupt vectors that the device originally came up with.

Change-Id: I0634aaebf7dc4dd6c66af8f9dbbef89d7beac438
Signed-off-by: default avatarAnjali Singhai Jain <anjali.singhai@intel.com>
Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: default avatarKavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent bf051a3b
...@@ -48,7 +48,7 @@ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi); ...@@ -48,7 +48,7 @@ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi);
static void i40e_handle_reset_warning(struct i40e_pf *pf); static void i40e_handle_reset_warning(struct i40e_pf *pf);
static int i40e_add_vsi(struct i40e_vsi *vsi); static int i40e_add_vsi(struct i40e_vsi *vsi);
static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi); static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi);
static int i40e_setup_pf_switch(struct i40e_pf *pf); static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit);
static int i40e_setup_misc_vector(struct i40e_pf *pf); static int i40e_setup_misc_vector(struct i40e_pf *pf);
static void i40e_determine_queue_usage(struct i40e_pf *pf); static void i40e_determine_queue_usage(struct i40e_pf *pf);
static int i40e_setup_pf_filter_control(struct i40e_pf *pf); static int i40e_setup_pf_filter_control(struct i40e_pf *pf);
...@@ -354,6 +354,9 @@ static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct( ...@@ -354,6 +354,9 @@ static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(
struct rtnl_link_stats64 *vsi_stats = i40e_get_vsi_stats_struct(vsi); struct rtnl_link_stats64 *vsi_stats = i40e_get_vsi_stats_struct(vsi);
int i; int i;
if (test_bit(__I40E_DOWN, &vsi->state))
return stats;
rcu_read_lock(); rcu_read_lock();
for (i = 0; i < vsi->num_queue_pairs; i++) { for (i = 0; i < vsi->num_queue_pairs; i++) {
struct i40e_ring *tx_ring, *rx_ring; struct i40e_ring *tx_ring, *rx_ring;
...@@ -4767,8 +4770,9 @@ static int i40e_prep_for_reset(struct i40e_pf *pf) ...@@ -4767,8 +4770,9 @@ static int i40e_prep_for_reset(struct i40e_pf *pf)
/** /**
* i40e_reset_and_rebuild - reset and rebuid using a saved config * i40e_reset_and_rebuild - reset and rebuid using a saved config
* @pf: board private structure * @pf: board private structure
* @reinit: if the Main VSI needs to re-initialized.
**/ **/
static void i40e_reset_and_rebuild(struct i40e_pf *pf) static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
{ {
struct i40e_driver_version dv; struct i40e_driver_version dv;
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
...@@ -4816,7 +4820,7 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf) ...@@ -4816,7 +4820,7 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf)
} }
/* do basic switch setup */ /* do basic switch setup */
ret = i40e_setup_pf_switch(pf); ret = i40e_setup_pf_switch(pf, reinit);
if (ret) if (ret)
goto end_core_reset; goto end_core_reset;
...@@ -4907,7 +4911,7 @@ static void i40e_handle_reset_warning(struct i40e_pf *pf) ...@@ -4907,7 +4911,7 @@ static void i40e_handle_reset_warning(struct i40e_pf *pf)
ret = i40e_prep_for_reset(pf); ret = i40e_prep_for_reset(pf);
if (!ret) if (!ret)
i40e_reset_and_rebuild(pf); i40e_reset_and_rebuild(pf, false);
} }
/** /**
...@@ -5088,11 +5092,12 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi) ...@@ -5088,11 +5092,12 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
/** /**
* i40e_vsi_alloc_arrays - Allocate queue and vector pointer arrays for the vsi * i40e_vsi_alloc_arrays - Allocate queue and vector pointer arrays for the vsi
* @type: VSI pointer * @type: VSI pointer
* @alloc_qvectors: a bool to specify if q_vectors need to be allocated.
* *
* On error: returns error code (negative) * On error: returns error code (negative)
* On success: returns 0 * On success: returns 0
**/ **/
static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi) static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi, bool alloc_qvectors)
{ {
int size; int size;
int ret = 0; int ret = 0;
...@@ -5104,6 +5109,7 @@ static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi) ...@@ -5104,6 +5109,7 @@ static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi)
return -ENOMEM; return -ENOMEM;
vsi->rx_rings = &vsi->tx_rings[vsi->alloc_queue_pairs]; vsi->rx_rings = &vsi->tx_rings[vsi->alloc_queue_pairs];
if (alloc_qvectors) {
/* allocate memory for q_vector pointers */ /* allocate memory for q_vector pointers */
size = sizeof(struct i40e_q_vectors *) * vsi->num_q_vectors; size = sizeof(struct i40e_q_vectors *) * vsi->num_q_vectors;
vsi->q_vectors = kzalloc(size, GFP_KERNEL); vsi->q_vectors = kzalloc(size, GFP_KERNEL);
...@@ -5111,6 +5117,7 @@ static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi) ...@@ -5111,6 +5117,7 @@ static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi)
ret = -ENOMEM; ret = -ENOMEM;
goto err_vectors; goto err_vectors;
} }
}
return ret; return ret;
err_vectors: err_vectors:
...@@ -5179,7 +5186,7 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type) ...@@ -5179,7 +5186,7 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type)
if (ret) if (ret)
goto err_rings; goto err_rings;
ret = i40e_vsi_alloc_arrays(vsi); ret = i40e_vsi_alloc_arrays(vsi, true);
if (ret) if (ret)
goto err_rings; goto err_rings;
...@@ -5201,15 +5208,18 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type) ...@@ -5201,15 +5208,18 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type)
/** /**
* i40e_vsi_free_arrays - Free queue and vector pointer arrays for the VSI * i40e_vsi_free_arrays - Free queue and vector pointer arrays for the VSI
* @type: VSI pointer * @type: VSI pointer
* @free_qvectors: a bool to specify if q_vectors need to be freed.
* *
* On error: returns error code (negative) * On error: returns error code (negative)
* On success: returns 0 * On success: returns 0
**/ **/
static void i40e_vsi_free_arrays(struct i40e_vsi *vsi) static void i40e_vsi_free_arrays(struct i40e_vsi *vsi, bool free_qvectors)
{ {
/* free the ring and vector containers */ /* free the ring and vector containers */
if (free_qvectors) {
kfree(vsi->q_vectors); kfree(vsi->q_vectors);
vsi->q_vectors = NULL; vsi->q_vectors = NULL;
}
kfree(vsi->tx_rings); kfree(vsi->tx_rings);
vsi->tx_rings = NULL; vsi->tx_rings = NULL;
vsi->rx_rings = NULL; vsi->rx_rings = NULL;
...@@ -5251,7 +5261,7 @@ static int i40e_vsi_clear(struct i40e_vsi *vsi) ...@@ -5251,7 +5261,7 @@ static int i40e_vsi_clear(struct i40e_vsi *vsi)
i40e_put_lump(pf->qp_pile, vsi->base_queue, vsi->idx); i40e_put_lump(pf->qp_pile, vsi->base_queue, vsi->idx);
i40e_put_lump(pf->irq_pile, vsi->base_vector, vsi->idx); i40e_put_lump(pf->irq_pile, vsi->base_vector, vsi->idx);
i40e_vsi_free_arrays(vsi); i40e_vsi_free_arrays(vsi, true);
pf->vsi[vsi->idx] = NULL; pf->vsi[vsi->idx] = NULL;
if (vsi->idx < pf->next_vsi) if (vsi->idx < pf->next_vsi)
...@@ -6262,6 +6272,69 @@ static int i40e_vsi_setup_vectors(struct i40e_vsi *vsi) ...@@ -6262,6 +6272,69 @@ static int i40e_vsi_setup_vectors(struct i40e_vsi *vsi)
return ret; return ret;
} }
/**
* i40e_vsi_reinit_setup - return and reallocate resources for a VSI
* @vsi: pointer to the vsi.
*
* This re-allocates a vsi's queue resources.
*
* Returns pointer to the successfully allocated and configured VSI sw struct
* on success, otherwise returns NULL on failure.
**/
static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
{
struct i40e_pf *pf = vsi->back;
u8 enabled_tc;
int ret;
i40e_put_lump(pf->qp_pile, vsi->base_queue, vsi->idx);
i40e_vsi_clear_rings(vsi);
i40e_vsi_free_arrays(vsi, false);
i40e_set_num_rings_in_vsi(vsi);
ret = i40e_vsi_alloc_arrays(vsi, false);
if (ret)
goto err_vsi;
ret = i40e_get_lump(pf, pf->qp_pile, vsi->alloc_queue_pairs, vsi->idx);
if (ret < 0) {
dev_info(&pf->pdev->dev, "VSI %d get_lump failed %d\n",
vsi->seid, ret);
goto err_vsi;
}
vsi->base_queue = ret;
/* Update the FW view of the VSI. Force a reset of TC and queue
* layout configurations.
*/
enabled_tc = pf->vsi[pf->lan_vsi]->tc_config.enabled_tc;
pf->vsi[pf->lan_vsi]->tc_config.enabled_tc = 0;
pf->vsi[pf->lan_vsi]->seid = pf->main_vsi_seid;
i40e_vsi_config_tc(pf->vsi[pf->lan_vsi], enabled_tc);
/* assign it some queues */
ret = i40e_alloc_rings(vsi);
if (ret)
goto err_rings;
/* map all of the rings to the q_vectors */
i40e_vsi_map_rings_to_vectors(vsi);
return vsi;
err_rings:
i40e_vsi_free_q_vectors(vsi);
if (vsi->netdev_registered) {
vsi->netdev_registered = false;
unregister_netdev(vsi->netdev);
free_netdev(vsi->netdev);
vsi->netdev = NULL;
}
i40e_aq_delete_element(&pf->hw, vsi->seid, NULL);
err_vsi:
i40e_vsi_clear(vsi);
return NULL;
}
/** /**
* i40e_vsi_setup - Set up a VSI by a given type * i40e_vsi_setup - Set up a VSI by a given type
* @pf: board private structure * @pf: board private structure
...@@ -6905,10 +6978,11 @@ int i40e_fetch_switch_configuration(struct i40e_pf *pf, bool printconfig) ...@@ -6905,10 +6978,11 @@ int i40e_fetch_switch_configuration(struct i40e_pf *pf, bool printconfig)
/** /**
* i40e_setup_pf_switch - Setup the HW switch on startup or after reset * i40e_setup_pf_switch - Setup the HW switch on startup or after reset
* @pf: board private structure * @pf: board private structure
* @reinit: if the Main VSI needs to re-initialized.
* *
* Returns 0 on success, negative value on failure * Returns 0 on success, negative value on failure
**/ **/
static int i40e_setup_pf_switch(struct i40e_pf *pf) static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
{ {
u32 rxfc = 0, txfc = 0, rxfc_reg; u32 rxfc = 0, txfc = 0, rxfc_reg;
int ret; int ret;
...@@ -6930,7 +7004,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf) ...@@ -6930,7 +7004,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf)
i40e_fdir_setup(pf); i40e_fdir_setup(pf);
/* first time setup */ /* first time setup */
if (pf->lan_vsi == I40E_NO_VSI) { if (pf->lan_vsi == I40E_NO_VSI || reinit) {
struct i40e_vsi *vsi = NULL; struct i40e_vsi *vsi = NULL;
u16 uplink_seid; u16 uplink_seid;
...@@ -6941,8 +7015,10 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf) ...@@ -6941,8 +7015,10 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf)
uplink_seid = pf->veb[pf->lan_veb]->seid; uplink_seid = pf->veb[pf->lan_veb]->seid;
else else
uplink_seid = pf->mac_seid; uplink_seid = pf->mac_seid;
if (pf->lan_vsi == I40E_NO_VSI)
vsi = i40e_vsi_setup(pf, I40E_VSI_MAIN, uplink_seid, 0); vsi = i40e_vsi_setup(pf, I40E_VSI_MAIN, uplink_seid, 0);
else if (reinit)
vsi = i40e_vsi_reinit_setup(pf->vsi[pf->lan_vsi]);
if (!vsi) { if (!vsi) {
dev_info(&pf->pdev->dev, "setup of MAIN VSI failed\n"); dev_info(&pf->pdev->dev, "setup of MAIN VSI failed\n");
i40e_fdir_teardown(pf); i40e_fdir_teardown(pf);
...@@ -7413,7 +7489,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -7413,7 +7489,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_switch_setup; goto err_switch_setup;
} }
err = i40e_setup_pf_switch(pf); err = i40e_setup_pf_switch(pf, false);
if (err) { if (err) {
dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err); dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err);
goto err_vsis; goto err_vsis;
......
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