]> git.droids-corp.org - dpdk.git/commitdiff
net/mlx5: fix reference count on detached indirect action
authorDariusz Sosnowski <dsosnowski@nvidia.com>
Tue, 23 Nov 2021 15:38:05 +0000 (17:38 +0200)
committerRaslan Darawsheh <rasland@nvidia.com>
Tue, 23 Nov 2021 16:57:19 +0000 (17:57 +0100)
This patch fixes segfault which was triggered when port, with indirect
actions created, was closed. Segfault was occurring only when
RTE_LIBRTE_MLX5_DEBUG was defined. It was caused by redundant decrement
of RX queues refcount:

- refcount was decremented when port was stopped and indirect actions
were detached from RX queues (port stop),
- refcount was decremented when indirect actions objects were destroyed
(port close or destroying of indirect action).

This patch fixes behavior. Dereferencing Rx queues is done if and only
if indirect action is explicitly destroyed by the user or detached on
port stop. Dereferencing Rx queues on action destroy operation depends
on an argument to the wrapper of indirect action destroy operation,
introduced in this patch.

Fixes: ec4e11d41d12 ("net/mlx5: preserve indirect actions on restart")
Cc: stable@dpdk.org
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
drivers/net/mlx5/mlx5_flow_dv.c
drivers/net/mlx5/mlx5_rx.h
drivers/net/mlx5/mlx5_rxq.c

index f5356418fa37fb9c0811ecfa40a8a693e5982ad3..9d4bd0560ceb8340c02b7d674c8541b9eaaf3f46 100644 (file)
@@ -14740,7 +14740,7 @@ __flow_dv_action_rss_setup(struct rte_eth_dev *dev,
 error_hrxq_new:
        err = rte_errno;
        __flow_dv_action_rss_hrxqs_release(dev, shared_rss);
-       if (!mlx5_ind_table_obj_release(dev, shared_rss->ind_tbl, true))
+       if (!mlx5_ind_table_obj_release(dev, shared_rss->ind_tbl, true, true))
                shared_rss->ind_tbl = NULL;
        rte_errno = err;
        return -rte_errno;
@@ -14883,7 +14883,8 @@ __flow_dv_action_rss_release(struct rte_eth_dev *dev, uint32_t idx,
                                          NULL,
                                          "shared rss hrxq has references");
        queue = shared_rss->ind_tbl->queues;
-       remaining = mlx5_ind_table_obj_release(dev, shared_rss->ind_tbl, true);
+       remaining = mlx5_ind_table_obj_release(dev, shared_rss->ind_tbl, true,
+                                              !!dev->data->dev_started);
        if (remaining)
                return rte_flow_error_set(error, EBUSY,
                                          RTE_FLOW_ERROR_TYPE_ACTION,
index 9cc1a2703bb57bed7e88fff28408b091a774e143..b19464bb37a8ad97dfaf8b16e5581b10345a4a18 100644 (file)
@@ -225,7 +225,8 @@ struct mlx5_ind_table_obj *mlx5_ind_table_obj_get(struct rte_eth_dev *dev,
                                                  uint32_t queues_n);
 int mlx5_ind_table_obj_release(struct rte_eth_dev *dev,
                               struct mlx5_ind_table_obj *ind_tbl,
-                              bool standalone);
+                              bool standalone,
+                              bool deref_rxqs);
 int mlx5_ind_table_obj_setup(struct rte_eth_dev *dev,
                             struct mlx5_ind_table_obj *ind_tbl);
 int mlx5_ind_table_obj_modify(struct rte_eth_dev *dev,
index e406779faf88186fef8003ba25e37e2890b11415..47dc24793b4e291dae00148d928ec392bcb56f04 100644 (file)
@@ -2195,6 +2195,9 @@ mlx5_ind_table_obj_get(struct rte_eth_dev *dev, const uint16_t *queues,
  *   Indirection table to release.
  * @param standalone
  *   Indirection table for Standalone queue.
+ * @param deref_rxqs
+ *   If true, then dereference RX queues related to indirection table.
+ *   Otherwise, no additional action will be taken.
  *
  * @return
  *   1 while a reference on it exists, 0 when freed.
@@ -2202,7 +2205,8 @@ mlx5_ind_table_obj_get(struct rte_eth_dev *dev, const uint16_t *queues,
 int
 mlx5_ind_table_obj_release(struct rte_eth_dev *dev,
                           struct mlx5_ind_table_obj *ind_tbl,
-                          bool standalone)
+                          bool standalone,
+                          bool deref_rxqs)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
        unsigned int i, ret;
@@ -2215,8 +2219,10 @@ mlx5_ind_table_obj_release(struct rte_eth_dev *dev,
        if (ret)
                return 1;
        priv->obj_ops.ind_table_destroy(ind_tbl);
-       for (i = 0; i != ind_tbl->queues_n; ++i)
-               claim_nonzero(mlx5_rxq_deref(dev, ind_tbl->queues[i]));
+       if (deref_rxqs) {
+               for (i = 0; i != ind_tbl->queues_n; ++i)
+                       claim_nonzero(mlx5_rxq_deref(dev, ind_tbl->queues[i]));
+       }
        mlx5_free(ind_tbl);
        return 0;
 }
@@ -2573,7 +2579,7 @@ mlx5_hrxq_modify(struct rte_eth_dev *dev, uint32_t hrxq_idx,
        if (ind_tbl != hrxq->ind_table) {
                MLX5_ASSERT(!hrxq->standalone);
                mlx5_ind_table_obj_release(dev, hrxq->ind_table,
-                                          hrxq->standalone);
+                                          hrxq->standalone, true);
                hrxq->ind_table = ind_tbl;
        }
        hrxq->hash_fields = hash_fields;
@@ -2583,7 +2589,8 @@ error:
        err = rte_errno;
        if (ind_tbl != hrxq->ind_table) {
                MLX5_ASSERT(!hrxq->standalone);
-               mlx5_ind_table_obj_release(dev, ind_tbl, hrxq->standalone);
+               mlx5_ind_table_obj_release(dev, ind_tbl, hrxq->standalone,
+                                          true);
        }
        rte_errno = err;
        return -rte_errno;
@@ -2600,7 +2607,7 @@ __mlx5_hrxq_remove(struct rte_eth_dev *dev, struct mlx5_hrxq *hrxq)
        priv->obj_ops.hrxq_destroy(hrxq);
        if (!hrxq->standalone) {
                mlx5_ind_table_obj_release(dev, hrxq->ind_table,
-                                          hrxq->standalone);
+                                          hrxq->standalone, true);
        }
        mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_HRXQ], hrxq->idx);
 }
@@ -2666,7 +2673,7 @@ __mlx5_hrxq_create(struct rte_eth_dev *dev,
        return hrxq;
 error:
        if (!rss_desc->ind_tbl)
-               mlx5_ind_table_obj_release(dev, ind_tbl, standalone);
+               mlx5_ind_table_obj_release(dev, ind_tbl, standalone, true);
        if (hrxq)
                mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_HRXQ], hrxq_idx);
        return NULL;