HWS tag action is used to implement FLAG and MARK rte_flow actions.
It was allocated either on port start or on rte_flow_configure().
This could cause unnecessary FW resource usage
if user did not use any FLAG/MARK actions.

This patch extends global actions internal API,
introduced in previous commit, to allow lazy allocation
of HWS tag action. It will be allocated on first use of
FLAG/MARK action and will be allocated per domain to minimize
FW resource usage.

Signed-off-by: Dariusz Sosnowski <[email protected]>
Acked-by: Ori Kam <[email protected]>
---
 drivers/net/mlx5/mlx5.h                    |  2 -
 drivers/net/mlx5/mlx5_flow_hw.c            | 47 +++++------
 drivers/net/mlx5/mlx5_hws_global_actions.c | 92 ++++++++++++++++++----
 drivers/net/mlx5/mlx5_hws_global_actions.h |  5 ++
 4 files changed, 100 insertions(+), 46 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 54683cce7a..43553b1f35 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -2115,8 +2115,6 @@ struct mlx5_priv {
        struct mlx5dr_action **hw_vport;
        /* HWS global actions. */
        struct mlx5_hws_global_actions hw_global_actions;
-       /* HW steering global tag action. */
-       struct mlx5dr_action *hw_tag[2];
        /* HW steering global default miss action. */
        struct mlx5dr_action *hw_def_miss;
        /* HW steering global send to kernel action. */
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 80e156f26a..54c30264b2 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -2692,16 +2692,33 @@ __flow_hw_translate_actions_template(struct rte_eth_dev 
*dev,
                        acts->rule_acts[dr_pos].action = priv->hw_def_miss;
                        break;
                case RTE_FLOW_ACTION_TYPE_FLAG:
+                       dr_action = mlx5_hws_global_action_tag_get(priv, type, 
is_root);
+                       if (dr_action == NULL) {
+                               DRV_LOG(ERR, "port %u failed to allocate flag 
action",
+                                       priv->dev_data->port_id);
+                               rte_flow_error_set(&sub_error, ENOMEM,
+                                                  RTE_FLOW_ERROR_TYPE_STATE, 
NULL,
+                                                  "failed to allocate flag 
action");
+                               goto err;
+                       }
                        acts->mark = true;
                        acts->rule_acts[dr_pos].tag.value =
                                mlx5_flow_mark_set(MLX5_FLOW_MARK_DEFAULT);
-                       acts->rule_acts[dr_pos].action =
-                               priv->hw_tag[!!attr->group];
+                       acts->rule_acts[dr_pos].action = dr_action;
                        rte_atomic_fetch_add_explicit(&priv->hws_mark_refcnt, 1,
                                        rte_memory_order_relaxed);
                        mlx5_flow_hw_rxq_flag_set(dev, true);
                        break;
                case RTE_FLOW_ACTION_TYPE_MARK:
+                       dr_action = mlx5_hws_global_action_tag_get(priv, type, 
is_root);
+                       if (dr_action == NULL) {
+                               DRV_LOG(ERR, "port %u failed to allocate mark 
action",
+                                       priv->dev_data->port_id);
+                               rte_flow_error_set(&sub_error, ENOMEM,
+                                                  RTE_FLOW_ERROR_TYPE_STATE, 
NULL,
+                                                  "failed to allocate mark 
action");
+                               goto err;
+                       }
                        acts->mark = true;
                        if (masks->conf &&
                            ((const struct rte_flow_action_mark *)
@@ -2714,8 +2731,7 @@ __flow_hw_translate_actions_template(struct rte_eth_dev 
*dev,
                                                                   
actions->type,
                                                                   src_pos, 
dr_pos))
                                goto err;
-                       acts->rule_acts[dr_pos].action =
-                               priv->hw_tag[!!attr->group];
+                       acts->rule_acts[dr_pos].action = dr_action;
                        rte_atomic_fetch_add_explicit(&priv->hws_mark_refcnt, 1,
                                        rte_memory_order_relaxed);
                        mlx5_flow_hw_rxq_flag_set(dev, true);
@@ -11973,10 +11989,6 @@ __mlx5_flow_hw_resource_release(struct rte_eth_dev 
*dev, bool ctx_close)
                claim_zero(flow_hw_actions_template_destroy(dev, at, NULL));
                at = temp_at;
        }
-       for (i = 0; i < MLX5_HW_ACTION_FLAG_MAX; i++) {
-               if (priv->hw_tag[i])
-                       mlx5dr_action_destroy(priv->hw_tag[i]);
-       }
        if (priv->hw_def_miss)
                mlx5dr_action_destroy(priv->hw_def_miss);
        flow_hw_destroy_nat64_actions(priv);
@@ -12351,25 +12363,6 @@ __flow_hw_configure(struct rte_eth_dev *dev,
        if (port_attr->nb_meters || (host_priv && host_priv->hws_mpool))
                if (mlx5_flow_meter_init(dev, port_attr->nb_meters, 0, 0, 
nb_q_updated))
                        goto err;
-       /* Add global actions. */
-       for (i = 0; i < MLX5_HW_ACTION_FLAG_MAX; i++) {
-               uint32_t tag_flags = mlx5_hw_act_flag[i][0];
-               bool tag_fdb_rx = 
!!priv->sh->cdev->config.hca_attr.fdb_rx_set_flow_tag_stc;
-
-               if (is_proxy) {
-                       if (unified_fdb) {
-                               if (i == MLX5_HW_ACTION_FLAG_NONE_ROOT && 
tag_fdb_rx)
-                                       tag_flags |= 
mlx5_hw_act_flag[i][MLX5DR_TABLE_TYPE_FDB_RX];
-                       } else {
-                               if (i == MLX5_HW_ACTION_FLAG_NONE_ROOT && 
tag_fdb_rx)
-                                       tag_flags |= 
mlx5_hw_act_flag[i][MLX5DR_TABLE_TYPE_FDB];
-                       }
-               }
-               priv->hw_tag[i] = mlx5dr_action_create_tag
-                       (priv->dr_ctx, tag_flags);
-               if (!priv->hw_tag[i])
-                       goto err;
-       }
        if (priv->sh->config.dv_esw_en) {
                ret = flow_hw_setup_tx_repr_tagging(dev, error);
                if (ret)
diff --git a/drivers/net/mlx5/mlx5_hws_global_actions.c 
b/drivers/net/mlx5/mlx5_hws_global_actions.c
index 6af5497123..1ca444ce98 100644
--- a/drivers/net/mlx5/mlx5_hws_global_actions.c
+++ b/drivers/net/mlx5/mlx5_hws_global_actions.c
@@ -12,33 +12,63 @@ mlx5_hws_global_actions_init(struct mlx5_priv *priv)
        rte_spinlock_init(&priv->hw_global_actions.lock);
 }
 
-void
-mlx5_hws_global_actions_cleanup(struct mlx5_priv *priv)
+static void
+global_actions_array_cleanup(struct mlx5_priv *priv,
+                            struct mlx5_hws_global_actions_array *array,
+                            const char *name)
 {
-       rte_spinlock_lock(&priv->hw_global_actions.lock);
-
        for (int i = 0; i < MLX5_HWS_GLOBAL_ACTION_MAX; ++i) {
                for (int j = 0; j < MLX5DR_TABLE_TYPE_MAX; ++j) {
                        int ret;
 
-                       if (priv->hw_global_actions.drop.arr[i][j] == NULL)
+                       if (array->arr[i][j] == NULL)
                                continue;
 
-                       ret = 
mlx5dr_action_destroy(priv->hw_global_actions.drop.arr[i][j]);
+                       ret = mlx5dr_action_destroy(array->arr[i][j]);
                        if (ret != 0)
-                               DRV_LOG(ERR, "port %u failed to free HWS 
action",
-                                       priv->dev_data->port_id);
-                       priv->hw_global_actions.drop.arr[i][j] = NULL;
+                               DRV_LOG(ERR, "port %u failed to free %s HWS 
action",
+                                       priv->dev_data->port_id,
+                                       name);
+                       array->arr[i][j] = NULL;
                }
        }
+}
+
+void
+mlx5_hws_global_actions_cleanup(struct mlx5_priv *priv)
+{
+       rte_spinlock_lock(&priv->hw_global_actions.lock);
+
+       global_actions_array_cleanup(priv, &priv->hw_global_actions.drop, 
"drop");
+       global_actions_array_cleanup(priv, &priv->hw_global_actions.tag, "tag");
 
        rte_spinlock_unlock(&priv->hw_global_actions.lock);
 }
 
-struct mlx5dr_action *
-mlx5_hws_global_action_drop_get(struct mlx5_priv *priv,
-                               enum mlx5dr_table_type table_type,
-                               bool is_root)
+typedef struct mlx5dr_action *(*global_action_create_t)(struct mlx5dr_context 
*ctx,
+                                                       uint32_t action_flags);
+
+static struct mlx5dr_action *
+action_create_drop_cb(struct mlx5dr_context *ctx,
+                     uint32_t action_flags)
+{
+       return mlx5dr_action_create_dest_drop(ctx, action_flags);
+}
+
+static struct mlx5dr_action *
+action_create_tag_cb(struct mlx5dr_context *ctx,
+                    uint32_t action_flags)
+{
+       return mlx5dr_action_create_tag(ctx, action_flags);
+}
+
+static struct mlx5dr_action *
+global_action_get(struct mlx5_priv *priv,
+                 struct mlx5_hws_global_actions_array *array,
+                 const char *name,
+                 enum mlx5dr_table_type table_type,
+                 bool is_root,
+                 global_action_create_t create_cb)
 {
        enum mlx5dr_action_flags action_flags;
        struct mlx5dr_action *action = NULL;
@@ -50,19 +80,47 @@ mlx5_hws_global_action_drop_get(struct mlx5_priv *priv,
 
        rte_spinlock_lock(&priv->hw_global_actions.lock);
 
-       action = priv->hw_global_actions.drop.arr[!is_root][table_type];
+       action = array->arr[!is_root][table_type];
        if (action != NULL)
                goto unlock_ret;
 
-       action = mlx5dr_action_create_dest_drop(priv->dr_ctx, action_flags);
+       action = create_cb(priv->dr_ctx, action_flags);
        if (action == NULL) {
-               DRV_LOG(ERR, "port %u failed to create drop HWS action", 
priv->dev_data->port_id);
+               DRV_LOG(ERR, "port %u failed to create %s HWS action",
+                       priv->dev_data->port_id,
+                       name);
                goto unlock_ret;
        }
 
-       priv->hw_global_actions.drop.arr[!is_root][table_type] = action;
+       array->arr[!is_root][table_type] = action;
 
 unlock_ret:
        rte_spinlock_unlock(&priv->hw_global_actions.lock);
        return action;
 }
+
+struct mlx5dr_action *
+mlx5_hws_global_action_drop_get(struct mlx5_priv *priv,
+                               enum mlx5dr_table_type table_type,
+                               bool is_root)
+{
+       return global_action_get(priv,
+                                &priv->hw_global_actions.drop,
+                                "drop",
+                                table_type,
+                                is_root,
+                                action_create_drop_cb);
+}
+
+struct mlx5dr_action *
+mlx5_hws_global_action_tag_get(struct mlx5_priv *priv,
+                              enum mlx5dr_table_type table_type,
+                              bool is_root)
+{
+       return global_action_get(priv,
+                                &priv->hw_global_actions.tag,
+                                "tag",
+                                table_type,
+                                is_root,
+                                action_create_tag_cb);
+}
diff --git a/drivers/net/mlx5/mlx5_hws_global_actions.h 
b/drivers/net/mlx5/mlx5_hws_global_actions.h
index 3921004102..bec9f3e0e8 100644
--- a/drivers/net/mlx5/mlx5_hws_global_actions.h
+++ b/drivers/net/mlx5/mlx5_hws_global_actions.h
@@ -25,6 +25,7 @@ struct mlx5_hws_global_actions_array {
 
 struct mlx5_hws_global_actions {
        struct mlx5_hws_global_actions_array drop;
+       struct mlx5_hws_global_actions_array tag;
        rte_spinlock_t lock;
 };
 
@@ -36,4 +37,8 @@ struct mlx5dr_action *mlx5_hws_global_action_drop_get(struct 
mlx5_priv *priv,
                                                      enum mlx5dr_table_type 
table_type,
                                                      bool is_root);
 
+struct mlx5dr_action *mlx5_hws_global_action_tag_get(struct mlx5_priv *priv,
+                                                    enum mlx5dr_table_type 
table_type,
+                                                    bool is_root);
+
 #endif /* !RTE_PMD_MLX5_HWS_GLOBAL_ACTIONS_H_ */
-- 
2.47.3

Reply via email to