Commit 135f4b9e authored by Jacob Keller's avatar Jacob Keller Committed by Tony Nguyen

ice: fix memory leak if register_netdev_fails

The ice_setup_pf_sw function can cause a memory leak if register_netdev
fails, due to accidentally failing to free the VSI rings. Fix the memory
leak by using ice_vsi_release, ensuring we actually go through the full
teardown process.

This should be safe even if the netdevice is not registered because we
will have set the netdev pointer to NULL, ensuring ice_vsi_release won't
call unregister_netdev.

An alternative fix would be moving management of the PF VSI netdev into
the main VSI setup code. This is complicated and likely requires
significant refactor in how we manage VSIs

Fixes: 3a858ba3 ("ice: Add support for VSI allocation and deallocation")
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Tested-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 466e4392
...@@ -246,7 +246,7 @@ static int ice_get_free_slot(void *array, int size, int curr) ...@@ -246,7 +246,7 @@ static int ice_get_free_slot(void *array, int size, int curr)
* ice_vsi_delete - delete a VSI from the switch * ice_vsi_delete - delete a VSI from the switch
* @vsi: pointer to VSI being removed * @vsi: pointer to VSI being removed
*/ */
void ice_vsi_delete(struct ice_vsi *vsi) static void ice_vsi_delete(struct ice_vsi *vsi)
{ {
struct ice_pf *pf = vsi->back; struct ice_pf *pf = vsi->back;
struct ice_vsi_ctx *ctxt; struct ice_vsi_ctx *ctxt;
...@@ -313,7 +313,7 @@ static void ice_vsi_free_arrays(struct ice_vsi *vsi) ...@@ -313,7 +313,7 @@ static void ice_vsi_free_arrays(struct ice_vsi *vsi)
* *
* Returns 0 on success, negative on failure * Returns 0 on success, negative on failure
*/ */
int ice_vsi_clear(struct ice_vsi *vsi) static int ice_vsi_clear(struct ice_vsi *vsi)
{ {
struct ice_pf *pf = NULL; struct ice_pf *pf = NULL;
struct device *dev; struct device *dev;
...@@ -563,7 +563,7 @@ static int ice_vsi_get_qs(struct ice_vsi *vsi) ...@@ -563,7 +563,7 @@ static int ice_vsi_get_qs(struct ice_vsi *vsi)
* ice_vsi_put_qs - Release queues from VSI to PF * ice_vsi_put_qs - Release queues from VSI to PF
* @vsi: the VSI that is going to release queues * @vsi: the VSI that is going to release queues
*/ */
void ice_vsi_put_qs(struct ice_vsi *vsi) static void ice_vsi_put_qs(struct ice_vsi *vsi)
{ {
struct ice_pf *pf = vsi->back; struct ice_pf *pf = vsi->back;
int i; int i;
......
...@@ -45,10 +45,6 @@ int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena, bool vlan_promisc); ...@@ -45,10 +45,6 @@ int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena, bool vlan_promisc);
void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create); void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create);
void ice_vsi_delete(struct ice_vsi *vsi);
int ice_vsi_clear(struct ice_vsi *vsi);
#ifdef CONFIG_DCB #ifdef CONFIG_DCB
int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc); int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc);
#endif /* CONFIG_DCB */ #endif /* CONFIG_DCB */
...@@ -79,8 +75,6 @@ bool ice_is_reset_in_progress(unsigned long *state); ...@@ -79,8 +75,6 @@ bool ice_is_reset_in_progress(unsigned long *state);
void void
ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio); ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio);
void ice_vsi_put_qs(struct ice_vsi *vsi);
void ice_vsi_dis_irq(struct ice_vsi *vsi); void ice_vsi_dis_irq(struct ice_vsi *vsi);
void ice_vsi_free_irq(struct ice_vsi *vsi); void ice_vsi_free_irq(struct ice_vsi *vsi);
......
...@@ -3169,10 +3169,8 @@ static int ice_setup_pf_sw(struct ice_pf *pf) ...@@ -3169,10 +3169,8 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
return -EBUSY; return -EBUSY;
vsi = ice_pf_vsi_setup(pf, pf->hw.port_info); vsi = ice_pf_vsi_setup(pf, pf->hw.port_info);
if (!vsi) { if (!vsi)
status = -ENOMEM; return -ENOMEM;
goto unroll_vsi_setup;
}
status = ice_cfg_netdev(vsi); status = ice_cfg_netdev(vsi);
if (status) { if (status) {
...@@ -3219,12 +3217,7 @@ static int ice_setup_pf_sw(struct ice_pf *pf) ...@@ -3219,12 +3217,7 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
} }
unroll_vsi_setup: unroll_vsi_setup:
if (vsi) { ice_vsi_release(vsi);
ice_vsi_free_q_vectors(vsi);
ice_vsi_delete(vsi);
ice_vsi_put_qs(vsi);
ice_vsi_clear(vsi);
}
return status; return status;
} }
......
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