[v3,1/5] net/mlx5/hws: introduce new matcher type

Message ID 20241024154351.1743447-2-akozyrev@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series jump to table index support in mlx5 |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Alexander Kozyrev Oct. 24, 2024, 3:41 p.m. UTC
From: Hamdan Igbaria <hamdani@nvidia.com>

introduce STE array matcher, where this matcher can only
be isolated under a parent table and not chained to the
table matchers chain.

Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr.h         | 13 +++++-
 drivers/net/mlx5/hws/mlx5dr_debug.c   | 12 +++++-
 drivers/net/mlx5/hws/mlx5dr_matcher.c | 58 +++++++++++++++++++++++--
 drivers/net/mlx5/hws/mlx5dr_matcher.h |  6 +++
 drivers/net/mlx5/hws/mlx5dr_rule.c    |  2 +-
 drivers/net/mlx5/hws/mlx5dr_table.c   | 61 +++++++++++++++++++--------
 drivers/net/mlx5/hws/mlx5dr_table.h   |  8 +++-
 drivers/net/mlx5/mlx5_flow_hw.c       |  2 +
 8 files changed, 135 insertions(+), 27 deletions(-)
  

Patch

diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h
index 0fe39e9c76..8a1a389a3f 100644
--- a/drivers/net/mlx5/hws/mlx5dr.h
+++ b/drivers/net/mlx5/hws/mlx5dr.h
@@ -130,6 +130,14 @@  enum mlx5dr_matcher_distribute_mode {
 	MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR = 0x1,
 };
 
+/* Match mode describes the behavior of the matcher STE's when a packet arrives */
+enum mlx5dr_matcher_match_mode {
+	/* Packet arriving at this matcher STE's will match according it's tag and match definer */
+	MLX5DR_MATCHER_MATCH_MODE_DEFAULT = 0x0,
+	/* Packet arriving at this matcher STE's will always hit and perform the actions */
+	MLX5DR_MATCHER_MATCH_MODE_ALWAYS_HIT = 0x1,
+};
+
 enum mlx5dr_rule_hash_calc_mode {
 	MLX5DR_RULE_HASH_CALC_MODE_RAW,
 	MLX5DR_RULE_HASH_CALC_MODE_IDX,
@@ -144,11 +152,14 @@  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 */
+	/* Define the insertion, distribution and match modes for this matcher */
 	enum mlx5dr_matcher_insert_mode insert_mode;
 	enum mlx5dr_matcher_distribute_mode distribute_mode;
+	enum mlx5dr_matcher_match_mode match_mode;
 	/* Define whether the created matcher supports resizing into a bigger matcher */
 	bool resizable;
+	/* This will imply that this matcher is not part of the matchers chain of parent table */
+	bool isolated;
 	union {
 		struct {
 			uint8_t sz_row_log;
diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c
index 741a725842..f15ad96598 100644
--- a/drivers/net/mlx5/hws/mlx5dr_debug.c
+++ b/drivers/net/mlx5/hws/mlx5dr_debug.c
@@ -182,7 +182,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,%d,%d\n",
+	ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
 		      MLX5DR_DEBUG_RES_TYPE_MATCHER_ATTR,
 		      (uint64_t)(uintptr_t)matcher,
 		      attr->priority,
@@ -192,7 +192,9 @@  mlx5dr_debug_dump_matcher_attr(FILE *f, struct mlx5dr_matcher *matcher)
 		      attr->optimize_using_rule_idx,
 		      attr->optimize_flow_src,
 		      attr->insert_mode,
-		      attr->distribute_mode);
+		      attr->distribute_mode,
+		      attr->match_mode,
+		      attr->isolated);
 	if (ret < 0) {
 		rte_errno = EINVAL;
 		return rte_errno;
@@ -377,6 +379,12 @@  static int mlx5dr_debug_dump_table(FILE *f, struct mlx5dr_table *tbl)
 			return ret;
 	}
 
+	LIST_FOREACH(matcher, &tbl->isolated_matchers, next) {
+		ret = mlx5dr_debug_dump_matcher(f, matcher);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 
 out_err:
diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c
index dfa2cd435c..54460cc82b 100644
--- a/drivers/net/mlx5/hws/mlx5dr_matcher.c
+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c
@@ -198,6 +198,18 @@  static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher)
 	struct mlx5dr_matcher *tmp_matcher;
 	int ret;
 
+	if (matcher->attr.isolated) {
+		LIST_INSERT_HEAD(&tbl->isolated_matchers, matcher, next);
+		ret = mlx5dr_table_connect_src_ft_to_miss_table(tbl, matcher->end_ft,
+								tbl->default_miss.miss_tbl);
+		if (ret) {
+			DR_LOG(ERR, "Failed to connect the new matcher to the miss_tbl");
+			goto remove_from_list;
+		}
+
+		return 0;
+	}
+
 	/* Find location in matcher list */
 	if (LIST_EMPTY(&tbl->head)) {
 		LIST_INSERT_HEAD(&tbl->head, matcher, next);
@@ -230,7 +242,7 @@  static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher)
 		}
 	} else {
 		/* Connect last matcher to next miss_tbl if exists */
-		ret = mlx5dr_table_connect_to_miss_table(tbl, tbl->default_miss.miss_tbl);
+		ret = mlx5dr_table_connect_to_miss_table(tbl, tbl->default_miss.miss_tbl, true);
 		if (ret) {
 			DR_LOG(ERR, "Failed connect new matcher to miss_tbl");
 			goto remove_from_list;
@@ -284,6 +296,11 @@  static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher)
 	struct mlx5dr_matcher *next;
 	int ret;
 
+	if (matcher->attr.isolated) {
+		LIST_REMOVE(matcher, next);
+		return 0;
+	}
+
 	prev_ft = tbl->ft;
 	prev_matcher = LIST_FIRST(&tbl->head);
 	LIST_FOREACH(tmp_matcher, &tbl->head, next) {
@@ -309,7 +326,7 @@  static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher)
 			goto matcher_reconnect;
 		}
 	} else {
-		ret = mlx5dr_table_connect_to_miss_table(tbl, tbl->default_miss.miss_tbl);
+		ret = mlx5dr_table_connect_to_miss_table(tbl, tbl->default_miss.miss_tbl, true);
 		if (ret) {
 			DR_LOG(ERR, "Failed to disconnect last matcher");
 			goto matcher_reconnect;
@@ -518,14 +535,17 @@  static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher,
 			}
 		} 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 */
