* [PATCH] net/mlx5/hws: add support for multi pattern
@ 2023-07-09 14:20 Alex Vesker
2023-08-30 12:26 ` Raslan Darawsheh
0 siblings, 1 reply; 2+ messages in thread
From: Alex Vesker @ 2023-07-09 14:20 UTC (permalink / raw)
To: valex, viacheslavo, thomas, suanmingm, Matan Azrad, Ori Kam; +Cc: dev
When creating an action it can contain a bulk of objects,
but the objects are fixed to a specific pattern and cannot
be reused. This can lead to inefficient usage of the HW resources,
This support allows creating multiple patterns over a single
mlx5dr action.
Signed-off-by: Alex Vesker <valex@nvidia.com>
Reviewed-by: Erez Shitrit <erezsh@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
drivers/net/mlx5/hws/mlx5dr.h | 45 ++-
drivers/net/mlx5/hws/mlx5dr_action.c | 538 +++++++++++++++-----------
drivers/net/mlx5/hws/mlx5dr_action.h | 8 +-
drivers/net/mlx5/hws/mlx5dr_pat_arg.c | 252 +++++-------
drivers/net/mlx5/hws/mlx5dr_pat_arg.h | 34 +-
drivers/net/mlx5/mlx5_flow_hw.c | 11 +-
6 files changed, 483 insertions(+), 405 deletions(-)
diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h
index ec2230d136..6b96a120f7 100644
--- a/drivers/net/mlx5/hws/mlx5dr.h
+++ b/drivers/net/mlx5/hws/mlx5dr.h
@@ -156,8 +156,21 @@ struct mlx5dr_devx_obj {
uint32_t id;
};
-/* In actions that take offset, the offset is unique, and the user should not
- * reuse the same index because data changing is not atomic.
+struct mlx5dr_action_reformat_header {
+ size_t sz;
+ void *data;
+};
+
+struct mlx5dr_action_mh_pattern {
+ /* Byte size of modify actions provided by "data" */
+ size_t sz;
+ /* PRM format modify actions pattern */
+ __be64 *data;
+};
+
+/* In actions that take offset, the offset is unique, pointing to a single
+ * resource and the user should not reuse the same index because data changing
+ * is not atomic.
*/
struct mlx5dr_rule_action {
struct mlx5dr_action *action;
@@ -172,11 +185,13 @@ struct mlx5dr_rule_action {
struct {
uint32_t offset;
+ uint8_t pattern_idx;
uint8_t *data;
} modify_header;
struct {
uint32_t offset;
+ uint8_t hdr_idx;
uint8_t *data;
} reformat;
@@ -481,12 +496,12 @@ mlx5dr_action_create_counter(struct mlx5dr_context *ctx,
* The context in which the new action will be created.
* @param[in] reformat_type
* Type of reformat prefixed with MLX5DR_ACTION_TYP_REFORMAT.
- * @param[in] data_sz
- * Size in bytes of data.
- * @param[in] inline_data
- * Header data array in case of inline action.
+ * @param[in] num_of_hdrs
+ * Number of provided headers in "hdrs" array.
+ * @param[in] hdrs
+ * Headers array containing header information.
* @param[in] log_bulk_size
- * Number of unique values used with this pattern.
+ * Number of unique values used with this reformat.
* @param[in] flags
* Action creation flags. (enum mlx5dr_action_flags)
* @return pointer to mlx5dr_action on success NULL otherwise.
@@ -494,8 +509,8 @@ mlx5dr_action_create_counter(struct mlx5dr_context *ctx,
struct mlx5dr_action *
mlx5dr_action_create_reformat(struct mlx5dr_context *ctx,
enum mlx5dr_action_type reformat_type,
- size_t data_sz,
- void *inline_data,
+ uint8_t num_of_hdrs,
+ struct mlx5dr_action_reformat_header *hdrs,
uint32_t log_bulk_size,
uint32_t flags);
@@ -503,10 +518,10 @@ mlx5dr_action_create_reformat(struct mlx5dr_context *ctx,
*
* @param[in] ctx
* The context in which the new action will be created.
- * @param[in] pattern_sz
- * Byte size of the pattern array.
- * @param[in] pattern
- * PRM format modify pattern action array.
+ * @param[in] num_of_patterns
+ * Number of provided patterns in "patterns" array.
+ * @param[in] patterns
+ * Patterns array containing pattern information.
* @param[in] log_bulk_size
* Number of unique values used with this pattern.
* @param[in] flags
@@ -515,8 +530,8 @@ mlx5dr_action_create_reformat(struct mlx5dr_context *ctx,
*/
struct mlx5dr_action *
mlx5dr_action_create_modify_header(struct mlx5dr_context *ctx,
- size_t pattern_sz,
- __be64 pattern[],
+ uint8_t num_of_patterns,
+ struct mlx5dr_action_mh_pattern *patterns,
uint32_t log_bulk_size,
uint32_t flags);
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c
index 920099ba5b..48fb6d3eaa 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.c
+++ b/drivers/net/mlx5/hws/mlx5dr_action.c
@@ -529,7 +529,7 @@ static void mlx5dr_action_fill_stc_attr(struct mlx5dr_action *action,
} else {
attr->action_type = MLX5_IFC_STC_ACTION_TYPE_ACC_MODIFY_LIST;
attr->modify_header.arg_id = action->modify_header.arg_obj->id;
- attr->modify_header.pattern_id = action->modify_header.pattern_obj->id;
+ attr->modify_header.pattern_id = action->modify_header.pat_obj->id;
}
break;
case MLX5DR_ACTION_TYP_TBL:
@@ -705,11 +705,13 @@ mlx5dr_action_is_hws_flags(uint32_t flags)
}
static struct mlx5dr_action *
-mlx5dr_action_create_generic(struct mlx5dr_context *ctx,
- uint32_t flags,
- enum mlx5dr_action_type action_type)
+mlx5dr_action_create_generic_bulk(struct mlx5dr_context *ctx,
+ uint32_t flags,
+ enum mlx5dr_action_type action_type,
+ uint8_t bulk_sz)
{
struct mlx5dr_action *action;
+ int i;
if (!mlx5dr_action_is_root_flags(flags) &&
!mlx5dr_action_is_hws_flags(flags)) {
@@ -725,20 +727,30 @@ mlx5dr_action_create_generic(struct mlx5dr_context *ctx,
return NULL;
}
- action = simple_calloc(1, sizeof(*action));
+ action = simple_calloc(bulk_sz, sizeof(*action));
if (!action) {
DR_LOG(ERR, "Failed to allocate memory for action [%d]", action_type);
rte_errno = ENOMEM;
return NULL;
}
- action->ctx = ctx;
- action->flags = flags;
- action->type = action_type;
+ for (i = 0; i < bulk_sz; i++) {
+ action[i].ctx = ctx;
+ action[i].flags = flags;
+ action[i].type = action_type;
+ }
return action;
}
+static struct mlx5dr_action *
+mlx5dr_action_create_generic(struct mlx5dr_context *ctx,
+ uint32_t flags,
+ enum mlx5dr_action_type action_type)
+{
+ return mlx5dr_action_create_generic_bulk(ctx, flags, action_type, 1);
+}
+
struct mlx5dr_action *
mlx5dr_action_create_dest_table(struct mlx5dr_context *ctx,
struct mlx5dr_table *tbl,
@@ -1141,7 +1153,7 @@ mlx5dr_action_create_pop_vlan(struct mlx5dr_context *ctx, uint32_t flags)
return NULL;
}
-static void
+static int
mlx5dr_action_conv_reformat_to_verbs(uint32_t action_type,
uint32_t *verb_reformat_type)
{
@@ -1149,19 +1161,23 @@ mlx5dr_action_conv_reformat_to_verbs(uint32_t action_type,
case MLX5DR_ACTION_TYP_REFORMAT_TNL_L2_TO_L2:
*verb_reformat_type =
MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2;
- break;
+ return 0;
case MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2:
*verb_reformat_type =
MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL;
- break;
+ return 0;
case MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2:
*verb_reformat_type =
MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2;
- break;
+ return 0;
case MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3:
*verb_reformat_type =
MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL;
- break;
+ return 0;
+ default:
+ DR_LOG(ERR, "Invalid root reformat action type");
+ rte_errno = EINVAL;
+ return rte_errno;
}
}
@@ -1199,7 +1215,9 @@ mlx5dr_action_create_reformat_root(struct mlx5dr_action *action,
if (ret)
return rte_errno;
- mlx5dr_action_conv_reformat_to_verbs(action->type, &verb_reformat_type);
+ ret = mlx5dr_action_conv_reformat_to_verbs(action->type, &verb_reformat_type);
+ if (ret)
+ return rte_errno;
/* Create the reformat type for root table */
ibv_ctx = mlx5dr_context_get_local_ibv(action->ctx);
@@ -1210,6 +1228,7 @@ mlx5dr_action_create_reformat_root(struct mlx5dr_action *action,
verb_reformat_type,
ft_type);
if (!action->flow_action) {
+ DR_LOG(ERR, "Failed to create dv_create_flow reformat");
rte_errno = errno;
return rte_errno;
}
@@ -1217,132 +1236,84 @@ mlx5dr_action_create_reformat_root(struct mlx5dr_action *action,
return 0;
}
-static int mlx5dr_action_handle_reformat_args(struct mlx5dr_context *ctx,
- size_t data_sz,
- void *data,
- uint32_t bulk_size,
- struct mlx5dr_action *action)
-{
- uint32_t args_log_size;
- int ret;
-
- if (data_sz % 2 != 0) {
- DR_LOG(ERR, "Data size should be multiply of 2");
- rte_errno = EINVAL;
- return rte_errno;
- }
- action->reformat.header_size = data_sz;
-
- args_log_size = mlx5dr_arg_data_size_to_arg_log_size(data_sz);
- if (args_log_size >= MLX5DR_ARG_CHUNK_SIZE_MAX) {
- DR_LOG(ERR, "Data size is bigger than supported");
- rte_errno = EINVAL;
- return rte_errno;
+static int
+mlx5dr_action_handle_l2_to_tunnel_l2(struct mlx5dr_action *action,
+ uint8_t num_of_hdrs,
+ struct mlx5dr_action_reformat_header *hdrs,
+ uint32_t log_bulk_sz)
+{
+ struct mlx5dr_devx_obj *arg_obj;
+ size_t max_sz = 0;
+ int ret, i;
+
+ for (i = 0; i < num_of_hdrs; i++) {
+ if (hdrs[i].sz % 2 != 0) {
+ DR_LOG(ERR, "Header data size should be multiply of 2");
+ rte_errno = EINVAL;
+ return rte_errno;
+ }
+ max_sz = RTE_MAX(hdrs[i].sz, max_sz);
}
- args_log_size += bulk_size;
- if (!mlx5dr_arg_is_valid_arg_request_size(ctx, args_log_size)) {
- DR_LOG(ERR, "Arg size %d does not fit FW requests",
- args_log_size);
- rte_errno = EINVAL;
+ /* Allocate single shared arg object for all headers */
+ arg_obj = mlx5dr_arg_create(action->ctx,
+ hdrs->data,
+ max_sz,
+ log_bulk_sz,
+ action->flags & MLX5DR_ACTION_FLAG_SHARED);
+ if (!arg_obj)
return rte_errno;
- }
- action->reformat.arg_obj = mlx5dr_cmd_arg_create(ctx->ibv_ctx,
- args_log_size,
- ctx->pd_num);
- if (!action->reformat.arg_obj) {
- DR_LOG(ERR, "Failed to create arg for reformat");
- return rte_errno;
- }
+ for (i = 0; i < num_of_hdrs; i++) {
+ action[i].reformat.arg_obj = arg_obj;
+ action[i].reformat.header_size = hdrs[i].sz;
+ action[i].reformat.num_of_hdrs = num_of_hdrs;
+ action[i].reformat.max_hdr_sz = max_sz;
- /* When INLINE need to write the arg data */
- if (action->flags & MLX5DR_ACTION_FLAG_SHARED) {
- ret = mlx5dr_arg_write_inline_arg_data(ctx,
- action->reformat.arg_obj->id,
- data,
- data_sz);
+ ret = mlx5dr_action_create_stcs(&action[i], NULL);
if (ret) {
- DR_LOG(ERR, "Failed to write inline arg for reformat");
- goto free_arg;
+ DR_LOG(ERR, "Failed to create stc for reformat");
+ goto free_stc;
}
}
return 0;
-free_arg:
- mlx5dr_cmd_destroy_obj(action->reformat.arg_obj);
- return ret;
-}
-
-static int mlx5dr_action_handle_l2_to_tunnel_l2(struct mlx5dr_context *ctx,
- size_t data_sz,
- void *data,
- uint32_t bulk_size,
- struct mlx5dr_action *action)
-{
- int ret;
+free_stc:
+ while (i--)
+ mlx5dr_action_destroy_stcs(&action[i]);
- ret = mlx5dr_action_handle_reformat_args(ctx, data_sz, data, bulk_size,
- action);
- if (ret) {
- DR_LOG(ERR, "Failed to create args for reformat");
- return ret;
- }
-
- ret = mlx5dr_action_create_stcs(action, NULL);
- if (ret) {
- DR_LOG(ERR, "Failed to create stc for reformat");
- goto free_arg;
- }
-
- return 0;
-
-free_arg:
- mlx5dr_cmd_destroy_obj(action->reformat.arg_obj);
+ mlx5dr_cmd_destroy_obj(arg_obj);
return ret;
}
-static int mlx5dr_action_get_shared_stc_offset(struct mlx5dr_context_common_res *common_res,
- enum mlx5dr_context_shared_stc_type stc_type)
-{
- return common_res->shared_stc[stc_type]->remove_header.offset;
-}
-
-static int mlx5dr_action_handle_l2_to_tunnel_l3(struct mlx5dr_context *ctx,
- size_t data_sz,
- void *data,
- uint32_t bulk_size,
- struct mlx5dr_action *action)
+static int
+mlx5dr_action_handle_l2_to_tunnel_l3(struct mlx5dr_action *action,
+ uint8_t num_of_hdrs,
+ struct mlx5dr_action_reformat_header *hdrs,
+ uint32_t log_bulk_sz)
{
int ret;
- ret = mlx5dr_action_handle_reformat_args(ctx, data_sz, data, bulk_size,
- action);
- if (ret) {
- DR_LOG(ERR, "Failed to create args for reformat");
- return ret;
- }
-
/* The action is remove-l2-header + insert-l3-header */
ret = mlx5dr_action_get_shared_stc(action, MLX5DR_CONTEXT_SHARED_STC_DECAP);
if (ret) {
DR_LOG(ERR, "Failed to create remove stc for reformat");
- goto free_arg;
+ return ret;
}
- ret = mlx5dr_action_create_stcs(action, NULL);
- if (ret) {
- DR_LOG(ERR, "Failed to create insert stc for reformat");
- goto down_shared;
- }
+ /* Reuse the insert with pointer for the L2L3 header */
+ ret = mlx5dr_action_handle_l2_to_tunnel_l2(action,
+ num_of_hdrs,
+ hdrs,
+ log_bulk_sz);
+ if (ret)
+ goto put_shared_stc;
return 0;
-down_shared:
+put_shared_stc:
mlx5dr_action_put_shared_stc(action, MLX5DR_CONTEXT_SHARED_STC_DECAP);
-free_arg:
- mlx5dr_cmd_destroy_obj(action->reformat.arg_obj);
return ret;
}
@@ -1393,67 +1364,81 @@ static void mlx5dr_action_prepare_decap_l3_actions(size_t data_sz,
}
static int
-mlx5dr_action_handle_tunnel_l3_to_l2(struct mlx5dr_context *ctx,
- size_t data_sz,
- void *data,
- uint32_t bulk_size,
- struct mlx5dr_action *action)
+mlx5dr_action_handle_tunnel_l3_to_l2(struct mlx5dr_action *action,
+ uint8_t num_of_hdrs,
+ struct mlx5dr_action_reformat_header *hdrs,
+ uint32_t log_bulk_sz)
{
uint8_t mh_data[MLX5DR_ACTION_REFORMAT_DATA_SIZE] = {0};
+ struct mlx5dr_devx_obj *arg_obj, *pat_obj;
+ struct mlx5dr_context *ctx = action->ctx;
int num_of_actions;
int mh_data_size;
- int ret;
+ int ret, i;
- if (data_sz != MLX5DR_ACTION_HDR_LEN_L2 &&
- data_sz != MLX5DR_ACTION_HDR_LEN_L2_W_VLAN) {
- DR_LOG(ERR, "Data size is not supported for decap-l3");
- rte_errno = EINVAL;
- return rte_errno;
+ for (i = 0; i < num_of_hdrs; i++) {
+ if (hdrs[i].sz != MLX5DR_ACTION_HDR_LEN_L2 &&
+ hdrs[i].sz != MLX5DR_ACTION_HDR_LEN_L2_W_VLAN) {
+ DR_LOG(ERR, "Data size is not supported for decap-l3");
+ rte_errno = EINVAL;
+ return rte_errno;
+ }
}
- mlx5dr_action_prepare_decap_l3_actions(data_sz, mh_data, &num_of_actions);
+ /* Create a full modify header action list in case shared */
+ mlx5dr_action_prepare_decap_l3_actions(hdrs->sz, mh_data, &num_of_actions);
+ mlx5dr_action_prepare_decap_l3_data(hdrs->data, mh_data, num_of_actions);
- mh_data_size = num_of_actions * MLX5DR_MODIFY_ACTION_SIZE;
+ /* All DecapL3 cases require the same max arg size */
+ arg_obj = mlx5dr_arg_create_modify_header_arg(ctx,
+ (__be64 *)mh_data,
+ num_of_actions,
+ log_bulk_sz,
+ action->flags & MLX5DR_ACTION_FLAG_SHARED);
+ if (!arg_obj)
+ return rte_errno;
- ret = mlx5dr_pat_arg_create_modify_header(ctx, action, mh_data_size,
- (__be64 *)mh_data, bulk_size);
- if (ret) {
- DR_LOG(ERR, "Failed allocating modify-header for decap-l3");
- return ret;
- }
+ for (i = 0; i < num_of_hdrs; i++) {
+ memset(mh_data, 0, MLX5DR_ACTION_REFORMAT_DATA_SIZE);
+ mlx5dr_action_prepare_decap_l3_actions(hdrs[i].sz, mh_data, &num_of_actions);
+ mh_data_size = num_of_actions * MLX5DR_MODIFY_ACTION_SIZE;
- ret = mlx5dr_action_create_stcs(action, NULL);
- if (ret)
- goto free_mh_obj;
-
- if (action->flags & MLX5DR_ACTION_FLAG_SHARED) {
- mlx5dr_action_prepare_decap_l3_data(data, mh_data, num_of_actions);
- ret = mlx5dr_arg_write_inline_arg_data(ctx,
- action->modify_header.arg_obj->id,
- (uint8_t *)mh_data,
- num_of_actions *
- MLX5DR_MODIFY_ACTION_SIZE);
+ pat_obj = mlx5dr_pat_get_pattern(ctx, (__be64 *)mh_data, mh_data_size);
+ if (!pat_obj) {
+ DR_LOG(ERR, "Failed to allocate pattern for DecapL3");
+ goto free_stc_and_pat;
+ }
+
+ action[i].modify_header.max_num_of_actions = num_of_actions;
+ action[i].modify_header.num_of_actions = num_of_actions;
+ action[i].modify_header.arg_obj = arg_obj;
+ action[i].modify_header.pat_obj = pat_obj;
+
+ ret = mlx5dr_action_create_stcs(&action[i], NULL);
if (ret) {
- DR_LOG(ERR, "Failed writing INLINE arg decap_l3");
- goto clean_stc;
+ mlx5dr_pat_put_pattern(ctx, pat_obj);
+ goto free_stc_and_pat;
}
}
return 0;
-clean_stc:
- mlx5dr_action_destroy_stcs(action);
-free_mh_obj:
- mlx5dr_pat_arg_destroy_modify_header(ctx, action);
- return ret;
+
+free_stc_and_pat:
+ while (i--) {
+ mlx5dr_action_destroy_stcs(&action[i]);
+ mlx5dr_pat_put_pattern(ctx, action[i].modify_header.pat_obj);
+ }
+
+ mlx5dr_cmd_destroy_obj(arg_obj);
+ return 0;
}
static int
-mlx5dr_action_create_reformat_hws(struct mlx5dr_context *ctx,
- size_t data_sz,
- void *data,
- uint32_t bulk_size,
- struct mlx5dr_action *action)
+mlx5dr_action_create_reformat_hws(struct mlx5dr_action *action,
+ uint8_t num_of_hdrs,
+ struct mlx5dr_action_reformat_header *hdrs,
+ uint32_t bulk_size)
{
int ret;
@@ -1462,18 +1447,17 @@ mlx5dr_action_create_reformat_hws(struct mlx5dr_context *ctx,
ret = mlx5dr_action_create_stcs(action, NULL);
break;
case MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2:
- ret = mlx5dr_action_handle_l2_to_tunnel_l2(ctx, data_sz, data, bulk_size, action);
+ ret = mlx5dr_action_handle_l2_to_tunnel_l2(action, num_of_hdrs, hdrs, bulk_size);
break;
case MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3:
- ret = mlx5dr_action_handle_l2_to_tunnel_l3(ctx, data_sz, data, bulk_size, action);
+ ret = mlx5dr_action_handle_l2_to_tunnel_l3(action, num_of_hdrs, hdrs, bulk_size);
break;
case MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2:
- ret = mlx5dr_action_handle_tunnel_l3_to_l2(ctx, data_sz, data, bulk_size, action);
+ ret = mlx5dr_action_handle_tunnel_l3_to_l2(action, num_of_hdrs, hdrs, bulk_size);
break;
-
default:
- assert(false);
- rte_errno = ENOTSUP;
+ DR_LOG(ERR, "Invalid HWS reformat action type");
+ rte_errno = EINVAL;
return rte_errno;
}
@@ -1483,15 +1467,20 @@ mlx5dr_action_create_reformat_hws(struct mlx5dr_context *ctx,
struct mlx5dr_action *
mlx5dr_action_create_reformat(struct mlx5dr_context *ctx,
enum mlx5dr_action_type reformat_type,
- size_t data_sz,
- void *inline_data,
+ uint8_t num_of_hdrs,
+ struct mlx5dr_action_reformat_header *hdrs,
uint32_t log_bulk_size,
uint32_t flags)
{
struct mlx5dr_action *action;
int ret;
- action = mlx5dr_action_create_generic(ctx, flags, reformat_type);
+ if (!num_of_hdrs) {
+ DR_LOG(ERR, "Reformat num_of_hdrs cannot be zero");
+ return NULL;
+ }
+
+ action = mlx5dr_action_create_generic_bulk(ctx, flags, reformat_type, num_of_hdrs);
if (!action)
return NULL;
@@ -1502,24 +1491,27 @@ mlx5dr_action_create_reformat(struct mlx5dr_context *ctx,
goto free_action;
}
- ret = mlx5dr_action_create_reformat_root(action, data_sz, inline_data);
- if (ret)
+ ret = mlx5dr_action_create_reformat_root(action,
+ hdrs ? hdrs->sz : 0,
+ hdrs ? hdrs->data : NULL);
+ if (ret) {
+ DR_LOG(ERR, "Failed to create root reformat action");
goto free_action;
+ }
return action;
}
if (!mlx5dr_action_is_hws_flags(flags) ||
- ((flags & MLX5DR_ACTION_FLAG_SHARED) && log_bulk_size)) {
- DR_LOG(ERR, "Reformat flags don't fit HWS (flags: %x0x)",
- flags);
+ ((flags & MLX5DR_ACTION_FLAG_SHARED) && (log_bulk_size || num_of_hdrs > 1))) {
+ DR_LOG(ERR, "Reformat flags don't fit HWS (flags: %x0x)", flags);
rte_errno = EINVAL;
goto free_action;
}
- ret = mlx5dr_action_create_reformat_hws(ctx, data_sz, inline_data, log_bulk_size, action);
+ ret = mlx5dr_action_create_reformat_hws(action, num_of_hdrs, hdrs, log_bulk_size);
if (ret) {
- DR_LOG(ERR, "Failed to create reformat.");
+ DR_LOG(ERR, "Failed to create HWS reformat action");
rte_errno = EINVAL;
goto free_action;
}
@@ -1559,17 +1551,104 @@ mlx5dr_action_create_modify_header_root(struct mlx5dr_action *action,
return 0;
}
+static int
+mlx5dr_action_create_modify_header_hws(struct mlx5dr_action *action,
+ uint8_t num_of_patterns,
+ struct mlx5dr_action_mh_pattern *pattern,
+ uint32_t log_bulk_size)
+{
+ struct mlx5dr_devx_obj *pat_obj, *arg_obj = NULL;
+ struct mlx5dr_context *ctx = action->ctx;
+ uint16_t max_mh_actions = 0;
+ int i, ret;
+
+ /* Caclulate maximum number of mh actions for shared arg allocation */
+ for (i = 0; i < num_of_patterns; i++)
+ max_mh_actions = RTE_MAX(max_mh_actions, pattern[i].sz / MLX5DR_MODIFY_ACTION_SIZE);
+
+ /* Allocate single shared arg for all patterns based on the max size */
+ if (max_mh_actions > 1) {
+ arg_obj = mlx5dr_arg_create_modify_header_arg(ctx,
+ pattern->data,
+ max_mh_actions,
+ log_bulk_size,
+ action->flags &
+ MLX5DR_ACTION_FLAG_SHARED);
+ if (!arg_obj)
+ return rte_errno;
+ }
+
+ for (i = 0; i < num_of_patterns; i++) {
+ if (!mlx5dr_pat_verify_actions(pattern[i].data, pattern[i].sz)) {
+ DR_LOG(ERR, "Fail to verify pattern modify actions");
+ rte_errno = EINVAL;
+ goto free_stc_and_pat;
+ }
+
+ action[i].modify_header.num_of_patterns = num_of_patterns;
+ action[i].modify_header.max_num_of_actions = max_mh_actions;
+ action[i].modify_header.num_of_actions = pattern[i].sz / MLX5DR_MODIFY_ACTION_SIZE;
+
+ if (action[i].modify_header.num_of_actions == 1) {
+ pat_obj = NULL;
+ /* Optimize single modify action to be used inline */
+ action[i].modify_header.single_action = pattern[i].data[0];
+ action[i].modify_header.single_action_type =
+ MLX5_GET(set_action_in, pattern[i].data, action_type);
+ } else {
+ /* Multiple modify actions require a pattern */
+ pat_obj = mlx5dr_pat_get_pattern(ctx, pattern[i].data, pattern[i].sz);
+ if (!pat_obj) {
+ DR_LOG(ERR, "Failed to allocate pattern for modify header");
+ goto free_stc_and_pat;
+ }
+
+ action[i].modify_header.arg_obj = arg_obj;
+ action[i].modify_header.pat_obj = pat_obj;
+ }
+ /* Allocate STC for each action representing a header */
+ ret = mlx5dr_action_create_stcs(&action[i], NULL);
+ if (ret) {
+ if (pat_obj)
+ mlx5dr_pat_put_pattern(ctx, pat_obj);
+ goto free_stc_and_pat;
+ }
+ }
+
+ return 0;
+
+free_stc_and_pat:
+ while (i--) {
+ mlx5dr_action_destroy_stcs(&action[i]);
+ if (action[i].modify_header.pat_obj)
+ mlx5dr_pat_put_pattern(ctx, action[i].modify_header.pat_obj);
+ }
+
+ if (arg_obj)
+ mlx5dr_cmd_destroy_obj(arg_obj);
+
+ return rte_errno;
+}
+
struct mlx5dr_action *
mlx5dr_action_create_modify_header(struct mlx5dr_context *ctx,
- size_t pattern_sz,
- __be64 pattern[],
+ uint8_t num_of_patterns,
+ struct mlx5dr_action_mh_pattern *patterns,
uint32_t log_bulk_size,
uint32_t flags)
{
struct mlx5dr_action *action;
int ret;
- action = mlx5dr_action_create_generic(ctx, flags, MLX5DR_ACTION_TYP_MODIFY_HDR);
+ if (!num_of_patterns) {
+ DR_LOG(ERR, "Invalid number of patterns");
+ rte_errno = ENOTSUP;
+ return NULL;
+ }
+
+ action = mlx5dr_action_create_generic_bulk(ctx, flags,
+ MLX5DR_ACTION_TYP_MODIFY_HDR,
+ num_of_patterns);
if (!action)
return NULL;
@@ -1579,52 +1658,37 @@ mlx5dr_action_create_modify_header(struct mlx5dr_context *ctx,
rte_errno = ENOTSUP;
goto free_action;
}
- ret = mlx5dr_action_create_modify_header_root(action, pattern_sz, pattern);
+
+ if (num_of_patterns != 1) {
+ DR_LOG(ERR, "Only a single pattern supported over root");
+ rte_errno = ENOTSUP;
+ goto free_action;
+ }
+
+ ret = mlx5dr_action_create_modify_header_root(action,
+ patterns->sz,
+ patterns->data);
if (ret)
goto free_action;
return action;
}
- if (!mlx5dr_action_is_hws_flags(flags) ||
- ((flags & MLX5DR_ACTION_FLAG_SHARED) && log_bulk_size)) {
- DR_LOG(ERR, "Flags don't fit hws (flags: %x0x, log_bulk_size: %d)",
- flags, log_bulk_size);
+ if ((flags & MLX5DR_ACTION_FLAG_SHARED) && (log_bulk_size || num_of_patterns > 1)) {
+ DR_LOG(ERR, "Action cannot be shared with requested pattern or size");
rte_errno = EINVAL;
goto free_action;
}
- if (!mlx5dr_pat_arg_verify_actions(pattern, pattern_sz / MLX5DR_MODIFY_ACTION_SIZE)) {
- DR_LOG(ERR, "One of the actions is not supported");
- rte_errno = EINVAL;
- goto free_action;
- }
-
- if (pattern_sz / MLX5DR_MODIFY_ACTION_SIZE == 1) {
- /* Optimize single modiy action to be used inline */
- action->modify_header.single_action = pattern[0];
- action->modify_header.num_of_actions = 1;
- action->modify_header.single_action_type =
- MLX5_GET(set_action_in, pattern, action_type);
- } else {
- /* Use multi action pattern and argument */
- ret = mlx5dr_pat_arg_create_modify_header(ctx, action, pattern_sz,
- pattern, log_bulk_size);
- if (ret) {
- DR_LOG(ERR, "Failed allocating modify-header");
- goto free_action;
- }
- }
-
- ret = mlx5dr_action_create_stcs(action, NULL);
+ ret = mlx5dr_action_create_modify_header_hws(action,
+ num_of_patterns,
+ patterns,
+ log_bulk_size);
if (ret)
- goto free_mh_obj;
+ goto free_action;
return action;
-free_mh_obj:
- if (action->modify_header.num_of_actions > 1)
- mlx5dr_pat_arg_destroy_modify_header(ctx, action);
free_action:
simple_free(action);
return NULL;
@@ -1684,6 +1748,9 @@ mlx5dr_action_create_dest_root(struct mlx5dr_context *ctx,
static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)
{
+ struct mlx5dr_devx_obj *obj = NULL;
+ uint32_t i;
+
switch (action->type) {
case MLX5DR_ACTION_TYP_TIR:
mlx5dr_action_destroy_stcs(action);
@@ -1711,17 +1778,28 @@ static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)
break;
case MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2:
case MLX5DR_ACTION_TYP_MODIFY_HDR:
- mlx5dr_action_destroy_stcs(action);
- if (action->modify_header.num_of_actions > 1)
- mlx5dr_pat_arg_destroy_modify_header(action->ctx, action);
+ for (i = 0; i < action->modify_header.num_of_patterns; i++) {
+ mlx5dr_action_destroy_stcs(&action[i]);
+ if (action[i].modify_header.num_of_actions > 1) {
+ mlx5dr_pat_put_pattern(action[i].ctx,
+ action[i].modify_header.pat_obj);
+ /* Save shared arg object if was used to free */
+ if (action[i].modify_header.arg_obj)
+ obj = action[i].modify_header.arg_obj;
+ }
+ }
+ if (obj)
+ mlx5dr_cmd_destroy_obj(obj);
break;
case MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3:
- mlx5dr_action_destroy_stcs(action);
mlx5dr_action_put_shared_stc(action, MLX5DR_CONTEXT_SHARED_STC_DECAP);
+ for (i = 0; i < action->reformat.num_of_hdrs; i++)
+ mlx5dr_action_destroy_stcs(&action[i]);
mlx5dr_cmd_destroy_obj(action->reformat.arg_obj);
break;
case MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2:
- mlx5dr_action_destroy_stcs(action);
+ for (i = 0; i < action->reformat.num_of_hdrs; i++)
+ mlx5dr_action_destroy_stcs(&action[i]);
mlx5dr_cmd_destroy_obj(action->reformat.arg_obj);
break;
}
@@ -1903,6 +1981,12 @@ mlx5dr_action_prepare_decap_l3_data(uint8_t *src, uint8_t *dst,
memcpy(dst, e_src, 2);
}
+static int mlx5dr_action_get_shared_stc_offset(struct mlx5dr_context_common_res *common_res,
+ enum mlx5dr_context_shared_stc_type stc_type)
+{
+ return common_res->shared_stc[stc_type]->remove_header.offset;
+}
+
static struct mlx5dr_actions_wqe_setter *
mlx5dr_action_setter_find_first(struct mlx5dr_actions_wqe_setter *setter,
uint8_t req_flags)
@@ -1945,13 +2029,15 @@ mlx5dr_action_setter_modify_header(struct mlx5dr_actions_apply_data *apply,
struct mlx5dr_actions_wqe_setter *setter)
{
struct mlx5dr_rule_action *rule_action;
+ uint32_t stc_idx, arg_sz, arg_idx;
struct mlx5dr_action *action;
- uint32_t arg_sz, arg_idx;
uint8_t *single_action;
rule_action = &apply->rule_action[setter->idx_double];
- action = rule_action->action;
- mlx5dr_action_apply_stc(apply, MLX5DR_ACTION_STC_IDX_DW6, setter->idx_double);
+ action = rule_action->action + rule_action->modify_header.pattern_idx;
+
+ stc_idx = htobe32(action->stc[apply->tbl_type].offset);
+ apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW6] = stc_idx;
apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW7] = 0;
apply->wqe_data[MLX5DR_ACTION_OFFSET_DW6] = 0;
@@ -1972,7 +2058,7 @@ mlx5dr_action_setter_modify_header(struct mlx5dr_actions_apply_data *apply,
*(__be32 *)MLX5_ADDR_OF(set_action_in, single_action, data);
} else {
/* Argument offset multiple with number of args per these actions */
- arg_sz = mlx5dr_arg_get_arg_size(action->modify_header.num_of_actions);
+ arg_sz = mlx5dr_arg_get_arg_size(action->modify_header.max_num_of_actions);
arg_idx = rule_action->modify_header.offset * arg_sz;
apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = htobe32(arg_idx);
@@ -1992,26 +2078,29 @@ mlx5dr_action_setter_insert_ptr(struct mlx5dr_actions_apply_data *apply,
struct mlx5dr_actions_wqe_setter *setter)
{
struct mlx5dr_rule_action *rule_action;
- uint32_t arg_idx, arg_sz;
+ uint32_t stc_idx, arg_idx, arg_sz;
+ struct mlx5dr_action *action;
rule_action = &apply->rule_action[setter->idx_double];
+ action = rule_action->action + rule_action->reformat.hdr_idx;
/* Argument offset multiple on args required for header size */
- arg_sz = mlx5dr_arg_data_size_to_arg_size(rule_action->action->reformat.header_size);
+ arg_sz = mlx5dr_arg_data_size_to_arg_size(action->reformat.max_hdr_sz);
arg_idx = rule_action->reformat.offset * arg_sz;
apply->wqe_data[MLX5DR_ACTION_OFFSET_DW6] = 0;
apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = htobe32(arg_idx);
- mlx5dr_action_apply_stc(apply, MLX5DR_ACTION_STC_IDX_DW6, setter->idx_double);
+ stc_idx = htobe32(action->stc[apply->tbl_type].offset);
+ apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW6] = stc_idx;
apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW7] = 0;
- if (!(rule_action->action->flags & MLX5DR_ACTION_FLAG_SHARED)) {
+ if (!(action->flags & MLX5DR_ACTION_FLAG_SHARED)) {
apply->require_dep = 1;
mlx5dr_arg_write(apply->queue, NULL,
- rule_action->action->reformat.arg_obj->id + arg_idx,
+ action->reformat.arg_obj->id + arg_idx,
rule_action->reformat.data,
- rule_action->action->reformat.header_size);
+ action->reformat.header_size);
}
}
@@ -2020,20 +2109,21 @@ mlx5dr_action_setter_tnl_l3_to_l2(struct mlx5dr_actions_apply_data *apply,
struct mlx5dr_actions_wqe_setter *setter)
{
struct mlx5dr_rule_action *rule_action;
+ uint32_t stc_idx, arg_sz, arg_idx;
struct mlx5dr_action *action;
- uint32_t arg_sz, arg_idx;
rule_action = &apply->rule_action[setter->idx_double];
- action = rule_action->action;
+ action = rule_action->action + rule_action->reformat.hdr_idx;
/* Argument offset multiple on args required for num of actions */
- arg_sz = mlx5dr_arg_get_arg_size(action->modify_header.num_of_actions);
+ arg_sz = mlx5dr_arg_get_arg_size(action->modify_header.max_num_of_actions);
arg_idx = rule_action->reformat.offset * arg_sz;
apply->wqe_data[MLX5DR_ACTION_OFFSET_DW6] = 0;
apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = htobe32(arg_idx);
- mlx5dr_action_apply_stc(apply, MLX5DR_ACTION_STC_IDX_DW6, setter->idx_double);
+ stc_idx = htobe32(action->stc[apply->tbl_type].offset);
+ apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW6] = stc_idx;
apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW7] = 0;
if (!(action->flags & MLX5DR_ACTION_FLAG_SHARED)) {
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.h b/drivers/net/mlx5/hws/mlx5dr_action.h
index a85f3b0139..314e289780 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.h
+++ b/drivers/net/mlx5/hws/mlx5dr_action.h
@@ -120,15 +120,19 @@ struct mlx5dr_action {
struct mlx5dr_pool_chunk stc[MLX5DR_TABLE_TYPE_MAX];
union {
struct {
- struct mlx5dr_devx_obj *pattern_obj;
+ struct mlx5dr_devx_obj *pat_obj;
struct mlx5dr_devx_obj *arg_obj;
__be64 single_action;
+ uint8_t num_of_patterns;
uint8_t single_action_type;
- uint16_t num_of_actions;
+ uint8_t num_of_actions;
+ uint8_t max_num_of_actions;
} modify_header;
struct {
struct mlx5dr_devx_obj *arg_obj;
uint32_t header_size;
+ uint8_t num_of_hdrs;
+ uint16_t max_hdr_sz;
} reformat;
struct {
struct mlx5dr_devx_obj *devx_obj;
diff --git a/drivers/net/mlx5/hws/mlx5dr_pat_arg.c b/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
index 309a61d477..50da90626c 100644
--- a/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
+++ b/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
@@ -60,22 +60,16 @@ void mlx5dr_pat_uninit_pattern_cache(struct mlx5dr_pattern_cache *cache)
simple_free(cache);
}
-static bool mlx5dr_pat_compare_pattern(enum mlx5dr_action_type cur_type,
- int cur_num_of_actions,
+static bool mlx5dr_pat_compare_pattern(int cur_num_of_actions,
__be64 cur_actions[],
- enum mlx5dr_action_type type,
int num_of_actions,
__be64 actions[])
{
int i;
- if (cur_num_of_actions != num_of_actions || cur_type != type)
+ if (cur_num_of_actions != num_of_actions)
return false;
- /* All decap-l3 look the same, only change is the num of actions */
- if (type == MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2)
- return true;
-
for (i = 0; i < num_of_actions; i++) {
u8 action_id =
MLX5_GET(set_action_in, &actions[i], action_type);
@@ -96,17 +90,14 @@ static bool mlx5dr_pat_compare_pattern(enum mlx5dr_action_type cur_type,
static struct mlx5dr_pattern_cache_item *
mlx5dr_pat_find_cached_pattern(struct mlx5dr_pattern_cache *cache,
- struct mlx5dr_action *action,
uint16_t num_of_actions,
__be64 *actions)
{
struct mlx5dr_pattern_cache_item *cached_pat;
LIST_FOREACH(cached_pat, &cache->head, next) {
- if (mlx5dr_pat_compare_pattern(cached_pat->type,
- cached_pat->mh_data.num_of_actions,
+ if (mlx5dr_pat_compare_pattern(cached_pat->mh_data.num_of_actions,
(__be64 *)cached_pat->mh_data.data,
- action->type,
num_of_actions,
actions))
return cached_pat;
@@ -117,13 +108,12 @@ mlx5dr_pat_find_cached_pattern(struct mlx5dr_pattern_cache *cache,
static struct mlx5dr_pattern_cache_item *
mlx5dr_pat_get_existing_cached_pattern(struct mlx5dr_pattern_cache *cache,
- struct mlx5dr_action *action,
uint16_t num_of_actions,
__be64 *actions)
{
struct mlx5dr_pattern_cache_item *cached_pattern;
- cached_pattern = mlx5dr_pat_find_cached_pattern(cache, action, num_of_actions, actions);
+ cached_pattern = mlx5dr_pat_find_cached_pattern(cache, num_of_actions, actions);
if (cached_pattern) {
/* LRU: move it to be first in the list */
LIST_REMOVE(cached_pattern, next);
@@ -134,24 +124,9 @@ mlx5dr_pat_get_existing_cached_pattern(struct mlx5dr_pattern_cache *cache,
return cached_pattern;
}
-static struct mlx5dr_pattern_cache_item *
-mlx5dr_pat_get_cached_pattern_by_action(struct mlx5dr_pattern_cache *cache,
- struct mlx5dr_action *action)
-{
- struct mlx5dr_pattern_cache_item *cached_pattern;
-
- LIST_FOREACH(cached_pattern, &cache->head, next) {
- if (cached_pattern->mh_data.pattern_obj->id == action->modify_header.pattern_obj->id)
- return cached_pattern;
- }
-
- return NULL;
-}
-
static struct mlx5dr_pattern_cache_item *
mlx5dr_pat_add_pattern_to_cache(struct mlx5dr_pattern_cache *cache,
struct mlx5dr_devx_obj *pattern_obj,
- enum mlx5dr_action_type type,
uint16_t num_of_actions,
__be64 *actions)
{
@@ -164,7 +139,6 @@ mlx5dr_pat_add_pattern_to_cache(struct mlx5dr_pattern_cache *cache,
return NULL;
}
- cached_pattern->type = type;
cached_pattern->mh_data.num_of_actions = num_of_actions;
cached_pattern->mh_data.pattern_obj = pattern_obj;
cached_pattern->mh_data.data =
@@ -188,6 +162,20 @@ mlx5dr_pat_add_pattern_to_cache(struct mlx5dr_pattern_cache *cache,
return NULL;
}
+static struct mlx5dr_pattern_cache_item *
+mlx5dr_pat_find_cached_pattern_by_obj(struct mlx5dr_pattern_cache *cache,
+ struct mlx5dr_devx_obj *pat_obj)
+{
+ struct mlx5dr_pattern_cache_item *cached_pattern;
+
+ LIST_FOREACH(cached_pattern, &cache->head, next) {
+ if (cached_pattern->mh_data.pattern_obj->id == pat_obj->id)
+ return cached_pattern;
+ }
+
+ return NULL;
+}
+
static void
mlx5dr_pat_remove_pattern(struct mlx5dr_pattern_cache_item *cached_pattern)
{
@@ -196,14 +184,14 @@ mlx5dr_pat_remove_pattern(struct mlx5dr_pattern_cache_item *cached_pattern)
simple_free(cached_pattern);
}
-static void
-mlx5dr_pat_put_pattern(struct mlx5dr_pattern_cache *cache,
- struct mlx5dr_action *action)
+void mlx5dr_pat_put_pattern(struct mlx5dr_context *ctx,
+ struct mlx5dr_devx_obj *pat_obj)
{
+ struct mlx5dr_pattern_cache *cache = ctx->pattern_cache;
struct mlx5dr_pattern_cache_item *cached_pattern;
pthread_spin_lock(&cache->lock);
- cached_pattern = mlx5dr_pat_get_cached_pattern_by_action(cache, action);
+ cached_pattern = mlx5dr_pat_find_cached_pattern_by_obj(cache, pat_obj);
if (!cached_pattern) {
DR_LOG(ERR, "Failed to find pattern according to action with pt");
assert(false);
@@ -214,62 +202,56 @@ mlx5dr_pat_put_pattern(struct mlx5dr_pattern_cache *cache,
goto out;
mlx5dr_pat_remove_pattern(cached_pattern);
+ mlx5dr_cmd_destroy_obj(pat_obj);
out:
pthread_spin_unlock(&cache->lock);
}
-static int mlx5dr_pat_get_pattern(struct mlx5dr_context *ctx,
- struct mlx5dr_action *action,
- uint16_t num_of_actions,
- size_t pattern_sz,
- __be64 *pattern)
+struct mlx5dr_devx_obj *
+mlx5dr_pat_get_pattern(struct mlx5dr_context *ctx,
+ __be64 *pattern, size_t pattern_sz)
{
+ uint16_t num_of_actions = pattern_sz / MLX5DR_MODIFY_ACTION_SIZE;
struct mlx5dr_pattern_cache_item *cached_pattern;
- int ret = 0;
+ struct mlx5dr_devx_obj *pat_obj = NULL;
pthread_spin_lock(&ctx->pattern_cache->lock);
cached_pattern = mlx5dr_pat_get_existing_cached_pattern(ctx->pattern_cache,
- action,
num_of_actions,
pattern);
if (cached_pattern) {
- action->modify_header.pattern_obj = cached_pattern->mh_data.pattern_obj;
+ pat_obj = cached_pattern->mh_data.pattern_obj;
goto out_unlock;
}
- action->modify_header.pattern_obj =
- mlx5dr_cmd_header_modify_pattern_create(ctx->ibv_ctx,
- pattern_sz,
- (uint8_t *)pattern);
- if (!action->modify_header.pattern_obj) {
+ pat_obj = mlx5dr_cmd_header_modify_pattern_create(ctx->ibv_ctx,
+ pattern_sz,
+ (uint8_t *)pattern);
+ if (!pat_obj) {
DR_LOG(ERR, "Failed to create pattern FW object");
-
- ret = rte_errno;
goto out_unlock;
}
- cached_pattern =
- mlx5dr_pat_add_pattern_to_cache(ctx->pattern_cache,
- action->modify_header.pattern_obj,
- action->type,
- num_of_actions,
- pattern);
+ cached_pattern = mlx5dr_pat_add_pattern_to_cache(ctx->pattern_cache,
+ pat_obj,
+ num_of_actions,
+ pattern);
if (!cached_pattern) {
DR_LOG(ERR, "Failed to add pattern to cache");
- ret = rte_errno;
goto clean_pattern;
}
-out_unlock:
pthread_spin_unlock(&ctx->pattern_cache->lock);
- return ret;
+ return pat_obj;
clean_pattern:
- mlx5dr_cmd_destroy_obj(action->modify_header.pattern_obj);
+ mlx5dr_cmd_destroy_obj(pat_obj);
+ pat_obj = NULL;
+out_unlock:
pthread_spin_unlock(&ctx->pattern_cache->lock);
- return ret;
+ return pat_obj;
}
static void
@@ -388,64 +370,80 @@ bool mlx5dr_arg_is_valid_arg_request_size(struct mlx5dr_context *ctx,
return true;
}
-static int
-mlx5dr_arg_create_modify_header_arg(struct mlx5dr_context *ctx,
- struct mlx5dr_action *action,
- uint16_t num_of_actions,
- __be64 *pattern,
- uint32_t bulk_size)
+struct mlx5dr_devx_obj *
+mlx5dr_arg_create(struct mlx5dr_context *ctx,
+ uint8_t *data,
+ size_t data_sz,
+ uint32_t log_bulk_sz,
+ bool write_data)
{
- uint32_t flags = action->flags;
- uint16_t args_log_size;
- int ret = 0;
+ struct mlx5dr_devx_obj *arg_obj;
+ uint16_t single_arg_log_sz;
+ uint16_t multi_arg_log_sz;
+ int ret;
- /* Alloc bulk of args */
- args_log_size = mlx5dr_arg_get_arg_log_size(num_of_actions);
- if (args_log_size >= MLX5DR_ARG_CHUNK_SIZE_MAX) {
- DR_LOG(ERR, "Exceed number of allowed actions %u",
- num_of_actions);
- rte_errno = EINVAL;
- return rte_errno;
+ single_arg_log_sz = mlx5dr_arg_data_size_to_arg_log_size(data_sz);
+ multi_arg_log_sz = single_arg_log_sz + log_bulk_sz;
+
+ if (single_arg_log_sz >= MLX5DR_ARG_CHUNK_SIZE_MAX) {
+ DR_LOG(ERR, "Requested single arg %u not supported", single_arg_log_sz);
+ rte_errno = ENOTSUP;
+ return NULL;
}
- if (!mlx5dr_arg_is_valid_arg_request_size(ctx, args_log_size + bulk_size)) {
- DR_LOG(ERR, "Arg size %d does not fit FW capability",
- args_log_size + bulk_size);
- rte_errno = EINVAL;
- return rte_errno;
+ if (!mlx5dr_arg_is_valid_arg_request_size(ctx, multi_arg_log_sz)) {
+ DR_LOG(ERR, "Argument log size %d not supported by FW", multi_arg_log_sz);
+ rte_errno = ENOTSUP;
+ return NULL;
}
- action->modify_header.arg_obj =
- mlx5dr_cmd_arg_create(ctx->ibv_ctx, args_log_size + bulk_size,
- ctx->pd_num);
- if (!action->modify_header.arg_obj) {
- DR_LOG(ERR, "Failed allocating arg in order: %d",
- args_log_size + bulk_size);
- return rte_errno;
+ /* Alloc bulk of args */
+ arg_obj = mlx5dr_cmd_arg_create(ctx->ibv_ctx, multi_arg_log_sz, ctx->pd_num);
+ if (!arg_obj) {
+ DR_LOG(ERR, "Failed allocating arg in order: %d", multi_arg_log_sz);
+ return NULL;
}
- /* When INLINE need to write the arg data */
- if (flags & MLX5DR_ACTION_FLAG_SHARED)
+ if (write_data) {
ret = mlx5dr_arg_write_inline_arg_data(ctx,
- action->modify_header.arg_obj->id,
- (uint8_t *)pattern,
- num_of_actions *
- MLX5DR_MODIFY_ACTION_SIZE);
- if (ret) {
- DR_LOG(ERR, "Failed writing INLINE arg in order: %d",
- args_log_size + bulk_size);
- mlx5dr_cmd_destroy_obj(action->modify_header.arg_obj);
- return rte_errno;
+ arg_obj->id,
+ data, data_sz);
+ if (ret) {
+ DR_LOG(ERR, "Failed writing arg data");
+ mlx5dr_cmd_destroy_obj(arg_obj);
+ return NULL;
+ }
}
- return 0;
+ return arg_obj;
}
-bool mlx5dr_pat_arg_verify_actions(__be64 pattern[], uint16_t num_of_actions)
+struct mlx5dr_devx_obj *
+mlx5dr_arg_create_modify_header_arg(struct mlx5dr_context *ctx,
+ __be64 *data,
+ uint8_t num_of_actions,
+ uint32_t log_bulk_sz,
+ bool write_data)
{
- int i;
+ size_t data_sz = num_of_actions * MLX5DR_MODIFY_ACTION_SIZE;
+ struct mlx5dr_devx_obj *arg_obj;
+
+ arg_obj = mlx5dr_arg_create(ctx,
+ (uint8_t *)data,
+ data_sz,
+ log_bulk_sz,
+ write_data);
+ if (!arg_obj)
+ DR_LOG(ERR, "Failed creating modify header arg");
+
+ return arg_obj;
+}
- for (i = 0; i < num_of_actions; i++) {
+bool mlx5dr_pat_verify_actions(__be64 pattern[], size_t sz)
+{
+ size_t i;
+
+ for (i = 0; i < sz / MLX5DR_MODIFY_ACTION_SIZE; i++) {
u8 action_id =
MLX5_GET(set_action_in, &pattern[i], action_type);
if (action_id >= MLX5_MODIFICATION_TYPE_MAX) {
@@ -456,51 +454,3 @@ bool mlx5dr_pat_arg_verify_actions(__be64 pattern[], uint16_t num_of_actions)
return true;
}
-
-int mlx5dr_pat_arg_create_modify_header(struct mlx5dr_context *ctx,
- struct mlx5dr_action *action,
- size_t pattern_sz,
- __be64 pattern[],
- uint32_t bulk_size)
-{
- uint16_t num_of_actions;
- int ret;
-
- num_of_actions = pattern_sz / MLX5DR_MODIFY_ACTION_SIZE;
- if (num_of_actions == 0) {
- DR_LOG(ERR, "Invalid number of actions %u", num_of_actions);
- rte_errno = EINVAL;
- return rte_errno;
- }
-
- action->modify_header.num_of_actions = num_of_actions;
-
- ret = mlx5dr_arg_create_modify_header_arg(ctx, action,
- num_of_actions,
- pattern,
- bulk_size);
- if (ret) {
- DR_LOG(ERR, "Failed to allocate arg");
- return ret;
- }
-
- ret = mlx5dr_pat_get_pattern(ctx, action, num_of_actions, pattern_sz,
- pattern);
- if (ret) {
- DR_LOG(ERR, "Failed to allocate pattern");
- goto free_arg;
- }
-
- return 0;
-
-free_arg:
- mlx5dr_cmd_destroy_obj(action->modify_header.arg_obj);
- return rte_errno;
-}
-
-void mlx5dr_pat_arg_destroy_modify_header(struct mlx5dr_context *ctx,
- struct mlx5dr_action *action)
-{
- mlx5dr_cmd_destroy_obj(action->modify_header.arg_obj);
- mlx5dr_pat_put_pattern(ctx->pattern_cache, action);
-}
diff --git a/drivers/net/mlx5/hws/mlx5dr_pat_arg.h b/drivers/net/mlx5/hws/mlx5dr_pat_arg.h
index ec467dbb4b..2a38891c4d 100644
--- a/drivers/net/mlx5/hws/mlx5dr_pat_arg.h
+++ b/drivers/net/mlx5/hws/mlx5dr_pat_arg.h
@@ -28,7 +28,6 @@ struct mlx5dr_pattern_cache {
};
struct mlx5dr_pattern_cache_item {
- enum mlx5dr_action_type type;
struct {
struct mlx5dr_devx_obj *pattern_obj;
struct dr_icm_chunk *chunk;
@@ -53,16 +52,29 @@ int mlx5dr_pat_init_pattern_cache(struct mlx5dr_pattern_cache **cache);
void mlx5dr_pat_uninit_pattern_cache(struct mlx5dr_pattern_cache *cache);
-bool mlx5dr_pat_arg_verify_actions(__be64 pattern[], uint16_t num_of_actions);
-
-int mlx5dr_pat_arg_create_modify_header(struct mlx5dr_context *ctx,
- struct mlx5dr_action *action,
- size_t pattern_sz,
- __be64 pattern[],
- uint32_t bulk_size);
-
-void mlx5dr_pat_arg_destroy_modify_header(struct mlx5dr_context *ctx,
- struct mlx5dr_action *action);
+bool mlx5dr_pat_verify_actions(__be64 pattern[], size_t sz);
+
+struct mlx5dr_devx_obj *
+mlx5dr_arg_create(struct mlx5dr_context *ctx,
+ uint8_t *data,
+ size_t data_sz,
+ uint32_t log_bulk_sz,
+ bool write_data);
+
+struct mlx5dr_devx_obj *
+mlx5dr_arg_create_modify_header_arg(struct mlx5dr_context *ctx,
+ __be64 *data,
+ uint8_t num_of_actions,
+ uint32_t log_bulk_sz,
+ bool write_data);
+
+struct mlx5dr_devx_obj *
+mlx5dr_pat_get_pattern(struct mlx5dr_context *ctx,
+ __be64 *pattern,
+ size_t pattern_sz);
+
+void mlx5dr_pat_put_pattern(struct mlx5dr_context *ctx,
+ struct mlx5dr_devx_obj *pat_obj);
bool mlx5dr_arg_is_valid_arg_request_size(struct mlx5dr_context *ctx,
uint32_t arg_size);
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 8e146d99e2..271e4aae10 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -1770,6 +1770,7 @@ __flow_hw_actions_translate(struct rte_eth_dev *dev,
}
}
if (mhdr.pos != UINT16_MAX) {
+ struct mlx5dr_action_mh_pattern pattern;
uint32_t flags;
uint32_t bulk_size;
size_t mhdr_len;
@@ -1791,14 +1792,17 @@ __flow_hw_actions_translate(struct rte_eth_dev *dev,
} else {
bulk_size = rte_log2_u32(table_attr->nb_flows);
}
+ pattern.data = (__be64 *)acts->mhdr->mhdr_cmds;
+ pattern.sz = mhdr_len;
acts->mhdr->action = mlx5dr_action_create_modify_header
- (priv->dr_ctx, mhdr_len, (__be64 *)acts->mhdr->mhdr_cmds,
+ (priv->dr_ctx, 1, &pattern,
bulk_size, flags);
if (!acts->mhdr->action)
goto err;
acts->rule_acts[acts->mhdr->pos].action = acts->mhdr->action;
}
if (reformat_used) {
+ struct mlx5dr_action_reformat_header hdr;
uint8_t buf[MLX5_ENCAP_MAX_LEN];
bool shared_rfmt = true;
@@ -1822,9 +1826,12 @@ __flow_hw_actions_translate(struct rte_eth_dev *dev,
acts->encap_decap->data_size = data_size;
memcpy(acts->encap_decap->data, encap_data, data_size);
}
+
+ hdr.sz = data_size;
+ hdr.data = encap_data;
acts->encap_decap->action = mlx5dr_action_create_reformat
(priv->dr_ctx, refmt_type,
- data_size, encap_data,
+ 1, &hdr,
shared_rfmt ? 0 : rte_log2_u32(table_attr->nb_flows),
mlx5_hw_act_flag[!!attr->group][type] |
(shared_rfmt ? MLX5DR_ACTION_FLAG_SHARED : 0));
--
2.18.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* RE: [PATCH] net/mlx5/hws: add support for multi pattern
2023-07-09 14:20 [PATCH] net/mlx5/hws: add support for multi pattern Alex Vesker
@ 2023-08-30 12:26 ` Raslan Darawsheh
0 siblings, 0 replies; 2+ messages in thread
From: Raslan Darawsheh @ 2023-08-30 12:26 UTC (permalink / raw)
To: Alex Vesker, Alex Vesker, Slava Ovsiienko,
NBU-Contact-Thomas Monjalon (EXTERNAL),
Suanming Mou, Matan Azrad, Ori Kam
Cc: dev
Hi,
> -----Original Message-----
> From: Alex Vesker <valex@nvidia.com>
> Sent: Sunday, July 9, 2023 5:20 PM
> To: Alex Vesker <valex@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; NBU-Contact-Thomas Monjalon (EXTERNAL)
> <thomas@monjalon.net>; Suanming Mou <suanmingm@nvidia.com>; Matan
> Azrad <matan@nvidia.com>; Ori Kam <orika@nvidia.com>
> Cc: dev@dpdk.org
> Subject: [PATCH] net/mlx5/hws: add support for multi pattern
>
> When creating an action it can contain a bulk of objects, but the objects are
> fixed to a specific pattern and cannot be reused. This can lead to inefficient
> usage of the HW resources, This support allows creating multiple patterns over
> a single mlx5dr action.
>
> Signed-off-by: Alex Vesker <valex@nvidia.com>
> Reviewed-by: Erez Shitrit <erezsh@nvidia.com>
> Acked-by: Matan Azrad <matan@nvidia.com>
> ---
....
>
> @@ -503,10 +518,10 @@ mlx5dr_action_create_reformat(struct
> mlx5dr_context *ctx,
> *
> * @param[in] ctx
> * The context in which the new action will be created.
> - * @param[in] pattern_sz
> - * Byte size of the pattern array.
> - * @param[in] pattern
> - * PRM format modify pattern action array.
> + * @param[in] num_of_patterns
> + * Number of provided patterns in "patterns" array.
Fixed an issue with the wrong indentation usage of space
> + * @param[in] patterns
> + * Patterns array containing pattern information.
> * @param[in] log_bulk_size
> * Number of unique values used with this pattern.
> * @param[in] flags
> @@ -515,8 +530,8 @@ mlx5dr_action_create_reformat(struct
....
> +static int
> +mlx5dr_action_create_modify_header_hws(struct mlx5dr_action *action,
> + uint8_t num_of_patterns,
> + struct mlx5dr_action_mh_pattern
> *pattern,
> + uint32_t log_bulk_size)
> +{
> + struct mlx5dr_devx_obj *pat_obj, *arg_obj = NULL;
> + struct mlx5dr_context *ctx = action->ctx;
> + uint16_t max_mh_actions = 0;
> + int i, ret;
> +
> + /* Caclulate maximum number of mh actions for shared arg allocation
Fixed a typo Caclulate =-> Calculate.
....
Patch applied to next-net-mlx,
Kindest regards,
Raslan Darawsheh
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-08-30 12:26 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-09 14:20 [PATCH] net/mlx5/hws: add support for multi pattern Alex Vesker
2023-08-30 12:26 ` Raslan Darawsheh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).