Added support for RTC with insertion by hash/index and distribution by normal/linear hash.
Supported modes are: - INSERT_BY_HASH + DISTRIBUTE_BY_HASH: what we had until now - INSERT_BY_INDEX + DISTRIBUTE_BY_HASH: Hash Split table, can also be used to calculate hash, in which case the result can be read from the hash_result meta-field (MLX5_MODI_HASH_RESULT) - INSERT_BY_INDEX + DISTRIBUTE_BY_LINEAR: Linear Lookup table, supported only for metadata_reg_c3[31:16] bits When setting INSERT_BY_INDEX mode, you can still provide number of rules both through 'rule' and 'table' fields of matcher attributes, but if 'table' is used, then 'table.sz_col_log' has to be 0. When providing rule with index, this index is used both in rule creation and deletion. Signed-off-by: Yevgeny Kliteynik <klit...@nvidia.com> --- drivers/net/mlx5/hws/mlx5dr.h | 17 ++- drivers/net/mlx5/hws/mlx5dr_debug.c | 6 +- drivers/net/mlx5/hws/mlx5dr_matcher.c | 211 +++++++++++++++++++++----- drivers/net/mlx5/hws/mlx5dr_matcher.h | 6 + drivers/net/mlx5/hws/mlx5dr_rule.c | 23 ++- drivers/net/mlx5/hws/mlx5dr_rule.h | 2 +- 6 files changed, 217 insertions(+), 48 deletions(-) diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h index c0f9a5e984..b3b2bf34f2 100644 --- a/drivers/net/mlx5/hws/mlx5dr.h +++ b/drivers/net/mlx5/hws/mlx5dr.h @@ -111,6 +111,16 @@ enum mlx5dr_matcher_flow_src { MLX5DR_MATCHER_FLOW_SRC_VPORT = 0x2, }; +enum mlx5dr_matcher_insert_mode { + MLX5DR_MATCHER_INSERT_BY_HASH = 0x0, + MLX5DR_MATCHER_INSERT_BY_INDEX = 0x1, +}; + +enum mlx5dr_matcher_distribute_mode { + MLX5DR_MATCHER_DISTRIBUTE_BY_HASH = 0x0, + MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR = 0x1, +}; + struct mlx5dr_matcher_attr { /* Processing priority inside table */ uint32_t priority; @@ -120,6 +130,9 @@ struct mlx5dr_matcher_attr { enum mlx5dr_matcher_resource_mode mode; /* Optimize insertion in case packet origin is the same for all rules */ enum mlx5dr_matcher_flow_src optimize_flow_src; + /* Define the insertion and distribution modes for this matcher */ + enum mlx5dr_matcher_insert_mode insert_mode; + enum mlx5dr_matcher_distribute_mode distribute_mode; union { struct { uint8_t sz_row_log; @@ -135,7 +148,9 @@ struct mlx5dr_matcher_attr { struct mlx5dr_rule_attr { uint16_t queue_id; void *user_data; - /* Valid if matcher optimize_using_rule_idx is set */ + /* Valid if matcher optimize_using_rule_idx is set or + * if matcher is configured to insert rules by index. + */ uint32_t rule_idx; uint32_t burst:1; }; diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 239dfcae46..0815327b18 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -158,7 +158,7 @@ mlx5dr_debug_dump_matcher_attr(FILE *f, struct mlx5dr_matcher *matcher) struct mlx5dr_matcher_attr *attr = &matcher->attr; int ret; - ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d\n", + ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d\n", MLX5DR_DEBUG_RES_TYPE_MATCHER_ATTR, (uint64_t)(uintptr_t)matcher, attr->priority, @@ -166,7 +166,9 @@ mlx5dr_debug_dump_matcher_attr(FILE *f, struct mlx5dr_matcher *matcher) attr->table.sz_row_log, attr->table.sz_col_log, attr->optimize_using_rule_idx, - attr->optimize_flow_src); + attr->optimize_flow_src, + attr->insert_mode, + attr->distribute_mode); if (ret < 0) { rte_errno = EINVAL; return rte_errno; diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c index 46217b2ab3..60865bf562 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.c +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c @@ -4,6 +4,25 @@ #include "mlx5dr_internal.h" +enum mlx5dr_matcher_rtc_type { + DR_MATCHER_RTC_TYPE_MATCH, + DR_MATCHER_RTC_TYPE_STE_ARRAY, + DR_MATCHER_RTC_TYPE_MAX, +}; + +static const char * const mlx5dr_matcher_rtc_type_str[] = { + [DR_MATCHER_RTC_TYPE_MATCH] = "MATCH", + [DR_MATCHER_RTC_TYPE_STE_ARRAY] = "STE_ARRAY", + [DR_MATCHER_RTC_TYPE_MAX] = "UNKNOWN", +}; + +static const char *mlx5dr_matcher_rtc_type_to_str(enum mlx5dr_matcher_rtc_type rtc_type) +{ + if (rtc_type > DR_MATCHER_RTC_TYPE_MAX) + rtc_type = DR_MATCHER_RTC_TYPE_MAX; + return mlx5dr_matcher_rtc_type_str[rtc_type]; +} + static bool mlx5dr_matcher_requires_col_tbl(uint8_t log_num_of_rules) { /* Collision table concatenation is done only for large rule tables */ @@ -320,10 +339,11 @@ static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher) static void mlx5dr_matcher_set_rtc_attr_sz(struct mlx5dr_matcher *matcher, struct mlx5dr_cmd_rtc_create_attr *rtc_attr, - bool is_match_rtc, + enum mlx5dr_matcher_rtc_type rtc_type, bool is_mirror) { enum mlx5dr_matcher_flow_src flow_src = matcher->attr.optimize_flow_src; + bool is_match_rtc = rtc_type == DR_MATCHER_RTC_TYPE_MATCH; struct mlx5dr_pool_chunk *ste = &matcher->action_ste.ste; if ((flow_src == MLX5DR_MATCHER_FLOW_SRC_VPORT && !is_mirror) || @@ -382,9 +402,9 @@ int mlx5dr_matcher_create_aliased_obj(struct mlx5dr_context *ctx, } static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, - bool is_match_rtc) + enum mlx5dr_matcher_rtc_type rtc_type) { - const char *rtc_type_str = is_match_rtc ? "match" : "action"; + struct mlx5dr_matcher_attr *attr = &matcher->attr; struct mlx5dr_cmd_rtc_create_attr rtc_attr = {0}; struct mlx5dr_context *ctx = matcher->tbl->ctx; struct mlx5dr_action_default_stc *default_stc; @@ -395,33 +415,57 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, struct mlx5dr_pool_chunk *ste; int ret; - if (is_match_rtc) { + switch (rtc_type) { + case DR_MATCHER_RTC_TYPE_MATCH: rtc_0 = &matcher->match_ste.rtc_0; rtc_1 = &matcher->match_ste.rtc_1; ste_pool = matcher->match_ste.pool; ste = &matcher->match_ste.ste; - ste->order = matcher->attr.table.sz_col_log + - matcher->attr.table.sz_row_log; - rtc_attr.log_size = matcher->attr.table.sz_row_log; - rtc_attr.log_depth = matcher->attr.table.sz_col_log; - rtc_attr.update_index_mode = MLX5_IFC_RTC_STE_UPDATE_MODE_BY_HASH; - /* The first match template is used since all share the same definer */ - rtc_attr.definer_id = mlx5dr_definer_get_id(matcher->mt[0]->definer); - rtc_attr.is_jumbo = mlx5dr_definer_is_jumbo(matcher->mt[0]->definer); + ste->order = attr->table.sz_col_log + attr->table.sz_row_log; + rtc_attr.log_size = attr->table.sz_row_log; + rtc_attr.log_depth = attr->table.sz_col_log; rtc_attr.miss_ft_id = matcher->end_ft->id; + + if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) { + /* The usual Hash Table */ + rtc_attr.update_index_mode = MLX5_IFC_RTC_STE_UPDATE_MODE_BY_HASH; + /* The first match template is used since all share the same definer */ + rtc_attr.definer_id = mlx5dr_definer_get_id(matcher->mt[0]->definer); + rtc_attr.is_jumbo = mlx5dr_definer_is_jumbo(matcher->mt[0]->definer); + } else if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX) { + rtc_attr.update_index_mode = MLX5_IFC_RTC_STE_UPDATE_MODE_BY_OFFSET; + rtc_attr.num_hash_definer = 1; + + if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + /* Hash Split Table */ + rtc_attr.access_index_mode = MLX5_IFC_RTC_STE_ACCESS_MODE_BY_HASH; + rtc_attr.definer_id = + mlx5dr_definer_get_id(matcher->mt[0]->definer); + rtc_attr.is_jumbo = + mlx5dr_definer_is_jumbo(matcher->mt[0]->definer); + } else if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR) { + /* Linear Lookup Table */ + rtc_attr.access_index_mode = MLX5_IFC_RTC_STE_ACCESS_MODE_LINEAR; + rtc_attr.definer_id = ctx->caps->linear_match_definer; + } + } + /* Match pool requires implicit allocation */ ret = mlx5dr_pool_chunk_alloc(ste_pool, ste); if (ret) { - DR_LOG(ERR, "Failed to allocate STE for %s RTC", rtc_type_str); + DR_LOG(ERR, "Failed to allocate STE for %s RTC", + mlx5dr_matcher_rtc_type_to_str(rtc_type)); return ret; } - } else { + break; + + case DR_MATCHER_RTC_TYPE_STE_ARRAY: rtc_0 = &matcher->action_ste.rtc_0; rtc_1 = &matcher->action_ste.rtc_1; ste_pool = matcher->action_ste.pool; ste = &matcher->action_ste.ste; ste->order = rte_log2_u32(matcher->action_ste.max_stes) + - matcher->attr.table.sz_row_log; + attr->table.sz_row_log; rtc_attr.log_size = ste->order; rtc_attr.log_depth = 0; rtc_attr.update_index_mode = MLX5_IFC_RTC_STE_UPDATE_MODE_BY_OFFSET; @@ -429,6 +473,12 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.definer_id = ctx->caps->trivial_match_definer; rtc_attr.is_jumbo = false; rtc_attr.miss_ft_id = 0; + break; + + default: + DR_LOG(ERR, "HWS Invalid RTC type"); + rte_errno = EINVAL; + return rte_errno; } devx_obj = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste); @@ -437,7 +487,7 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.ste_base = devx_obj->id; rtc_attr.ste_offset = ste->offset; rtc_attr.table_type = mlx5dr_table_get_res_fw_ft_type(tbl->type, false); - mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, is_match_rtc, false); + mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, rtc_type, false); /* STC is a single resource (devx_obj), use any STC for the ID */ stc_pool = ctx->stc_pool[tbl->type]; @@ -447,7 +497,8 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, *rtc_0 = mlx5dr_cmd_rtc_create(ctx->ibv_ctx, &rtc_attr); if (!*rtc_0) { - DR_LOG(ERR, "Failed to create matcher %s RTC", rtc_type_str); + DR_LOG(ERR, "Failed to create matcher RTC of type %s", + mlx5dr_matcher_rtc_type_to_str(rtc_type)); goto free_ste; } @@ -458,11 +509,12 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, devx_obj = mlx5dr_pool_chunk_get_base_devx_obj_mirror(stc_pool, &default_stc->default_hit); rtc_attr.stc_base = devx_obj->id; - mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, is_match_rtc, true); + mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, rtc_type, true); *rtc_1 = mlx5dr_cmd_rtc_create(ctx->ibv_ctx, &rtc_attr); if (!*rtc_1) { - DR_LOG(ERR, "Failed to create peer matcher %s RTC0", rtc_type_str); + DR_LOG(ERR, "Failed to create peer matcher RTC of type %s", + mlx5dr_matcher_rtc_type_to_str(rtc_type)); goto destroy_rtc_0; } } @@ -472,36 +524,41 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, destroy_rtc_0: mlx5dr_cmd_destroy_obj(*rtc_0); free_ste: - if (is_match_rtc) + if (rtc_type == DR_MATCHER_RTC_TYPE_MATCH) mlx5dr_pool_chunk_free(ste_pool, ste); return rte_errno; } static void mlx5dr_matcher_destroy_rtc(struct mlx5dr_matcher *matcher, - bool is_match_rtc) + enum mlx5dr_matcher_rtc_type rtc_type) { struct mlx5dr_table *tbl = matcher->tbl; struct mlx5dr_devx_obj *rtc_0, *rtc_1; struct mlx5dr_pool_chunk *ste; struct mlx5dr_pool *ste_pool; - if (is_match_rtc) { + switch (rtc_type) { + case DR_MATCHER_RTC_TYPE_MATCH: rtc_0 = matcher->match_ste.rtc_0; rtc_1 = matcher->match_ste.rtc_1; ste_pool = matcher->match_ste.pool; ste = &matcher->match_ste.ste; - } else { + break; + case DR_MATCHER_RTC_TYPE_STE_ARRAY: rtc_0 = matcher->action_ste.rtc_0; rtc_1 = matcher->action_ste.rtc_1; ste_pool = matcher->action_ste.pool; ste = &matcher->action_ste.ste; + break; + default: + return; } if (tbl->type == MLX5DR_TABLE_TYPE_FDB) mlx5dr_cmd_destroy_obj(rtc_1); mlx5dr_cmd_destroy_obj(rtc_0); - if (is_match_rtc) + if (rtc_type == DR_MATCHER_RTC_TYPE_MATCH) mlx5dr_pool_chunk_free(ste_pool, ste); } @@ -572,7 +629,7 @@ static int mlx5dr_matcher_bind_at(struct mlx5dr_matcher *matcher) } /* Allocate action RTC */ - ret = mlx5dr_matcher_create_rtc(matcher, false); + ret = mlx5dr_matcher_create_rtc(matcher, DR_MATCHER_RTC_TYPE_STE_ARRAY); if (ret) { DR_LOG(ERR, "Failed to create action RTC"); goto free_ste_pool; @@ -595,7 +652,7 @@ static int mlx5dr_matcher_bind_at(struct mlx5dr_matcher *matcher) return 0; free_rtc: - mlx5dr_matcher_destroy_rtc(matcher, false); + mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_STE_ARRAY); free_ste_pool: mlx5dr_pool_destroy(matcher->action_ste.pool); return rte_errno; @@ -609,7 +666,7 @@ static void mlx5dr_matcher_unbind_at(struct mlx5dr_matcher *matcher) return; mlx5dr_action_free_single_stc(tbl->ctx, tbl->type, &matcher->action_ste.stc); - mlx5dr_matcher_destroy_rtc(matcher, false); + mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_STE_ARRAY); mlx5dr_pool_destroy(matcher->action_ste.pool); } @@ -674,6 +731,84 @@ static void mlx5dr_matcher_unbind_mt(struct mlx5dr_matcher *matcher) mlx5dr_pool_destroy(matcher->match_ste.pool); } +static int +mlx5dr_matcher_validate_insert_mode(struct mlx5dr_cmd_query_caps *caps, + struct mlx5dr_matcher *matcher, + bool is_root) +{ + struct mlx5dr_matcher_attr *attr = &matcher->attr; + + if (is_root) { + if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_RULE) { + DR_LOG(ERR, "Root matcher supports only rule resource mode"); + goto not_supported; + } + if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH) { + DR_LOG(ERR, "Root matcher supports only insert by hash mode"); + goto not_supported; + } + if (attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + DR_LOG(ERR, "Root matcher supports only distribute by hash mode"); + goto not_supported; + } + if (attr->optimize_flow_src) { + DR_LOG(ERR, "Root matcher can't specify FDB direction"); + goto not_supported; + } + } + + switch (attr->insert_mode) { + case MLX5DR_MATCHER_INSERT_BY_HASH: + if (matcher->attr.distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + DR_LOG(ERR, "Invalid matcher distribute mode"); + goto not_supported; + } + break; + + case MLX5DR_MATCHER_INSERT_BY_INDEX: + if (attr->table.sz_col_log) { + DR_LOG(ERR, "Matcher with INSERT_BY_INDEX supports only Nx1 table size"); + goto not_supported; + } + + if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + /* Hash Split Table */ + if (!caps->rtc_hash_split_table) { + DR_LOG(ERR, "FW doesn't support insert by index and hash distribute"); + goto not_supported; + } + } else if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR) { + /* Linear Lookup Table */ + if (!caps->rtc_linear_lookup_table || + !IS_BIT_SET(caps->access_index_mode, + MLX5_IFC_RTC_STE_ACCESS_MODE_LINEAR)) { + DR_LOG(ERR, "FW doesn't support insert by index and linear distribute"); + goto not_supported; + } + + if (attr->table.sz_row_log > MLX5_IFC_RTC_LINEAR_LOOKUP_TBL_LOG_MAX) { + DR_LOG(ERR, "Matcher with linear distribute: rows exceed limit %d", + MLX5_IFC_RTC_LINEAR_LOOKUP_TBL_LOG_MAX); + goto not_supported; + } + } else { + DR_LOG(ERR, "Matcher has unsupported distribute mode"); + goto not_supported; + } + break; + + default: + DR_LOG(ERR, "Matcher has unsupported insert mode"); + goto not_supported; + } + + return 0; + +not_supported: + rte_errno = EOPNOTSUPP; + return rte_errno; +} + static int mlx5dr_matcher_process_attr(struct mlx5dr_cmd_query_caps *caps, struct mlx5dr_matcher *matcher, @@ -681,16 +816,10 @@ mlx5dr_matcher_process_attr(struct mlx5dr_cmd_query_caps *caps, { struct mlx5dr_matcher_attr *attr = &matcher->attr; - if (matcher->tbl->type != MLX5DR_TABLE_TYPE_FDB && attr->optimize_flow_src) { - DR_LOG(ERR, "NIC domain doesn't support flow_src"); + if (mlx5dr_matcher_validate_insert_mode(caps, matcher, is_root)) goto not_supported; - } if (is_root) { - if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_RULE) { - DR_LOG(ERR, "Root matcher supports only rule resource mode"); - goto not_supported; - } if (attr->optimize_flow_src) { DR_LOG(ERR, "Root matcher can't specify FDB direction"); goto not_supported; @@ -698,8 +827,14 @@ mlx5dr_matcher_process_attr(struct mlx5dr_cmd_query_caps *caps, return 0; } + if (matcher->tbl->type != MLX5DR_TABLE_TYPE_FDB && attr->optimize_flow_src) { + DR_LOG(ERR, "NIC domain doesn't support flow_src"); + goto not_supported; + } + /* Convert number of rules to the required depth */ - if (attr->mode == MLX5DR_MATCHER_RESOURCE_MODE_RULE) + if (attr->mode == MLX5DR_MATCHER_RESOURCE_MODE_RULE && + attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) attr->table.sz_col_log = mlx5dr_matcher_rules_to_tbl_depth(attr->rule.num_log); if (attr->table.sz_col_log > caps->rtc_log_depth_max) { @@ -744,7 +879,7 @@ static int mlx5dr_matcher_create_and_connect(struct mlx5dr_matcher *matcher) goto unbind_at; /* Allocate the RTC for the new matcher */ - ret = mlx5dr_matcher_create_rtc(matcher, true); + ret = mlx5dr_matcher_create_rtc(matcher, DR_MATCHER_RTC_TYPE_MATCH); if (ret) goto destroy_end_ft; @@ -763,7 +898,7 @@ static int mlx5dr_matcher_create_and_connect(struct mlx5dr_matcher *matcher) destroy_shared: mlx5dr_matcher_create_uninit_shared(matcher); destroy_rtc: - mlx5dr_matcher_destroy_rtc(matcher, true); + mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_MATCH); destroy_end_ft: mlx5dr_matcher_destroy_end_ft(matcher); unbind_at: @@ -777,7 +912,7 @@ static void mlx5dr_matcher_destroy_and_disconnect(struct mlx5dr_matcher *matcher { mlx5dr_matcher_disconnect(matcher); mlx5dr_matcher_create_uninit_shared(matcher); - mlx5dr_matcher_destroy_rtc(matcher, true); + mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_MATCH); mlx5dr_matcher_destroy_end_ft(matcher); mlx5dr_matcher_unbind_at(matcher); mlx5dr_matcher_unbind_mt(matcher); diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h index 62004078cf..2bebc4bcce 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.h +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h @@ -82,4 +82,10 @@ int mlx5dr_matcher_create_aliased_obj(struct mlx5dr_context *ctx, uint32_t aliased_object_id, uint16_t object_type, struct mlx5dr_devx_obj **obj); + +static inline bool mlx5dr_matcher_is_insert_by_idx(struct mlx5dr_matcher *matcher) +{ + return matcher->attr.insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX; +} + #endif /* MLX5DR_MATCHER_H_ */ diff --git a/drivers/net/mlx5/hws/mlx5dr_rule.c b/drivers/net/mlx5/hws/mlx5dr_rule.c index b27318e6d4..60a82c022f 100644 --- a/drivers/net/mlx5/hws/mlx5dr_rule.c +++ b/drivers/net/mlx5/hws/mlx5dr_rule.c @@ -118,7 +118,8 @@ static int mlx5dr_rule_alloc_action_ste(struct mlx5dr_rule *rule, int ret; /* Use rule_idx for locking optimzation, otherwise allocate from pool */ - if (matcher->attr.optimize_using_rule_idx) { + if (matcher->attr.optimize_using_rule_idx || + mlx5dr_matcher_is_insert_by_idx(matcher)) { rule->action_ste_idx = attr->rule_idx * matcher->action_ste.max_stes; } else { struct mlx5dr_pool_chunk ste = {0}; @@ -138,7 +139,9 @@ void mlx5dr_rule_free_action_ste_idx(struct mlx5dr_rule *rule) { struct mlx5dr_matcher *matcher = rule->matcher; - if (rule->action_ste_idx > -1 && !matcher->attr.optimize_using_rule_idx) { + if (rule->action_ste_idx > -1 && + !matcher->attr.optimize_using_rule_idx && + !mlx5dr_matcher_is_insert_by_idx(matcher)) { struct mlx5dr_pool_chunk ste = {0}; /* This release is safe only when the rule match part was deleted */ @@ -244,9 +247,14 @@ static int mlx5dr_rule_create_hws(struct mlx5dr_rule *rule, mlx5dr_action_apply_setter(&apply, setter--, !i && is_jumbo); if (i == 0) { - /* Handle last match STE */ - mlx5dr_definer_create_tag(items, mt->fc, mt->fc_sz, - (uint8_t *)dep_wqe->wqe_data.action); + /* Handle last match STE. + * For hash split / linear lookup RTCs, packets reaching any STE + * will always match and perform the specified actions, which + * makes the tag irrelevant. + */ + if (likely(!mlx5dr_matcher_is_insert_by_idx(matcher))) + mlx5dr_definer_create_tag(items, mt->fc, mt->fc_sz, + (uint8_t *)dep_wqe->wqe_data.action); /* Rule has dependent WQEs, match dep_wqe is queued */ if (action_stes || apply.require_dep) @@ -258,13 +266,14 @@ static int mlx5dr_rule_create_hws(struct mlx5dr_rule *rule, ste_attr.send_attr.notify_hw = !attr->burst; ste_attr.send_attr.user_data = dep_wqe->user_data; ste_attr.send_attr.rule = dep_wqe->rule; - ste_attr.direct_index = 0; ste_attr.rtc_0 = dep_wqe->rtc_0; ste_attr.rtc_1 = dep_wqe->rtc_1; ste_attr.used_id_rtc_0 = &rule->rtc_0; ste_attr.used_id_rtc_1 = &rule->rtc_1; ste_attr.retry_rtc_0 = dep_wqe->retry_rtc_0; ste_attr.retry_rtc_1 = dep_wqe->retry_rtc_1; + ste_attr.direct_index = mlx5dr_matcher_is_insert_by_idx(matcher) ? + attr->rule_idx : 0; } else { apply.next_direct_idx = --ste_attr.direct_index; } @@ -364,6 +373,8 @@ static int mlx5dr_rule_destroy_hws(struct mlx5dr_rule *rule, ste_attr.wqe_tag = &rule->tag; ste_attr.wqe_tag_is_jumbo = mlx5dr_definer_is_jumbo(matcher->mt[0]->definer); ste_attr.gta_opcode = MLX5DR_WQE_GTA_OP_DEACTIVATE; + if (unlikely(mlx5dr_matcher_is_insert_by_idx(matcher))) + ste_attr.direct_index = attr->rule_idx; mlx5dr_send_ste(queue, &ste_attr); diff --git a/drivers/net/mlx5/hws/mlx5dr_rule.h b/drivers/net/mlx5/hws/mlx5dr_rule.h index 96c85674f2..f2fe418159 100644 --- a/drivers/net/mlx5/hws/mlx5dr_rule.h +++ b/drivers/net/mlx5/hws/mlx5dr_rule.h @@ -40,7 +40,7 @@ struct mlx5dr_rule { }; uint32_t rtc_0; /* The RTC into which the STE was inserted */ uint32_t rtc_1; /* The RTC into which the STE was inserted */ - int action_ste_idx; /* Action STE pool ID */ + int action_ste_idx; /* STE array index */ uint8_t status; /* enum mlx5dr_rule_status */ uint8_t pending_wqes; }; -- 2.27.0