HWS pop_vlan action is used to implement OF_POP_VLAN rte_flow action.
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 OF_POP_VLAN action.

This patch extends global actions internal API,
introduced in previous commits, to allow lazy allocation
of HWS pop_vlan action. It will be allocated on first use
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                    |  1 -
 drivers/net/mlx5/mlx5_flow_hw.c            | 20 ++++++++++----------
 drivers/net/mlx5/mlx5_hws_global_actions.c | 21 +++++++++++++++++++++
 drivers/net/mlx5/mlx5_hws_global_actions.h |  5 +++++
 4 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 43553b1f35..9e46a8cee8 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -2111,7 +2111,6 @@ struct mlx5_priv {
        /* HW steering rte flow group list header */
        LIST_HEAD(flow_hw_grp, mlx5_flow_group) flow_hw_grp;
        struct mlx5dr_action *hw_push_vlan[MLX5DR_TABLE_TYPE_MAX];
-       struct mlx5dr_action *hw_pop_vlan[MLX5DR_TABLE_TYPE_MAX];
        struct mlx5dr_action **hw_vport;
        /* HWS global actions. */
        struct mlx5_hws_global_actions hw_global_actions;
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 54c30264b2..21c61bce90 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -2753,8 +2753,16 @@ __flow_hw_translate_actions_template(struct rte_eth_dev 
*dev,
                        masks += of_vlan_offset;
                        break;
                case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
-                       acts->rule_acts[dr_pos].action =
-                               priv->hw_pop_vlan[type];
+                       dr_action = mlx5_hws_global_action_pop_vlan_get(priv, 
type, is_root);
+                       if (dr_action == NULL) {
+                               DRV_LOG(ERR, "port %u failed to allocate pop 
VLAN action",
+                                       priv->dev_data->port_id);
+                               rte_flow_error_set(&sub_error, ENOMEM,
+                                                  RTE_FLOW_ERROR_TYPE_STATE, 
NULL,
+                                                  "failed to allocate pop VLAN 
action");
+                               goto err;
+                       }
+                       acts->rule_acts[dr_pos].action = dr_action;
                        break;
                case RTE_FLOW_ACTION_TYPE_JUMP:
                        if (masks->conf &&
@@ -11377,10 +11385,6 @@ flow_hw_destroy_vlan(struct rte_eth_dev *dev)
        enum mlx5dr_table_type i;
 
        for (i = MLX5DR_TABLE_TYPE_NIC_RX; i < MLX5DR_TABLE_TYPE_MAX; i++) {
-               if (priv->hw_pop_vlan[i]) {
-                       mlx5dr_action_destroy(priv->hw_pop_vlan[i]);
-                       priv->hw_pop_vlan[i] = NULL;
-               }
                if (priv->hw_push_vlan[i]) {
                        mlx5dr_action_destroy(priv->hw_push_vlan[i]);
                        priv->hw_push_vlan[i] = NULL;
@@ -11401,10 +11405,6 @@ _create_vlan(struct mlx5_priv *priv, enum 
mlx5dr_table_type type)
        };
 
        /* rte_errno is set in the mlx5dr_action* functions. */
-       priv->hw_pop_vlan[type] =
-               mlx5dr_action_create_pop_vlan(priv->dr_ctx, flags[type]);
-       if (!priv->hw_pop_vlan[type])
-               return -rte_errno;
        priv->hw_push_vlan[type] =
                mlx5dr_action_create_push_vlan(priv->dr_ctx, flags[type]);
        if (!priv->hw_push_vlan[type])
diff --git a/drivers/net/mlx5/mlx5_hws_global_actions.c 
b/drivers/net/mlx5/mlx5_hws_global_actions.c
index 1ca444ce98..236e6f1d1a 100644
--- a/drivers/net/mlx5/mlx5_hws_global_actions.c
+++ b/drivers/net/mlx5/mlx5_hws_global_actions.c
@@ -41,6 +41,7 @@ mlx5_hws_global_actions_cleanup(struct mlx5_priv *priv)
 
        global_actions_array_cleanup(priv, &priv->hw_global_actions.drop, 
"drop");
        global_actions_array_cleanup(priv, &priv->hw_global_actions.tag, "tag");
+       global_actions_array_cleanup(priv, &priv->hw_global_actions.pop_vlan, 
"pop_vlan");
 
        rte_spinlock_unlock(&priv->hw_global_actions.lock);
 }
@@ -62,6 +63,13 @@ action_create_tag_cb(struct mlx5dr_context *ctx,
        return mlx5dr_action_create_tag(ctx, action_flags);
 }
 
+static struct mlx5dr_action *
+action_create_pop_vlan_cb(struct mlx5dr_context *ctx,
+                         uint32_t action_flags)
+{
+       return mlx5dr_action_create_pop_vlan(ctx, action_flags);
+}
+
 static struct mlx5dr_action *
 global_action_get(struct mlx5_priv *priv,
                  struct mlx5_hws_global_actions_array *array,
@@ -124,3 +132,16 @@ mlx5_hws_global_action_tag_get(struct mlx5_priv *priv,
                                 is_root,
                                 action_create_tag_cb);
 }
+
+struct mlx5dr_action *
+mlx5_hws_global_action_pop_vlan_get(struct mlx5_priv *priv,
+                                   enum mlx5dr_table_type table_type,
+                                   bool is_root)
+{
+       return global_action_get(priv,
+                                &priv->hw_global_actions.pop_vlan,
+                                "pop_vlan",
+                                table_type,
+                                is_root,
+                                action_create_pop_vlan_cb);
+}
diff --git a/drivers/net/mlx5/mlx5_hws_global_actions.h 
b/drivers/net/mlx5/mlx5_hws_global_actions.h
index bec9f3e0e8..d04ebc42be 100644
--- a/drivers/net/mlx5/mlx5_hws_global_actions.h
+++ b/drivers/net/mlx5/mlx5_hws_global_actions.h
@@ -26,6 +26,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;
+       struct mlx5_hws_global_actions_array pop_vlan;
        rte_spinlock_t lock;
 };
 
@@ -41,4 +42,8 @@ struct mlx5dr_action *mlx5_hws_global_action_tag_get(struct 
mlx5_priv *priv,
                                                     enum mlx5dr_table_type 
table_type,
                                                     bool is_root);
 
+struct mlx5dr_action *mlx5_hws_global_action_pop_vlan_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