net/bnxt: add dpool allocator for EM allocation
[dpdk.git] / drivers / net / mlx5 / mlx5_flow_meter.c
index ac2735e..d7ce5cd 100644 (file)
@@ -559,7 +559,8 @@ static int
 __mlx5_flow_meter_policy_delete(struct rte_eth_dev *dev,
                        uint32_t policy_id,
                        struct mlx5_flow_meter_policy *mtr_policy,
-                       struct rte_mtr_error *error)
+                       struct rte_mtr_error *error,
+                       bool clear_l3t)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
        struct mlx5_flow_meter_sub_policy *sub_policy;
@@ -590,7 +591,7 @@ __mlx5_flow_meter_policy_delete(struct rte_eth_dev *dev,
                        }
                }
        }
-       if (priv->sh->mtrmng->policy_idx_tbl) {
+       if (priv->sh->mtrmng->policy_idx_tbl && clear_l3t) {
                if (mlx5_l3t_clear_entry(priv->sh->mtrmng->policy_idx_tbl,
                                        policy_id)) {
                        rte_spinlock_unlock(&mtr_policy->sl);
@@ -748,7 +749,7 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
                                        policy->actions, error);
        if (ret)
                goto policy_add_err;
-       if (!is_rss) {
+       if (!is_rss && !mtr_policy->is_queue) {
                /* Create policy rules in HW. */
                ret = mlx5_flow_create_policy_rules(dev, mtr_policy);
                if (ret)
@@ -768,7 +769,7 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
 policy_add_err:
        if (mtr_policy) {
                ret = __mlx5_flow_meter_policy_delete(dev, policy_id,
-                       mtr_policy, error);
+                       mtr_policy, error, false);
                mlx5_free(mtr_policy);
                if (ret)
                        return ret;
@@ -815,7 +816,7 @@ mlx5_flow_meter_policy_delete(struct rte_eth_dev *dev,
                        RTE_MTR_ERROR_TYPE_METER_POLICY_ID, NULL,
                        "Meter policy id is invalid. ");
        ret = __mlx5_flow_meter_policy_delete(dev, policy_id, mtr_policy,
-                                               error);
+                                               error, true);
        if (ret)
                return ret;
        mlx5_free(mtr_policy);
@@ -1808,6 +1809,40 @@ mlx5_flow_meter_detach(struct mlx5_priv *priv,
 #endif
 }
 
+/**
+ * Flush meter with Rx queue configuration.
+ *
+ * @param[in] dev
+ *   Pointer to Ethernet device.
+ */
+void
+mlx5_flow_meter_rxq_flush(struct rte_eth_dev *dev)
+{
+       struct mlx5_priv *priv = dev->data->dev_private;
+       struct mlx5_flow_meter_sub_policy *sub_policy;
+       struct mlx5_flow_meter_policy *mtr_policy;
+       void *entry;
+       uint32_t i, policy_idx;
+
+       if (!priv->mtr_en)
+               return;
+       if (priv->sh->mtrmng->policy_idx_tbl && priv->sh->refcnt == 1) {
+               MLX5_L3T_FOREACH(priv->sh->mtrmng->policy_idx_tbl,
+                                       i, entry) {
+                       policy_idx = *(uint32_t *)entry;
+                       sub_policy = mlx5_ipool_get
+                               (priv->sh->ipool[MLX5_IPOOL_MTR_POLICY],
+                               policy_idx);
+                       if (!sub_policy || !sub_policy->main_policy)
+                               continue;
+                       mtr_policy = sub_policy->main_policy;
+                       if (mtr_policy->is_queue || mtr_policy->is_rss)
+                               mlx5_flow_destroy_sub_policy_with_rxq(dev,
+                                       mtr_policy);
+               }
+       }
+}
+
 /**
  * Flush meter configuration.
  *
@@ -1875,7 +1910,7 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error)
                                                "meter policy invalid.");
                        if (__mlx5_flow_meter_policy_delete(dev, i,
                                                sub_policy->main_policy,
-                                               error))
+                                               error, true))
                                return -rte_mtr_error_set(error,
                                                EINVAL,
                                        RTE_MTR_ERROR_TYPE_METER_POLICY_ID,