HWS push_vlan action is used to implement OF_PUSH_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_PUSH_VLAN action.
This patch extends global actions internal API, introduced in previous commits, to allow lazy allocation of HWS push_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 | 78 +++------------------- drivers/net/mlx5/mlx5_hws_global_actions.c | 21 ++++++ drivers/net/mlx5/mlx5_hws_global_actions.h | 5 ++ 4 files changed, 36 insertions(+), 69 deletions(-) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 9e46a8cee8..94b4cb0d7b 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -2110,7 +2110,6 @@ struct mlx5_priv { LIST_HEAD(flow_hw_tbl, rte_flow_template_table) flow_hw_tbl; /* 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_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 21c61bce90..2ecae1b7e7 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -2737,8 +2737,16 @@ __flow_hw_translate_actions_template(struct rte_eth_dev *dev, mlx5_flow_hw_rxq_flag_set(dev, true); break; case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: - acts->rule_acts[dr_pos].action = - priv->hw_push_vlan[type]; + dr_action = mlx5_hws_global_action_push_vlan_get(priv, type, is_root); + if (dr_action == NULL) { + DRV_LOG(ERR, "port %u failed to allocate push VLAN action", + priv->dev_data->port_id); + rte_flow_error_set(&sub_error, ENOMEM, + RTE_FLOW_ERROR_TYPE_STATE, NULL, + "failed to allocate push VLAN action"); + goto err; + } + acts->rule_acts[dr_pos].action = dr_action; if (is_template_masked_push_vlan(masks->conf)) acts->rule_acts[dr_pos].push_vlan.vlan_hdr = vlan_hdr_to_be32(actions); @@ -11378,65 +11386,6 @@ mlx5_flow_ct_init(struct rte_eth_dev *dev, return ret; } -static void -flow_hw_destroy_vlan(struct rte_eth_dev *dev) -{ - struct mlx5_priv *priv = dev->data->dev_private; - enum mlx5dr_table_type i; - - for (i = MLX5DR_TABLE_TYPE_NIC_RX; i < MLX5DR_TABLE_TYPE_MAX; i++) { - if (priv->hw_push_vlan[i]) { - mlx5dr_action_destroy(priv->hw_push_vlan[i]); - priv->hw_push_vlan[i] = NULL; - } - } -} - -static int -_create_vlan(struct mlx5_priv *priv, enum mlx5dr_table_type type) -{ - const enum mlx5dr_action_flags flags[MLX5DR_TABLE_TYPE_MAX] = { - MLX5DR_ACTION_FLAG_HWS_RX, - MLX5DR_ACTION_FLAG_HWS_TX, - MLX5DR_ACTION_FLAG_HWS_FDB, - MLX5DR_ACTION_FLAG_HWS_FDB_RX, - MLX5DR_ACTION_FLAG_HWS_FDB_TX, - MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED, - }; - - /* rte_errno is set in the mlx5dr_action* functions. */ - priv->hw_push_vlan[type] = - mlx5dr_action_create_push_vlan(priv->dr_ctx, flags[type]); - if (!priv->hw_push_vlan[type]) - return -rte_errno; - return 0; -} - -static int -flow_hw_create_vlan(struct rte_eth_dev *dev) -{ - struct mlx5_priv *priv = dev->data->dev_private; - enum mlx5dr_table_type i, from, to; - int rc; - bool unified_fdb = is_unified_fdb(priv); - - for (i = MLX5DR_TABLE_TYPE_NIC_RX; i <= MLX5DR_TABLE_TYPE_NIC_TX; i++) { - rc = _create_vlan(priv, i); - if (rc) - return rc; - } - from = unified_fdb ? MLX5DR_TABLE_TYPE_FDB_RX : MLX5DR_TABLE_TYPE_FDB; - to = unified_fdb ? MLX5DR_TABLE_TYPE_FDB_UNIFIED : MLX5DR_TABLE_TYPE_FDB; - if (priv->sh->config.dv_esw_en && priv->master) { - for (i = from; i <= to; i++) { - rc = _create_vlan(priv, i); - if (rc) - return rc; - } - } - return 0; -} - void mlx5_flow_hw_cleanup_ctrl_rx_tables(struct rte_eth_dev *dev) { @@ -11992,7 +11941,6 @@ __mlx5_flow_hw_resource_release(struct rte_eth_dev *dev, bool ctx_close) if (priv->hw_def_miss) mlx5dr_action_destroy(priv->hw_def_miss); flow_hw_destroy_nat64_actions(priv); - flow_hw_destroy_vlan(dev); flow_hw_destroy_send_to_kernel_action(priv); flow_hw_free_vport_actions(priv); if (priv->acts_ipool) { @@ -12452,12 +12400,6 @@ __flow_hw_configure(struct rte_eth_dev *dev, if (ret < 0) goto err; } - ret = flow_hw_create_vlan(dev); - if (ret) { - rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, "Failed to VLAN actions."); - goto err; - } if (flow_hw_should_create_nat64_actions(priv)) { if (flow_hw_create_nat64_actions(priv, error)) goto err; diff --git a/drivers/net/mlx5/mlx5_hws_global_actions.c b/drivers/net/mlx5/mlx5_hws_global_actions.c index 236e6f1d1a..2bbfa5a24c 100644 --- a/drivers/net/mlx5/mlx5_hws_global_actions.c +++ b/drivers/net/mlx5/mlx5_hws_global_actions.c @@ -42,6 +42,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"); + global_actions_array_cleanup(priv, &priv->hw_global_actions.push_vlan, "push_vlan"); rte_spinlock_unlock(&priv->hw_global_actions.lock); } @@ -70,6 +71,13 @@ action_create_pop_vlan_cb(struct mlx5dr_context *ctx, return mlx5dr_action_create_pop_vlan(ctx, action_flags); } +static struct mlx5dr_action * +action_create_push_vlan_cb(struct mlx5dr_context *ctx, + uint32_t action_flags) +{ + return mlx5dr_action_create_push_vlan(ctx, action_flags); +} + static struct mlx5dr_action * global_action_get(struct mlx5_priv *priv, struct mlx5_hws_global_actions_array *array, @@ -145,3 +153,16 @@ mlx5_hws_global_action_pop_vlan_get(struct mlx5_priv *priv, is_root, action_create_pop_vlan_cb); } + +struct mlx5dr_action * +mlx5_hws_global_action_push_vlan_get(struct mlx5_priv *priv, + enum mlx5dr_table_type table_type, + bool is_root) +{ + return global_action_get(priv, + &priv->hw_global_actions.push_vlan, + "push_vlan", + table_type, + is_root, + action_create_push_vlan_cb); +} diff --git a/drivers/net/mlx5/mlx5_hws_global_actions.h b/drivers/net/mlx5/mlx5_hws_global_actions.h index d04ebc42be..4281ba701c 100644 --- a/drivers/net/mlx5/mlx5_hws_global_actions.h +++ b/drivers/net/mlx5/mlx5_hws_global_actions.h @@ -27,6 +27,7 @@ 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; + struct mlx5_hws_global_actions_array push_vlan; rte_spinlock_t lock; }; @@ -46,4 +47,8 @@ struct mlx5dr_action *mlx5_hws_global_action_pop_vlan_get(struct mlx5_priv *priv enum mlx5dr_table_type table_type, bool is_root); +struct mlx5dr_action *mlx5_hws_global_action_push_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