+				if (mlx5dr_matcher_is_always_hit(matcher))
+					rtc_attr.num_hash_definer = 1;
+
 				rtc_attr.access_index_mode = MLX5_IFC_RTC_STE_ACCESS_MODE_BY_HASH;
 				rtc_attr.match_definer_0 = mlx5dr_definer_get_id(mt->definer);
 			} else if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR) {
 				/* Linear Lookup Table */
+				rtc_attr.num_hash_definer = 1;
 				rtc_attr.access_index_mode = MLX5_IFC_RTC_STE_ACCESS_MODE_LINEAR;
 				rtc_attr.match_definer_0 = ctx->caps->linear_match_definer;
 			}
@@ -973,10 +993,17 @@  mlx5dr_matcher_validate_insert_mode(struct mlx5dr_cmd_query_caps *caps,
 
 		if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) {
 			/* Hash Split Table */
-			if (!caps->rtc_hash_split_table) {
+			if (attr->match_mode == MLX5DR_MATCHER_MATCH_MODE_ALWAYS_HIT &&
+			    !caps->rtc_hash_split_table) {
 				DR_LOG(ERR, "FW doesn't support insert by index and hash distribute");
 				goto not_supported;
 			}
+
+			if (attr->match_mode == MLX5DR_MATCHER_MATCH_MODE_DEFAULT &&
+			    !attr->isolated) {
+				DR_LOG(ERR, "STE array matcher supported only as an isolated matcher");
+				goto not_supported;
+			}
 		} else if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR) {
 			/* Linear Lookup Table */
 			if (!caps->rtc_linear_lookup_table ||
@@ -991,6 +1018,12 @@  mlx5dr_matcher_validate_insert_mode(struct mlx5dr_cmd_query_caps *caps,
 				       MLX5_IFC_RTC_LINEAR_LOOKUP_TBL_LOG_MAX);
 				goto not_supported;
 			}
+
+			if (attr->match_mode != MLX5DR_MATCHER_MATCH_MODE_ALWAYS_HIT) {
+				DR_LOG(ERR, "Linear lookup tables will always hit, given match mode is not supported %d\n",
+				       attr->match_mode);
+				goto not_supported;
+			}
 		} else {
 			DR_LOG(ERR, "Matcher has unsupported distribute mode");
 			goto not_supported;
@@ -1032,6 +1065,11 @@  mlx5dr_matcher_process_attr(struct mlx5dr_cmd_query_caps *caps,
 			DR_LOG(ERR, "Root matcher does not support resizing");
 			goto not_supported;
 		}
+		if (attr->isolated) {
+			DR_LOG(ERR, "Root matcher can not be isolated");
+			goto not_supported;
+		}
+
 		return 0;
 	}
 
