Message ID | 20200902155347.16972-6-anthony.l.nguyen@intel.com |
---|---|
State | Accepted |
Delegated to: | Anthony Nguyen |
Headers | show |
Series | [net,1/6] ice: preserve NVM capabilities in safe mode | expand |
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of > Tony Nguyen > Sent: Wednesday, September 2, 2020 8:54 AM > To: intel-wired-lan@lists.osuosl.org > Subject: [Intel-wired-lan] [net 6/6] ice: fix memory leak in ice_vsi_setup > > From: Jacob Keller <jacob.e.keller@intel.com> > > During ice_vsi_setup, if ice_cfg_vsi_lan fails, it does not properly > release memory associated with the VSI rings. If we had used devres > allocations for the rings, this would be ok. However, we use kzalloc and > kfree_rcu for these ring structures. > > Using the correct label to cleanup the rings during ice_vsi_setup > highlights an issue in the ice_vsi_clear_rings function: it can leave > behind stale ring pointers in the q_vectors structure. > > When releasing rings, we must also ensure that no q_vector associated > with the VSI will point to this ring again. To resolve this, loop over > all q_vectors and release their ring mapping. Because we are about to > free all rings, no q_vector should remain pointing to any of the rings > in this VSI. > > Fixes: 5513b920a4f7 ("ice: Update Tx scheduler tree for VSI multi-Tx queue > support") > Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> > --- > drivers/net/ethernet/intel/ice/ice_lib.c | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > Tested-by: Aaron Brown <aaron.f.brown@intel.com>
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index 65cc78279501..ebbb8f54871c 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -1196,6 +1196,18 @@ static void ice_vsi_clear_rings(struct ice_vsi *vsi) { int i; + /* Avoid stale references by clearing map from vector to ring */ + if (vsi->q_vectors) { + ice_for_each_q_vector(vsi, i) { + struct ice_q_vector *q_vector = vsi->q_vectors[i]; + + if (q_vector) { + q_vector->tx.ring = NULL; + q_vector->rx.ring = NULL; + } + } + } + if (vsi->tx_rings) { for (i = 0; i < vsi->alloc_txq; i++) { if (vsi->tx_rings[i]) { @@ -2291,7 +2303,7 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi, if (status) { dev_err(dev, "VSI %d failed lan queue config, error %s\n", vsi->vsi_num, ice_stat_str(status)); - goto unroll_vector_base; + goto unroll_clear_rings; } /* Add switch rule to drop all Tx Flow Control Frames, of look up