HWS send_to_kernel action is used to implement SEND_TO_KERNEL 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 SEND_TO_KERNEL action.
This patch extends global actions internal API, introduced in previous commits, to allow lazy allocation of HWS send_to_kernel 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 | 2 - drivers/net/mlx5/mlx5_flow_hw.c | 90 ++++------------------ drivers/net/mlx5/mlx5_hws_global_actions.c | 59 +++++++++++--- drivers/net/mlx5/mlx5_hws_global_actions.h | 5 ++ 4 files changed, 66 insertions(+), 90 deletions(-) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 94b4cb0d7b..739b414faf 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -2115,8 +2115,6 @@ struct mlx5_priv { struct mlx5_hws_global_actions hw_global_actions; /* HW steering global default miss action. */ struct mlx5dr_action *hw_def_miss; - /* HW steering global send to kernel action. */ - struct mlx5dr_action *hw_send_to_kernel[MLX5DR_TABLE_TYPE_MAX]; /* HW steering create ongoing rte flow table list header. */ LIST_HEAD(flow_hw_tbl_ongo, rte_flow_template_table) flow_hw_tbl_ongo; struct mlx5_indexed_pool *acts_ipool; /* Action data indexed pool. */ diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index 2ecae1b7e7..7fafe3fe6a 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -2913,14 +2913,24 @@ __flow_hw_translate_actions_template(struct rte_eth_dev *dev, break; case RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL: if (is_root) { - __flow_hw_action_template_destroy(dev, acts); rte_flow_error_set(&sub_error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "Send to kernel action on root table is not supported in HW steering mode"); goto err; } - acts->rule_acts[dr_pos].action = priv->hw_send_to_kernel[type]; + dr_action = mlx5_hws_global_action_send_to_kernel_get(priv, + type, + MLX5_HW_LOWEST_PRIO_ROOT); + if (dr_action == NULL) { + DRV_LOG(ERR, "port %u failed to allocate send to kernel action", + priv->dev_data->port_id); + rte_flow_error_set(&sub_error, ENOMEM, + RTE_FLOW_ERROR_TYPE_STATE, NULL, + "failed to allocate send to kernel action"); + goto err; + } + acts->rule_acts[dr_pos].action = dr_action; break; case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD: err = flow_hw_modify_field_compile(dev, attr, actions, @@ -7366,36 +7376,14 @@ mlx5_flow_hw_actions_validate(struct rte_eth_dev *dev, action_flags |= MLX5_FLOW_ACTION_JUMP; break; #ifdef HAVE_MLX5DV_DR_ACTION_CREATE_DEST_ROOT_TABLE - case RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL: { - bool res; - + case RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL: if (priv->shared_host) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, action, "action not supported in guest port"); - if (attr->ingress) { - res = priv->hw_send_to_kernel[MLX5DR_TABLE_TYPE_NIC_RX]; - } else if (attr->egress) { - res = priv->hw_send_to_kernel[MLX5DR_TABLE_TYPE_NIC_TX]; - } else { - if (!is_unified_fdb(priv)) - res = priv->hw_send_to_kernel[MLX5DR_TABLE_TYPE_FDB]; - else - res = - priv->hw_send_to_kernel[MLX5DR_TABLE_TYPE_FDB_RX] && - priv->hw_send_to_kernel[MLX5DR_TABLE_TYPE_FDB_TX] && - priv->hw_send_to_kernel[MLX5DR_TABLE_TYPE_FDB_UNIFIED]; - } - if (!res) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, - action, - "action is not available"); - action_flags |= MLX5_FLOW_ACTION_SEND_TO_KERNEL; break; - } #endif case RTE_FLOW_ACTION_TYPE_QUEUE: ret = mlx5_hw_validate_action_queue(dev, action, mask, @@ -9891,55 +9879,6 @@ flow_hw_free_vport_actions(struct mlx5_priv *priv) priv->hw_vport = NULL; } -#ifdef HAVE_MLX5DV_DR_ACTION_CREATE_DEST_ROOT_TABLE -static __rte_always_inline void -_create_send_to_kernel_actions(struct mlx5_priv *priv, int type) -{ - int action_flag; - - action_flag = mlx5_hw_act_flag[1][type]; - priv->hw_send_to_kernel[type] = - mlx5dr_action_create_dest_root(priv->dr_ctx, - MLX5_HW_LOWEST_PRIO_ROOT, - action_flag); - if (!priv->hw_send_to_kernel[type]) - DRV_LOG(WARNING, "Unable to create HWS send to kernel action"); -} -#endif - -static void -flow_hw_create_send_to_kernel_actions(__rte_unused struct mlx5_priv *priv, - __rte_unused bool is_proxy) -{ -#ifdef HAVE_MLX5DV_DR_ACTION_CREATE_DEST_ROOT_TABLE - int i, from, to; - bool unified_fdb = is_unified_fdb(priv); - - for (i = MLX5DR_TABLE_TYPE_NIC_RX; i <= MLX5DR_TABLE_TYPE_NIC_TX; i++) - _create_send_to_kernel_actions(priv, i); - - if (is_proxy) { - from = unified_fdb ? MLX5DR_TABLE_TYPE_FDB_RX : MLX5DR_TABLE_TYPE_FDB; - to = unified_fdb ? MLX5DR_TABLE_TYPE_FDB_UNIFIED : MLX5DR_TABLE_TYPE_FDB; - for (i = from; i <= to; i++) - _create_send_to_kernel_actions(priv, i); - } -#endif -} - -static void -flow_hw_destroy_send_to_kernel_action(struct mlx5_priv *priv) -{ - int i; - - for (i = MLX5DR_TABLE_TYPE_NIC_RX; i < MLX5DR_TABLE_TYPE_MAX; i++) { - if (priv->hw_send_to_kernel[i]) { - mlx5dr_action_destroy(priv->hw_send_to_kernel[i]); - priv->hw_send_to_kernel[i] = NULL; - } - } -} - static bool flow_hw_should_create_nat64_actions(struct mlx5_priv *priv) { @@ -11941,7 +11880,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_send_to_kernel_action(priv); flow_hw_free_vport_actions(priv); if (priv->acts_ipool) { mlx5_ipool_destroy(priv->acts_ipool); @@ -12360,8 +12298,6 @@ __flow_hw_configure(struct rte_eth_dev *dev, goto err; } } - if (!priv->shared_host) - flow_hw_create_send_to_kernel_actions(priv, is_proxy); if (port_attr->nb_conn_tracks || (host_priv && host_priv->hws_ctpool)) { if (mlx5_flow_ct_init(dev, port_attr->nb_conn_tracks, nb_q_updated)) goto err; diff --git a/drivers/net/mlx5/mlx5_hws_global_actions.c b/drivers/net/mlx5/mlx5_hws_global_actions.c index 2bbfa5a24c..d8b21a67f1 100644 --- a/drivers/net/mlx5/mlx5_hws_global_actions.c +++ b/drivers/net/mlx5/mlx5_hws_global_actions.c @@ -43,48 +43,67 @@ mlx5_hws_global_actions_cleanup(struct mlx5_priv *priv) 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"); + global_actions_array_cleanup(priv, + &priv->hw_global_actions.send_to_kernel, + "send_to_kernel"); rte_spinlock_unlock(&priv->hw_global_actions.lock); } typedef struct mlx5dr_action *(*global_action_create_t)(struct mlx5dr_context *ctx, - uint32_t action_flags); + uint32_t action_flags, + void *user_data); static struct mlx5dr_action * action_create_drop_cb(struct mlx5dr_context *ctx, - uint32_t action_flags) + uint32_t action_flags, + void *user_data __rte_unused) { 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) + uint32_t action_flags, + void *user_data __rte_unused) { 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) + uint32_t action_flags, + void *user_data __rte_unused) { 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) + uint32_t action_flags, + void *user_data __rte_unused) { return mlx5dr_action_create_push_vlan(ctx, action_flags); } +static struct mlx5dr_action * +action_create_send_to_kernel_cb(struct mlx5dr_context *ctx, + uint32_t action_flags, + void *user_data) +{ + uint16_t priority = (uint16_t)(uintptr_t)user_data; + + return mlx5dr_action_create_dest_root(ctx, priority, 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) + global_action_create_t create_cb, + void *user_data) { enum mlx5dr_action_flags action_flags; struct mlx5dr_action *action = NULL; @@ -100,7 +119,7 @@ global_action_get(struct mlx5_priv *priv, if (action != NULL) goto unlock_ret; - action = create_cb(priv->dr_ctx, action_flags); + action = create_cb(priv->dr_ctx, action_flags, user_data); if (action == NULL) { DRV_LOG(ERR, "port %u failed to create %s HWS action", priv->dev_data->port_id, @@ -125,7 +144,8 @@ mlx5_hws_global_action_drop_get(struct mlx5_priv *priv, "drop", table_type, is_root, - action_create_drop_cb); + action_create_drop_cb, + NULL); } struct mlx5dr_action * @@ -138,7 +158,8 @@ mlx5_hws_global_action_tag_get(struct mlx5_priv *priv, "tag", table_type, is_root, - action_create_tag_cb); + action_create_tag_cb, + NULL); } struct mlx5dr_action * @@ -151,7 +172,8 @@ mlx5_hws_global_action_pop_vlan_get(struct mlx5_priv *priv, "pop_vlan", table_type, is_root, - action_create_pop_vlan_cb); + action_create_pop_vlan_cb, + NULL); } struct mlx5dr_action * @@ -164,5 +186,20 @@ mlx5_hws_global_action_push_vlan_get(struct mlx5_priv *priv, "push_vlan", table_type, is_root, - action_create_push_vlan_cb); + action_create_push_vlan_cb, + NULL); +} + +struct mlx5dr_action * +mlx5_hws_global_action_send_to_kernel_get(struct mlx5_priv *priv, + enum mlx5dr_table_type table_type, + uint16_t priority) +{ + return global_action_get(priv, + &priv->hw_global_actions.send_to_kernel, + "send_to_kernel", + table_type, + false, /* send-to-kernel is non-root only */ + action_create_send_to_kernel_cb, + (void *)(uintptr_t)priority); } diff --git a/drivers/net/mlx5/mlx5_hws_global_actions.h b/drivers/net/mlx5/mlx5_hws_global_actions.h index 4281ba701c..7fbca9fc96 100644 --- a/drivers/net/mlx5/mlx5_hws_global_actions.h +++ b/drivers/net/mlx5/mlx5_hws_global_actions.h @@ -28,6 +28,7 @@ struct mlx5_hws_global_actions { struct mlx5_hws_global_actions_array tag; struct mlx5_hws_global_actions_array pop_vlan; struct mlx5_hws_global_actions_array push_vlan; + struct mlx5_hws_global_actions_array send_to_kernel; rte_spinlock_t lock; }; @@ -51,4 +52,8 @@ struct mlx5dr_action *mlx5_hws_global_action_push_vlan_get(struct mlx5_priv *pri enum mlx5dr_table_type table_type, bool is_root); +struct mlx5dr_action *mlx5_hws_global_action_send_to_kernel_get(struct mlx5_priv *priv, + enum mlx5dr_table_type table_type, + uint16_t priority); + #endif /* !RTE_PMD_MLX5_HWS_GLOBAL_ACTIONS_H_ */ -- 2.47.3