@@ -1045,6 +1083,18 @@  mlx5dr_matcher_process_attr(struct mlx5dr_cmd_query_caps *caps,
 	    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->isolated) {
+		if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_INDEX ||
+		    attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH ||
+		    attr->match_mode != MLX5DR_MATCHER_MATCH_MODE_DEFAULT) {
+			DR_LOG(ERR, "Isolated matcher only supported for STE array matcher");
+			goto not_supported;
+		}
+
+		/* We reach here only in case of STE array */
+		matcher->flags |= MLX5DR_MATCHER_FLAGS_STE_ARRAY;
+	}
+
 	matcher->flags |= attr->resizable ? MLX5DR_MATCHER_FLAGS_RESIZABLE : 0;
 
 	return mlx5dr_matcher_check_attr_sz(caps, attr);
diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h
index ca6a5298d9..ef42b7de6b 100644
--- a/drivers/net/mlx5/hws/mlx5dr_matcher.h
+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h
@@ -28,6 +28,7 @@  enum mlx5dr_matcher_flags {
 	MLX5DR_MATCHER_FLAGS_COLLISION		= 1 << 2,
 	MLX5DR_MATCHER_FLAGS_RESIZABLE		= 1 << 3,
 	MLX5DR_MATCHER_FLAGS_COMPARE		= 1 << 4,
+	MLX5DR_MATCHER_FLAGS_STE_ARRAY		= 1 << 5,
 };
 
 struct mlx5dr_match_template {
@@ -146,6 +147,11 @@  static inline bool mlx5dr_matcher_is_insert_by_idx(struct mlx5dr_matcher *matche
 	return matcher->attr.insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX;
 }
 
+static inline bool mlx5dr_matcher_is_always_hit(struct mlx5dr_matcher *matcher)
+{
+	return matcher->attr.match_mode == MLX5DR_MATCHER_MATCH_MODE_ALWAYS_HIT;
+}
+
 int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx,
 				     uint32_t fw_ft_type,
 				     enum mlx5dr_table_type type,
diff --git a/drivers/net/mlx5/hws/mlx5dr_rule.c b/drivers/net/mlx5/hws/mlx5dr_rule.c
index 5d66d81ea5..519328ccf3 100644
--- a/drivers/net/mlx5/hws/mlx5dr_rule.c
+++ b/drivers/net/mlx5/hws/mlx5dr_rule.c
@@ -539,7 +539,7 @@  static int mlx5dr_rule_create_hws(struct mlx5dr_rule *rule,
 			 * will always match and perform the specified actions, which
 			 * makes the tag irrelevant.
 			 */
-			if (likely(!mlx5dr_matcher_is_insert_by_idx(matcher) && !is_update))
+			if (likely(!mlx5dr_matcher_is_always_hit(matcher) && !is_update))
 				mlx5dr_definer_create_tag(items, mt->fc, mt->fc_sz,
 							  (uint8_t *)dep_wqe->wqe_data.action);
 			else if (unlikely(is_update))
diff --git a/drivers/net/mlx5/hws/mlx5dr_table.c b/drivers/net/mlx5/hws/mlx5dr_table.c
index ab73017ade..634b484a94 100644
--- a/drivers/net/mlx5/hws/mlx5dr_table.c
+++ b/drivers/net/mlx5/hws/mlx5dr_table.c
@@ -429,7 +429,7 @@  int mlx5dr_table_destroy(struct mlx5dr_table *tbl)
 {
 	struct mlx5dr_context *ctx = tbl->ctx;
 	pthread_spin_lock(&ctx->ctrl_lock);
-	if (!LIST_EMPTY(&tbl->head)) {
+	if (!LIST_EMPTY(&tbl->head) || !LIST_EMPTY(&tbl->isolated_matchers)) {
 		DR_LOG(ERR, "Cannot destroy table containing matchers");
 		rte_errno = EBUSY;
 		goto unlock_err;
@@ -531,7 +531,7 @@  int mlx5dr_table_update_connected_miss_tables(struct mlx5dr_table *dst_tbl)
 		return 0;
 
 	LIST_FOREACH(src_tbl, &dst_tbl->default_miss.head, default_miss.next) {
-		ret = mlx5dr_table_connect_to_miss_table(src_tbl, dst_tbl);
+		ret = mlx5dr_table_connect_to_miss_table(src_tbl, dst_tbl, false);
 		if (ret) {
 			DR_LOG(ERR, "Failed to update source miss table, unexpected behavior");
 			return ret;
@@ -541,34 +541,32 @@  int mlx5dr_table_update_connected_miss_tables(struct mlx5dr_table *dst_tbl)
 	return 0;
 }
 
-int mlx5dr_table_connect_to_miss_table(struct mlx5dr_table *src_tbl,
-				       struct mlx5dr_table *dst_tbl)
+int mlx5dr_table_connect_src_ft_to_miss_table(struct mlx5dr_table *src_tbl,
+					      struct mlx5dr_devx_obj *ft,
+					      struct mlx5dr_table *dst_tbl)
 {
-	struct mlx5dr_devx_obj *last_ft;
 	struct mlx5dr_matcher *matcher;
 	int ret;
 
-	last_ft = mlx5dr_table_get_last_ft(src_tbl);
-
 	if (dst_tbl) {
 		if (LIST_EMPTY(&dst_tbl->head)) {
-			/* Connect src_tbl last_ft to dst_tbl start anchor */
-			ret = mlx5dr_table_ft_set_next_ft(last_ft,
+			/* Connect src_tbl ft to dst_tbl start anchor */
+			ret = mlx5dr_table_ft_set_next_ft(ft,
 							  src_tbl->fw_ft_type,
 							  dst_tbl->ft->id);
 			if (ret)
 				return ret;
 
-			/* Reset last_ft RTC to default RTC */
-			ret = mlx5dr_table_ft_set_next_rtc(last_ft,
+			/* Reset ft RTC to default RTC */
+			ret = mlx5dr_table_ft_set_next_rtc(ft,
 							   src_tbl->fw_ft_type,
 							   NULL, NULL);
 			if (ret)
 				return ret;
 		} else {
-			/* Connect src_tbl last_ft to first matcher RTC */
+			/* Connect src_tbl ft to first matcher RTC */
 			matcher = LIST_FIRST(&dst_tbl->head);
-			ret = mlx5dr_table_ft_set_next_rtc(last_ft,
+			ret = mlx5dr_table_ft_set_next_rtc(ft,
 							   src_tbl->fw_ft_type,
 							   matcher->match_ste.rtc_0,
 							   matcher->match_ste.rtc_1);
@@ -576,24 +574,51 @@  int mlx5dr_table_connect_to_miss_table(struct mlx5dr_table *src_tbl,
 				return ret;
 
 			/* Reset next miss FT to default */
-			ret = mlx5dr_table_ft_set_default_next_ft(src_tbl, last_ft);
+			ret = mlx5dr_table_ft_set_default_next_ft(src_tbl, ft);
 			if (ret)
 				return ret;
 		}
 	} else {
 		/* Reset next miss FT to default */
-		ret = mlx5dr_table_ft_set_default_next_ft(src_tbl, last_ft);
+		ret = mlx5dr_table_ft_set_default_next_ft(src_tbl, ft);
 		if (ret)
 			return ret;
 
-		/* Reset last_ft RTC to default RTC */
-		ret = mlx5dr_table_ft_set_next_rtc(last_ft,
+		/* Reset ft RTC to default RTC */
+		ret = mlx5dr_table_ft_set_next_rtc(ft,
 						   src_tbl->fw_ft_type,
 						   NULL, NULL);
 		if (ret)
 			return ret;
 	}
 
+	return 0;
+}
+
+int mlx5dr_table_connect_to_miss_table(struct mlx5dr_table *src_tbl,
+				       struct mlx5dr_table *dst_tbl,
+				       bool only_update_last_ft)
+{
+	struct mlx5dr_matcher *matcher;
+	struct mlx5dr_devx_obj *ft;
+	int ret;
+
+	/* Connect last FT in the src_tbl matchers chain */
+	ft = mlx5dr_table_get_last_ft(src_tbl);
+	ret = mlx5dr_table_connect_src_ft_to_miss_table(src_tbl, ft, dst_tbl);
+	if (ret)
+		return ret;
+
+	if (!only_update_last_ft) {
+		/* Connect isolated matchers FT */
+		LIST_FOREACH(matcher, &src_tbl->isolated_matchers, next) {
+			ft = matcher->end_ft;
+			ret = mlx5dr_table_connect_src_ft_to_miss_table(src_tbl, ft, dst_tbl);
+			if (ret)
+				return ret;
+		}
+	}
+
 	src_tbl->default_miss.miss_tbl = dst_tbl;
 
 	return 0;
@@ -633,7 +658,7 @@  int mlx5dr_table_set_default_miss(struct mlx5dr_table *tbl,
 
 	pthread_spin_lock(&ctx->ctrl_lock);
 	old_miss_tbl = tbl->default_miss.miss_tbl;
-	ret = mlx5dr_table_connect_to_miss_table(tbl, miss_tbl);
+	ret = mlx5dr_table_connect_to_miss_table(tbl, miss_tbl, false);
 	if (ret)
 		goto out;
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_table.h b/drivers/net/mlx5/hws/mlx5dr_table.h
index b2fbb47416..32f2574a97 100644
--- a/drivers/net/mlx5/hws/mlx5dr_table.h
+++ b/drivers/net/mlx5/hws/mlx5dr_table.h
@@ -23,6 +23,7 @@  struct mlx5dr_table {
 	uint32_t fw_ft_type;
 	uint32_t level;
 	LIST_HEAD(matcher_head, mlx5dr_matcher) head;
+	LIST_HEAD(isolated_matchers_head, mlx5dr_matcher) isolated_matchers;
 	LIST_ENTRY(mlx5dr_table) next;
 	struct mlx5dr_default_miss default_miss;
 };
@@ -54,7 +55,8 @@  void mlx5dr_table_destroy_default_ft(struct mlx5dr_table *tbl,
 				     struct mlx5dr_devx_obj *ft_obj);
 
 int mlx5dr_table_connect_to_miss_table(struct mlx5dr_table *src_tbl,
-				       struct mlx5dr_table *dst_tbl);
+				       struct mlx5dr_table *dst_tbl,
+				       bool only_update_last_ft);
 
 int mlx5dr_table_update_connected_miss_tables(struct mlx5dr_table *dst_tbl);
 
@@ -66,4 +68,8 @@  int mlx5dr_table_ft_set_next_rtc(struct mlx5dr_devx_obj *ft,
 				 struct mlx5dr_devx_obj *rtc_0,
 				 struct mlx5dr_devx_obj *rtc_1);
 
+int mlx5dr_table_connect_src_ft_to_miss_table(struct mlx5dr_table *src_tbl,
+					      struct mlx5dr_devx_obj *ft,
+					      struct mlx5dr_table *dst_tbl);
+
 #endif /* MLX5DR_TABLE_H_ */
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 5b34154bf1..c21eb1eaed 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -5157,6 +5157,8 @@  flow_hw_table_create(struct rte_eth_dev *dev,
 	matcher_attr.optimize_using_rule_idx = true;
 	matcher_attr.mode = MLX5DR_MATCHER_RESOURCE_MODE_RULE;
 	matcher_attr.insert_mode = flow_hw_matcher_insert_mode_get(attr->insertion_type);
+	if (matcher_attr.insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX)
+		matcher_attr.match_mode = MLX5DR_MATCHER_MATCH_MODE_ALWAYS_HIT;
 	if (attr->hash_func == RTE_FLOW_TABLE_HASH_FUNC_CRC16) {
 		DRV_LOG(ERR, "16-bit checksum hash type is not supported");
 		rte_errno = ENOTSUP;