Fix several VSI create/destroy issues introduced by VF representor
support:

- Initialize other_vsi_list with TAILQ_INIT in sxe2_vsi_init before
  any VSI is inserted into it.
- Treat -EPERM as a non-fatal error when destroying VSIs, since the
  kernel may have already removed the VSI.
- Set main_vsi to NULL after destroy/free to avoid a dangling pointer
  if the VSI is destroyed again.

Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Jie Liu <[email protected]>
---
 drivers/net/sxe2/sxe2_vsi.c | 31 ++++++++++---------------------
 1 file changed, 10 insertions(+), 21 deletions(-)

diff --git a/drivers/net/sxe2/sxe2_vsi.c b/drivers/net/sxe2/sxe2_vsi.c
index d29480b931..e1a26fda6a 100644
--- a/drivers/net/sxe2/sxe2_vsi.c
+++ b/drivers/net/sxe2/sxe2_vsi.c
@@ -96,21 +96,6 @@ static struct sxe2_vsi *sxe2_vsi_node_create(struct 
sxe2_adapter *adapter,
        return vsi;
 }
 
-static void sxe2_vsi_node_free(struct sxe2_vsi *vsi)
-{
-       struct sxe2_adapter *adapter;
-
-       if (!vsi)
-               return;
-
-       adapter = vsi->adapter;
-       if (vsi->vsi_type == SXE2_VSI_T_ESW)
-               TAILQ_REMOVE(&adapter->vsi_ctxt.other_vsi_list, vsi, next);
-
-       rte_free(vsi);
-       vsi = NULL;
-}
-
 static int32_t sxe2_vsi_destroy(struct sxe2_adapter *adapter, struct sxe2_vsi 
*vsi)
 {
        int32_t ret = 0;
@@ -131,6 +116,8 @@ static int32_t sxe2_vsi_destroy(struct sxe2_adapter 
*adapter, struct sxe2_vsi *v
        }
 
 l_free:
+       if (vsi->vsi_type == SXE2_VSI_T_DPDK_ESW)
+               TAILQ_REMOVE(&adapter->vsi_ctxt.other_vsi_list, vsi, next);
        rte_free(vsi);
        vsi = NULL;
 
@@ -174,7 +161,7 @@ static int32_t sxe2_main_vsi_create(struct sxe2_adapter 
*adapter)
        goto l_end;
 
 l_free_vsi:
-       sxe2_vsi_node_free(adapter->vsi_ctxt.main_vsi);
+       rte_free(adapter->vsi_ctxt.main_vsi);
        adapter->vsi_ctxt.main_vsi = NULL;
 l_end:
        return ret;
@@ -217,7 +204,7 @@ int32_t sxe2_other_vsi_create(struct sxe2_adapter *adapter, 
uint16_t cnt_vf)
        goto l_end;
 
 l_free_vsi:
-       sxe2_vsi_node_free(other_vsi);
+       rte_free(other_vsi);
 l_end:
        return ret;
 }
@@ -230,7 +217,7 @@ int32_t sxe2_vsi_init(struct rte_eth_dev *dev)
        uint16_t srcvsi_cnt;
 
        PMD_INIT_FUNC_TRACE();
-
+       TAILQ_INIT(&adapter->vsi_ctxt.other_vsi_list);
        ret = sxe2_main_vsi_create(adapter);
        if (ret) {
                PMD_LOG_ERR(DRV, "Failed to create main VSI, ret=%d", ret);
@@ -283,13 +270,14 @@ void sxe2_vsi_uninit(struct rte_eth_dev *dev)
 
 l_free:
        ret = sxe2_vsi_destroy(adapter, adapter->vsi_ctxt.main_vsi);
-       if (ret) {
+       if (ret && ret != -EPERM) {
                PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
                goto l_end;
        }
+       adapter->vsi_ctxt.main_vsi = NULL;
        RTE_TAILQ_FOREACH_SAFE(var, &adapter->vsi_ctxt.other_vsi_list, next, 
tvar) {
                ret = sxe2_vsi_destroy(adapter, var);
-               if (ret) {
+               if (ret && ret != -EPERM) {
                        PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", 
ret);
                        break;
                }
@@ -356,5 +344,6 @@ void sxe2_vsi_repr_main_vsi_destroy(struct rte_eth_dev *dev)
 {
        struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
 
-       sxe2_vsi_node_free(adapter->vsi_ctxt.main_vsi);
+       rte_free(adapter->vsi_ctxt.main_vsi);
+       adapter->vsi_ctxt.main_vsi = NULL;
 }
-- 
2.52.0

Reply via email to