DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH v3 0/5] jump to table index support in mlx5
@ 2024-10-24 15:41 Alexander Kozyrev
  2024-10-24 15:41 ` [PATCH v3 1/5] net/mlx5/hws: introduce new matcher type Alexander Kozyrev
                   ` (5 more replies)
  0 siblings, 6 replies; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 15:41 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

Support the new Flow API JUMP_TO_TABLE_INDEX action in mlx5.

Seried-acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>

Alexander Kozyrev (3):
  net/mlx5: create array ste matcher
  net/mlx5: add flow rule insertion by index with pattern
  net/mlx5: implement jump to table index action

Hamdan Igbaria (2):
  net/mlx5/hws: introduce new matcher type
  net/mlx5/hws: introduce jump to matcher action

 doc/guides/nics/features/mlx5.ini             |   1 +
 doc/guides/prog_guide/ethdev/flow_offload.rst |  24 +
 doc/guides/rel_notes/release_24_11.rst        |   3 +
 drivers/net/mlx5/hws/mlx5dr.h                 |  42 +-
 drivers/net/mlx5/hws/mlx5dr_action.c          |  87 +++-
 drivers/net/mlx5/hws/mlx5dr_action.h          |   3 +
 drivers/net/mlx5/hws/mlx5dr_debug.c           |  13 +-
 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.h                  |   8 +-
 drivers/net/mlx5/mlx5_flow_hw.c               | 435 ++++++++++--------
 14 files changed, 519 insertions(+), 232 deletions(-)

-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 1/5] net/mlx5/hws: introduce new matcher type
  2024-10-24 15:41 [PATCH v3 0/5] jump to table index support in mlx5 Alexander Kozyrev
@ 2024-10-24 15:41 ` Alexander Kozyrev
  2024-10-24 15:41 ` [PATCH v3 2/5] net/mlx5/hws: introduce jump to matcher action Alexander Kozyrev
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 15:41 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

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(-)

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;
-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 2/5] net/mlx5/hws: introduce jump to matcher action
  2024-10-24 15:41 [PATCH v3 0/5] jump to table index support in mlx5 Alexander Kozyrev
  2024-10-24 15:41 ` [PATCH v3 1/5] net/mlx5/hws: introduce new matcher type Alexander Kozyrev
@ 2024-10-24 15:41 ` Alexander Kozyrev
  2024-10-24 15:41 ` [PATCH v3 3/5] net/mlx5: create array ste matcher Alexander Kozyrev
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 15:41 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

From: Hamdan Igbaria <hamdani@nvidia.com>

Introduce jump to matcher action, this action will allow
jumping to another matcher.
For now this jump restricted to STE array matchers and
matchers of size 1.

Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr.h        | 29 ++++++++++
 drivers/net/mlx5/hws/mlx5dr_action.c | 87 +++++++++++++++++++++++++++-
 drivers/net/mlx5/hws/mlx5dr_action.h |  3 +
 drivers/net/mlx5/hws/mlx5dr_debug.c  |  1 +
 4 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h
index 8a1a389a3f..1b58eeb2c7 100644
--- a/drivers/net/mlx5/hws/mlx5dr.h
+++ b/drivers/net/mlx5/hws/mlx5dr.h
@@ -52,6 +52,7 @@ enum mlx5dr_action_type {
 	MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT,
 	MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT,
 	MLX5DR_ACTION_TYP_NAT64,
+	MLX5DR_ACTION_TYP_JUMP_TO_MATCHER,
 	MLX5DR_ACTION_TYP_MAX,
 };
 
@@ -287,6 +288,10 @@ struct mlx5dr_rule_action {
 			uint32_t offset;
 			enum mlx5dr_action_aso_ct_flags direction;
 		} aso_ct;
+
+		struct {
+			uint32_t offset;
+		} jump_to_matcher;
 	};
 };
 
@@ -304,6 +309,15 @@ struct mlx5dr_action_dest_attr {
 	} reformat;
 };
 
+enum mlx5dr_action_jump_to_matcher_type {
+	MLX5DR_ACTION_JUMP_TO_MATCHER_BY_INDEX,
+};
+
+struct mlx5dr_action_jump_to_matcher_attr {
+	enum mlx5dr_action_jump_to_matcher_type type;
+	struct mlx5dr_matcher *matcher;
+};
+
 union mlx5dr_crc_encap_entropy_hash_ip_field {
 	uint8_t  ipv6_addr[16];
 	struct {
@@ -938,6 +952,21 @@ mlx5dr_action_create_nat64(struct mlx5dr_context *ctx,
 			   struct mlx5dr_action_nat64_attr *attr,
 			   uint32_t flags);
 
+/* Create direct rule jump to matcher action.
+ *
+ * @param[in] ctx
+ *	The context in which the new action will be created.
+ * @param[in] attr
+ *	The relevant attribute of the action.
+ * @param[in] flags
+ *	Action creation flags. (enum mlx5dr_action_flags)
+ * @return pointer to mlx5dr_action on success NULL otherwise.
+ */
+struct mlx5dr_action *
+mlx5dr_action_create_jump_to_matcher(struct mlx5dr_context *ctx,
+				     struct mlx5dr_action_jump_to_matcher_attr *attr,
+				     uint32_t flags);
+
 /* Destroy direct rule action.
  *
  * @param[in] action
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c
index 3fceb96de2..3412a96894 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.c
+++ b/drivers/net/mlx5/hws/mlx5dr_action.c
@@ -42,7 +42,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_TIR) |
 		BIT(MLX5DR_ACTION_TYP_DROP) |
 		BIT(MLX5DR_ACTION_TYP_DEST_ROOT) |
-		BIT(MLX5DR_ACTION_TYP_DEST_ARRAY),
+		BIT(MLX5DR_ACTION_TYP_DEST_ARRAY) |
+		BIT(MLX5DR_ACTION_TYP_JUMP_TO_MATCHER),
 		BIT(MLX5DR_ACTION_TYP_LAST),
 	},
 	[MLX5DR_TABLE_TYPE_NIC_TX] = {
@@ -62,7 +63,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_TBL) |
 		BIT(MLX5DR_ACTION_TYP_MISS) |
 		BIT(MLX5DR_ACTION_TYP_DROP) |
-		BIT(MLX5DR_ACTION_TYP_DEST_ROOT),
+		BIT(MLX5DR_ACTION_TYP_DEST_ROOT) |
+		BIT(MLX5DR_ACTION_TYP_JUMP_TO_MATCHER),
 		BIT(MLX5DR_ACTION_TYP_LAST),
 	},
 	[MLX5DR_TABLE_TYPE_FDB] = {
@@ -88,7 +90,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_VPORT) |
 		BIT(MLX5DR_ACTION_TYP_DROP) |
 		BIT(MLX5DR_ACTION_TYP_DEST_ROOT) |
-		BIT(MLX5DR_ACTION_TYP_DEST_ARRAY),
+		BIT(MLX5DR_ACTION_TYP_DEST_ARRAY) |
+		BIT(MLX5DR_ACTION_TYP_JUMP_TO_MATCHER),
 		BIT(MLX5DR_ACTION_TYP_LAST),
 	},
 };
@@ -1091,6 +1094,13 @@ static void mlx5dr_action_fill_stc_attr(struct mlx5dr_action *action,
 		attr->action_offset = MLX5DR_ACTION_OFFSET_DW5;
 		attr->reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS;
 		break;
+	case MLX5DR_ACTION_TYP_JUMP_TO_MATCHER:
+		attr->action_type = MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE;
+		attr->action_offset = MLX5DR_ACTION_OFFSET_HIT;
+		attr->ste_table.ste = action->jump_to_matcher.matcher->match_ste.ste;
+		attr->ste_table.ste_pool = action->jump_to_matcher.matcher->match_ste.pool;
+		attr->ste_table.match_definer_id = action->ctx->caps->trivial_match_definer;
+		break;
 	default:
 		DR_LOG(ERR, "Invalid action type %d", action->type);
 		assert(false);
@@ -3078,6 +3088,57 @@ mlx5dr_action_create_nat64(struct mlx5dr_context *ctx,
 	return NULL;
 }
 
+struct mlx5dr_action *
+mlx5dr_action_create_jump_to_matcher(struct mlx5dr_context *ctx,
+				     struct mlx5dr_action_jump_to_matcher_attr *attr,
+				     uint32_t flags)
+{
+	struct mlx5dr_matcher *matcher = attr->matcher;
+	struct mlx5dr_matcher_attr *m_attr;
+	struct mlx5dr_action *action;
+
+	if (attr->type != MLX5DR_ACTION_JUMP_TO_MATCHER_BY_INDEX) {
+		DR_LOG(ERR, "Only jump to matcher by index is supported");
+		goto enotsup;
+	}
+
+	if (mlx5dr_action_is_root_flags(flags)) {
+		DR_LOG(ERR, "Action flags must be only non root (HWS)");
+		goto enotsup;
+	}
+
+	if (mlx5dr_table_is_root(matcher->tbl)) {
+		DR_LOG(ERR, "Root matcher cannot be set as destination");
+		goto enotsup;
+	}
+
+	m_attr = &matcher->attr;
+
+	if (!(matcher->flags & MLX5DR_MATCHER_FLAGS_STE_ARRAY) &&
+	    (m_attr->resizable || m_attr->table.sz_col_log || m_attr->table.sz_row_log)) {
+		DR_LOG(ERR, "Only STE array or matcher of size 1 can be set as destination");
+		goto enotsup;
+	}
+
+	action = mlx5dr_action_create_generic(ctx, flags, MLX5DR_ACTION_TYP_JUMP_TO_MATCHER);
+	if (!action)
+		return NULL;
+
+	action->jump_to_matcher.matcher = matcher;
+
+	if (mlx5dr_action_create_stcs(action, NULL)) {
+		DR_LOG(ERR, "Failed to create action jump to matcher STC");
+		simple_free(action);
+		return NULL;
+	}
+
+	return action;
+
+enotsup:
+	rte_errno = ENOTSUP;
+	return NULL;
+}
+
 static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)
 {
 	struct mlx5dr_devx_obj *obj = NULL;
@@ -3100,6 +3161,7 @@ static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)
 	case MLX5DR_ACTION_TYP_PUSH_VLAN:
 	case MLX5DR_ACTION_TYP_REMOVE_HEADER:
 	case MLX5DR_ACTION_TYP_VPORT:
+	case MLX5DR_ACTION_TYP_JUMP_TO_MATCHER:
 		mlx5dr_action_destroy_stcs(action);
 		break;
 	case MLX5DR_ACTION_TYP_DEST_ROOT:
@@ -3618,6 +3680,19 @@ mlx5dr_action_setter_default_hit(struct mlx5dr_actions_apply_data *apply,
 		htobe32(apply->common_res->default_stc->default_hit.offset);
 }
 
+static void
+mlx5dr_action_setter_hit_matcher(struct mlx5dr_actions_apply_data *apply,
+				 struct mlx5dr_actions_wqe_setter *setter)
+{
+	struct mlx5dr_rule_action *rule_action;
+
+	rule_action = &apply->rule_action[setter->idx_hit];
+
+	apply->wqe_data[MLX5DR_ACTION_OFFSET_HIT_LSB] =
+		htobe32(rule_action->jump_to_matcher.offset << 6);
+	mlx5dr_action_apply_stc(apply, MLX5DR_ACTION_STC_IDX_HIT, setter->idx_hit);
+}
+
 static void
 mlx5dr_action_setter_hit_next_action(struct mlx5dr_actions_apply_data *apply,
 				     __rte_unused struct mlx5dr_actions_wqe_setter *setter)
@@ -3965,6 +4040,12 @@ int mlx5dr_action_template_process(struct mlx5dr_action_template *at)
 			}
 			break;
 
+		case MLX5DR_ACTION_TYP_JUMP_TO_MATCHER:
+			last_setter->flags |= ASF_HIT;
+			last_setter->set_hit = &mlx5dr_action_setter_hit_matcher;
+			last_setter->idx_hit = i;
+			break;
+
 		default:
 			DR_LOG(ERR, "Unsupported action type: %d", action_type[i]);
 			rte_errno = ENOTSUP;
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.h b/drivers/net/mlx5/hws/mlx5dr_action.h
index ba4ce55228..8ce4ecd5ba 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.h
+++ b/drivers/net/mlx5/hws/mlx5dr_action.h
@@ -223,6 +223,9 @@ struct mlx5dr_action {
 				struct {
 					struct mlx5dr_action *stages[MLX5DR_ACTION_NAT64_STAGES];
 				} nat64;
+				struct {
+					struct mlx5dr_matcher *matcher;
+				} jump_to_matcher;
 			};
 		};
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c
index f15ad96598..8684a8197a 100644
--- a/drivers/net/mlx5/hws/mlx5dr_debug.c
+++ b/drivers/net/mlx5/hws/mlx5dr_debug.c
@@ -29,6 +29,7 @@ const char *mlx5dr_debug_action_type_str[] = {
 	[MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT] = "POP_IPV6_ROUTE_EXT",
 	[MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT] = "PUSH_IPV6_ROUTE_EXT",
 	[MLX5DR_ACTION_TYP_NAT64] = "NAT64",
+	[MLX5DR_ACTION_TYP_JUMP_TO_MATCHER] = "JUMP_TO_MATCHER",
 };
 
 static_assert(ARRAY_SIZE(mlx5dr_debug_action_type_str) == MLX5DR_ACTION_TYP_MAX,
-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 3/5] net/mlx5: create array ste matcher
  2024-10-24 15:41 [PATCH v3 0/5] jump to table index support in mlx5 Alexander Kozyrev
  2024-10-24 15:41 ` [PATCH v3 1/5] net/mlx5/hws: introduce new matcher type Alexander Kozyrev
  2024-10-24 15:41 ` [PATCH v3 2/5] net/mlx5/hws: introduce jump to matcher action Alexander Kozyrev
@ 2024-10-24 15:41 ` Alexander Kozyrev
  2024-10-24 15:41 ` [PATCH v3 4/5] net/mlx5: add flow rule insertion by index with pattern Alexander Kozyrev
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 15:41 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

Create an array STE matcher for a template table
in case of insertion by index with pattern is selected.
Packets will be matched on a pattern at the index.
This table is isolated from any other tables in a group.
That means packets missed the rule won't go to a lower
priority tables, but proceed with the default miss instead.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow_hw.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index c21eb1eaed..c236831e21 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -5157,8 +5157,15 @@ 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 (matcher_attr.insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX) {
+		if (attr->insertion_type == RTE_FLOW_TABLE_INSERTION_TYPE_INDEX_WITH_PATTERN) {
+			matcher_attr.isolated = true;
+			matcher_attr.match_mode = MLX5DR_MATCHER_MATCH_MODE_DEFAULT;
+		} else {
+			matcher_attr.isolated = false;
+			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;
-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 4/5] net/mlx5: add flow rule insertion by index with pattern
  2024-10-24 15:41 [PATCH v3 0/5] jump to table index support in mlx5 Alexander Kozyrev
                   ` (2 preceding siblings ...)
  2024-10-24 15:41 ` [PATCH v3 3/5] net/mlx5: create array ste matcher Alexander Kozyrev
@ 2024-10-24 15:41 ` Alexander Kozyrev
  2024-10-24 15:41 ` [PATCH v3 5/5] net/mlx5: implement jump to table index action Alexander Kozyrev
  2024-10-24 17:50 ` [PATCH v4 0/5] jump to table index support in mlx5 Alexander Kozyrev
  5 siblings, 0 replies; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 15:41 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

Implement rte_flow_async_create_by_index_with_pattern() function.
Rework the driver implementation to reduce code duplication by
providing a single flow insertion routine, that can be called with
different parameters depending on the insertion type.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/rel_notes/release_24_11.rst |   2 +
 drivers/net/mlx5/mlx5_flow_hw.c        | 281 +++++++------------------
 2 files changed, 83 insertions(+), 200 deletions(-)

diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst
index fa4822d928..07a8435b19 100644
--- a/doc/guides/rel_notes/release_24_11.rst
+++ b/doc/guides/rel_notes/release_24_11.rst
@@ -247,6 +247,8 @@ New Features
   Added ability for node to advertise and update multiple xstat counters,
   that can be retrieved using ``rte_graph_cluster_stats_get``.
 
+* **Updated NVIDIA MLX5 net driver.**
+  * Added rte_flow_async_create_by_index_with_pattern() support.
 
 Removed Items
 -------------
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index c236831e21..412d927efb 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -335,18 +335,13 @@ static __rte_always_inline uint32_t flow_hw_tx_tag_regc_value(struct rte_eth_dev
 static int flow_hw_async_create_validate(struct rte_eth_dev *dev,
 					 const uint32_t queue,
 					 const struct rte_flow_template_table *table,
+					 enum rte_flow_table_insertion_type insertion_type,
+					 const uint32_t rule_index,
 					 const struct rte_flow_item items[],
 					 const uint8_t pattern_template_index,
 					 const struct rte_flow_action actions[],
 					 const uint8_t action_template_index,
 					 struct rte_flow_error *error);
-static int flow_hw_async_create_by_index_validate(struct rte_eth_dev *dev,
-						  const uint32_t queue,
-						  const struct rte_flow_template_table *table,
-						  const uint32_t rule_index,
-						  const struct rte_flow_action actions[],
-						  const uint8_t action_template_index,
-						  struct rte_flow_error *error);
 static int flow_hw_async_update_validate(struct rte_eth_dev *dev,
 					 const uint32_t queue,
 					 const struct rte_flow_hw *flow,
@@ -3884,6 +3879,12 @@ flow_hw_get_rule_items(struct rte_eth_dev *dev,
  *   The queue to create the flow.
  * @param[in] attr
  *   Pointer to the flow operation attributes.
+ * @param[in] table
+ *   Pointer to the template table.
+ * @param[in] insertion_type
+ *   Insertion type for flow rules.
+ * @param[in] rule_index
+ *   The item pattern flow follows from the table.
  * @param[in] items
  *   Items with flow spec value.
  * @param[in] pattern_template_index
@@ -3900,17 +3901,19 @@ flow_hw_get_rule_items(struct rte_eth_dev *dev,
  * @return
  *    Flow pointer on success, NULL otherwise and rte_errno is set.
  */
-static struct rte_flow *
-flow_hw_async_flow_create(struct rte_eth_dev *dev,
-			  uint32_t queue,
-			  const struct rte_flow_op_attr *attr,
-			  struct rte_flow_template_table *table,
-			  const struct rte_flow_item items[],
-			  uint8_t pattern_template_index,
-			  const struct rte_flow_action actions[],
-			  uint8_t action_template_index,
-			  void *user_data,
-			  struct rte_flow_error *error)
+static __rte_always_inline struct rte_flow *
+flow_hw_async_flow_create_generic(struct rte_eth_dev *dev,
+				  uint32_t queue,
+				  const struct rte_flow_op_attr *attr,
+				  struct rte_flow_template_table *table,
+				  enum rte_flow_table_insertion_type insertion_type,
+				  uint32_t rule_index,
+				  const struct rte_flow_item items[],
+				  uint8_t pattern_template_index,
+				  const struct rte_flow_action actions[],
+				  uint8_t action_template_index,
+				  void *user_data,
+				  struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5dr_rule_attr rule_attr = {
@@ -3928,8 +3931,8 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
 	int ret;
 
 	if (mlx5_fp_debug_enabled()) {
-		if (flow_hw_async_create_validate(dev, queue, table, items, pattern_template_index,
-						  actions, action_template_index, error))
+		if (flow_hw_async_create_validate(dev, queue, table, insertion_type, rule_index,
+			items, pattern_template_index, actions, action_template_index, error))
 			return NULL;
 	}
 	flow = mlx5_ipool_malloc(table->flow, &flow_idx);
@@ -3967,7 +3970,7 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
 	 * Indexed pool returns 1-based indices, but mlx5dr expects 0-based indices
 	 * for rule insertion hints.
 	 */
-	flow->rule_idx = flow->res_idx - 1;
+	flow->rule_idx = (rule_index == UINT32_MAX) ? flow->res_idx - 1 : rule_index;
 	rule_attr.rule_idx = flow->rule_idx;
 	/*
 	 * Construct the flow actions based on the input actions.
@@ -4023,33 +4026,26 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
 	return NULL;
 }
 
-/**
- * Enqueue HW steering flow creation by index.
- *
- * The flow will be applied to the HW only if the postpone bit is not set or
- * the extra push function is called.
- * The flow creation status should be checked from dequeue result.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to create the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] rule_index
- *   The item pattern flow follows from the table.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Flow pointer on success, NULL otherwise and rte_errno is set.
- */
+static struct rte_flow *
+flow_hw_async_flow_create(struct rte_eth_dev *dev,
+			  uint32_t queue,
+			  const struct rte_flow_op_attr *attr,
+			  struct rte_flow_template_table *table,
+			  const struct rte_flow_item items[],
+			  uint8_t pattern_template_index,
+			  const struct rte_flow_action actions[],
+			  uint8_t action_template_index,
+			  void *user_data,
+			  struct rte_flow_error *error)
+{
+	uint32_t rule_index = UINT32_MAX;
+
+	return flow_hw_async_flow_create_generic(dev, queue, attr, table,
+		RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN, rule_index,
+		items, pattern_template_index, actions, action_template_index,
+		user_data, error);
+}
+
 static struct rte_flow *
 flow_hw_async_flow_create_by_index(struct rte_eth_dev *dev,
 			  uint32_t queue,
@@ -4062,105 +4058,31 @@ flow_hw_async_flow_create_by_index(struct rte_eth_dev *dev,
 			  struct rte_flow_error *error)
 {
 	struct rte_flow_item items[] = {{.type = RTE_FLOW_ITEM_TYPE_END,}};
-	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5dr_rule_attr rule_attr = {
-		.queue_id = queue,
-		.user_data = user_data,
-		.burst = attr->postpone,
-	};
-	struct mlx5dr_rule_action *rule_acts;
-	struct mlx5_flow_hw_action_params ap;
-	struct rte_flow_hw *flow = NULL;
-	uint32_t flow_idx = 0;
-	uint32_t res_idx = 0;
-	int ret;
+	uint8_t pattern_template_index = 0;
 
-	if (mlx5_fp_debug_enabled()) {
-		if (flow_hw_async_create_by_index_validate(dev, queue, table, rule_index,
-							   actions, action_template_index, error))
-			return NULL;
-	}
-	flow = mlx5_ipool_malloc(table->flow, &flow_idx);
-	if (!flow) {
-		rte_errno = ENOMEM;
-		goto error;
-	}
-	rule_acts = flow_hw_get_dr_action_buffer(priv, table, action_template_index, queue);
-	/*
-	 * Set the table here in order to know the destination table
-	 * when free the flow afterwards.
-	 */
-	flow->table = table;
-	flow->mt_idx = 0;
-	flow->idx = flow_idx;
-	if (table->resource) {
-		mlx5_ipool_malloc(table->resource, &res_idx);
-		if (!res_idx) {
-			rte_errno = ENOMEM;
-			goto error;
-		}
-		flow->res_idx = res_idx;
-	} else {
-		flow->res_idx = flow_idx;
-	}
-	flow->flags = 0;
-	/*
-	 * Set the flow operation type here in order to know if the flow memory
-	 * should be freed or not when get the result from dequeue.
-	 */
-	flow->operation_type = MLX5_FLOW_HW_FLOW_OP_TYPE_CREATE;
-	flow->user_data = user_data;
-	rule_attr.user_data = flow;
-	/* Set the rule index. */
-	flow->rule_idx = rule_index;
-	rule_attr.rule_idx = flow->rule_idx;
-	/*
-	 * Construct the flow actions based on the input actions.
-	 * The implicitly appended action is always fixed, like metadata
-	 * copy action from FDB to NIC Rx.
-	 * No need to copy and contrust a new "actions" list based on the
-	 * user's input, in order to save the cost.
-	 */
-	if (flow_hw_actions_construct(dev, flow, &ap,
-				      &table->ats[action_template_index],
-				      table->its[0]->item_flags, table,
-				      actions, rule_acts, queue, error)) {
-		rte_errno = EINVAL;
-		goto error;
-	}
-	if (likely(!rte_flow_template_table_resizable(dev->data->port_id, &table->cfg.attr))) {
-		ret = mlx5dr_rule_create(table->matcher_info[0].matcher,
-					 0, items, action_template_index,
-					 rule_acts, &rule_attr,
-					 (struct mlx5dr_rule *)flow->rule);
-	} else {
-		struct rte_flow_hw_aux *aux = mlx5_flow_hw_aux(dev->data->port_id, flow);
-		uint32_t selector;
+	return flow_hw_async_flow_create_generic(dev, queue, attr, table,
+		RTE_FLOW_TABLE_INSERTION_TYPE_INDEX, rule_index,
+		items, pattern_template_index, actions, action_template_index,
+		user_data, error);
+}
 
-		flow->operation_type = MLX5_FLOW_HW_FLOW_OP_TYPE_RSZ_TBL_CREATE;
-		rte_rwlock_read_lock(&table->matcher_replace_rwlk);
-		selector = table->matcher_selector;
-		ret = mlx5dr_rule_create(table->matcher_info[selector].matcher,
-					 0, items, action_template_index,
-					 rule_acts, &rule_attr,
-					 (struct mlx5dr_rule *)flow->rule);
-		rte_rwlock_read_unlock(&table->matcher_replace_rwlk);
-		aux->matcher_selector = selector;
-		flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_MATCHER_SELECTOR;
-	}
-	if (likely(!ret)) {
-		flow_hw_q_inc_flow_ops(priv, queue);
-		return (struct rte_flow *)flow;
-	}
-error:
-	if (table->resource && res_idx)
-		mlx5_ipool_free(table->resource, res_idx);
-	if (flow_idx)
-		mlx5_ipool_free(table->flow, flow_idx);
-	rte_flow_error_set(error, rte_errno,
-			   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-			   "fail to create rte flow");
-	return NULL;
+static struct rte_flow *
+flow_hw_async_flow_create_by_index_with_pattern(struct rte_eth_dev *dev,
+						uint32_t queue,
+						const struct rte_flow_op_attr *attr,
+						struct rte_flow_template_table *table,
+						uint32_t rule_index,
+						const struct rte_flow_item items[],
+						uint8_t pattern_template_index,
+						const struct rte_flow_action actions[],
+						uint8_t action_template_index,
+						void *user_data,
+						struct rte_flow_error *error)
+{
+	return flow_hw_async_flow_create_generic(dev, queue, attr, table,
+		RTE_FLOW_TABLE_INSERTION_TYPE_INDEX_WITH_PATTERN, rule_index,
+		items, pattern_template_index, actions, action_template_index,
+		user_data, error);
 }
 
 /**
@@ -16770,6 +16692,8 @@ flow_hw_async_op_validate(struct rte_eth_dev *dev,
  *   The queue to create the flow.
  * @param[in] table
  *   Pointer to template table.
+ * @param[in] rule_index
+ *   The item pattern flow follows from the table.
  * @param[in] items
  *   Items with flow spec value.
  * @param[in] pattern_template_index
@@ -16789,6 +16713,8 @@ static int
 flow_hw_async_create_validate(struct rte_eth_dev *dev,
 			      const uint32_t queue,
 			      const struct rte_flow_template_table *table,
+			      enum rte_flow_table_insertion_type insertion_type,
+			      uint32_t rule_index,
 			      const struct rte_flow_item items[],
 			      const uint8_t pattern_template_index,
 			      const struct rte_flow_action actions[],
@@ -16798,63 +16724,18 @@ flow_hw_async_create_validate(struct rte_eth_dev *dev,
 	if (flow_hw_async_op_validate(dev, queue, table, error))
 		return -rte_errno;
 
-	if (table->cfg.attr.insertion_type != RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN)
-		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "Only pattern insertion is allowed on this table");
-
-	if (flow_hw_validate_rule_pattern(dev, table, pattern_template_index, items, error))
-		return -rte_errno;
-
-	if (flow_hw_validate_rule_actions(dev, table, action_template_index, actions, error))
-		return -rte_errno;
-
-	return 0;
-}
+	if (insertion_type != table->cfg.attr.insertion_type)
+		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					  NULL, "Flow rule insertion type mismatch with table configuration");
 
-/**
- * Validate user input for rte_flow_async_create_by_index() implementation.
- *
- * If RTE_LIBRTE_MLX5_DEBUG macro is not defined, this function is a no-op.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to create the flow.
- * @param[in] table
- *   Pointer to template table.
- * @param[in] rule_index
- *   Rule index in the table.
- *   Inserting a rule to already occupied index results in undefined behavior.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 if user input is valid.
- *    Negative errno otherwise, rte_errno and error struct is set.
- */
-static int
-flow_hw_async_create_by_index_validate(struct rte_eth_dev *dev,
-				       const uint32_t queue,
-				       const struct rte_flow_template_table *table,
-				       const uint32_t rule_index,
-				       const struct rte_flow_action actions[],
-				       const uint8_t action_template_index,
-				       struct rte_flow_error *error)
-{
-	if (flow_hw_async_op_validate(dev, queue, table, error))
-		return -rte_errno;
+	if (table->cfg.attr.insertion_type != RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN)
+		if (rule_index >= table->cfg.attr.nb_flows)
+			return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						  NULL, "Flow rule index exceeds table size");
 
 	if (table->cfg.attr.insertion_type != RTE_FLOW_TABLE_INSERTION_TYPE_INDEX)
-		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "Only index insertion is allowed on this table");
-
-	if (rule_index >= table->cfg.attr.nb_flows)
-		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "Flow rule index exceeds table size");
+		if (flow_hw_validate_rule_pattern(dev, table, pattern_template_index, items, error))
+			return -rte_errno;
 
 	if (flow_hw_validate_rule_actions(dev, table, action_template_index, actions, error))
 		return -rte_errno;
@@ -16862,7 +16743,6 @@ flow_hw_async_create_by_index_validate(struct rte_eth_dev *dev,
 	return 0;
 }
 
-
 /**
  * Validate user input for rte_flow_async_update() implementation.
  *
@@ -16935,6 +16815,7 @@ flow_hw_async_destroy_validate(struct rte_eth_dev *dev,
 static struct rte_flow_fp_ops mlx5_flow_hw_fp_ops = {
 	.async_create = flow_hw_async_flow_create,
 	.async_create_by_index = flow_hw_async_flow_create_by_index,
+	.async_create_by_index_with_pattern = flow_hw_async_flow_create_by_index_with_pattern,
 	.async_actions_update = flow_hw_async_flow_update,
 	.async_destroy = flow_hw_async_flow_destroy,
 	.push = flow_hw_push,
-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 5/5] net/mlx5: implement jump to table index action
  2024-10-24 15:41 [PATCH v3 0/5] jump to table index support in mlx5 Alexander Kozyrev
                   ` (3 preceding siblings ...)
  2024-10-24 15:41 ` [PATCH v3 4/5] net/mlx5: add flow rule insertion by index with pattern Alexander Kozyrev
@ 2024-10-24 15:41 ` Alexander Kozyrev
  2024-10-24 17:50 ` [PATCH v4 0/5] jump to table index support in mlx5 Alexander Kozyrev
  5 siblings, 0 replies; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 15:41 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

Implement RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX action.
Create the hardware steering jump to matcher action,
associated with the template matcher. Use this action and
provide the rule index as an offset in the matcher.
Note that it is only supported by the isolated matcher,
i.e. the table insertion type is by index with pattern.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/nics/features/mlx5.ini             |   1 +
 doc/guides/prog_guide/ethdev/flow_offload.rst |  24 +++
 doc/guides/rel_notes/release_24_11.rst        |   1 +
 drivers/net/mlx5/mlx5_flow.h                  |   8 +-
 drivers/net/mlx5/mlx5_flow_hw.c               | 145 ++++++++++++++++++
 5 files changed, 177 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/mlx5.ini b/doc/guides/nics/features/mlx5.ini
index 056e04275b..55bc52c666 100644
--- a/doc/guides/nics/features/mlx5.ini
+++ b/doc/guides/nics/features/mlx5.ini
@@ -150,3 +150,4 @@ set_tp_src           = Y
 set_ttl              = Y
 vxlan_decap          = Y
 vxlan_encap          = Y
+jump_to_table_index  = Y
diff --git a/doc/guides/prog_guide/ethdev/flow_offload.rst b/doc/guides/prog_guide/ethdev/flow_offload.rst
index 2d6187ed11..bff0b5a794 100644
--- a/doc/guides/prog_guide/ethdev/flow_offload.rst
+++ b/doc/guides/prog_guide/ethdev/flow_offload.rst
@@ -3535,6 +3535,30 @@ Send packets to the kernel, without going to userspace at all.
 The packets will be received by the kernel driver sharing the same device
 as the DPDK port on which this action is configured.
 
+Action: ``JUMP_TO_TABLE_INDEX``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Redirects packets to a particular index in a flow table.
+
+Bypassing a hierarchy of groups, this action redirects the matched flow to
+the specified index in the particular template table on the device.
+
+If a matched flow is redirected to a non-existing template table or
+the table which doesn't contain a rule at the specified index,
+then the behavior is undefined and the resulting behavior is up to driver.
+
+.. _table_rte_flow_action_jump_to_table_index:
+
+.. table:: JUMP_TO_TABLE_INDEX
+
+   +-----------+-------------------------------------------+
+   | Field     | Value                                     |
+   +===========+===========================================+
+   | ``table`` | Template table to redirect packets to     |
+   +-----------+-------------------------------------------+
+   | ``index`` | Index in the table to redirect packets to |
+   +-----------+-------------------------------------------+
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst
index 07a8435b19..dbef29706c 100644
--- a/doc/guides/rel_notes/release_24_11.rst
+++ b/doc/guides/rel_notes/release_24_11.rst
@@ -249,6 +249,7 @@ New Features
 
 * **Updated NVIDIA MLX5 net driver.**
   * Added rte_flow_async_create_by_index_with_pattern() support.
+  * Added RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX support.
 
 Removed Items
 -------------
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index db56ae051d..90ad23c94a 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -398,6 +398,7 @@ enum mlx5_feature_name {
 #define MLX5_FLOW_ACTION_IPV6_ROUTING_REMOVE (1ull << 48)
 #define MLX5_FLOW_ACTION_IPV6_ROUTING_PUSH (1ull << 49)
 #define MLX5_FLOW_ACTION_NAT64 (1ull << 50)
+#define MLX5_FLOW_ACTION_JUMP_TO_TABLE_INDEX (1ull << 51)
 
 #define MLX5_FLOW_DROP_INCLUSIVE_ACTIONS \
 	(MLX5_FLOW_ACTION_COUNT | MLX5_FLOW_ACTION_SAMPLE | MLX5_FLOW_ACTION_AGE)
@@ -408,12 +409,14 @@ enum mlx5_feature_name {
 	 MLX5_FLOW_ACTION_DEFAULT_MISS | \
 	 MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY | \
 	 MLX5_FLOW_ACTION_SEND_TO_KERNEL | \
-	 MLX5_FLOW_ACTION_PORT_REPRESENTOR)
+	 MLX5_FLOW_ACTION_PORT_REPRESENTOR | \
+	 MLX5_FLOW_ACTION_JUMP_TO_TABLE_INDEX)
 
 #define MLX5_FLOW_FATE_ESWITCH_ACTIONS \
 	(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_PORT_ID | \
 	 MLX5_FLOW_ACTION_SEND_TO_KERNEL | \
-	 MLX5_FLOW_ACTION_JUMP | MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY)
+	 MLX5_FLOW_ACTION_JUMP | MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY | \
+	 MLX5_FLOW_ACTION_JUMP_TO_TABLE_INDEX)
 
 #define MLX5_FLOW_MODIFY_HDR_ACTIONS (MLX5_FLOW_ACTION_SET_IPV4_SRC | \
 				      MLX5_FLOW_ACTION_SET_IPV4_DST | \
@@ -1704,6 +1707,7 @@ struct mlx5_flow_template_table_cfg {
 
 struct mlx5_matcher_info {
 	struct mlx5dr_matcher *matcher; /* Template matcher. */
+	struct mlx5dr_action *jump; /* Jump to matcher action. */
 	RTE_ATOMIC(uint32_t) refcnt;
 };
 
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 412d927efb..0ef7844fd8 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -729,6 +729,9 @@ flow_hw_action_flags_get(const struct rte_flow_action actions[],
 		case MLX5_RTE_FLOW_ACTION_TYPE_DEFAULT_MISS:
 			action_flags |= MLX5_FLOW_ACTION_DEFAULT_MISS;
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+			action_flags |= MLX5_FLOW_ACTION_JUMP_TO_TABLE_INDEX;
+			break;
 		case RTE_FLOW_ACTION_TYPE_VOID:
 		case RTE_FLOW_ACTION_TYPE_END:
 			break;
@@ -2925,6 +2928,34 @@ __flow_hw_translate_actions_template(struct rte_eth_dev *dev,
 								     src_pos, dr_pos))
 				goto err;
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+			if (masks->conf &&
+			    ((const struct rte_flow_action_jump_to_table_index *)
+			     masks->conf)->table) {
+				struct rte_flow_template_table *jump_table =
+					((const struct rte_flow_action_jump_to_table_index *)
+					actions->conf)->table;
+				acts->rule_acts[dr_pos].jump_to_matcher.offset =
+					((const struct rte_flow_action_jump_to_table_index *)
+					actions->conf)->index;
+				if (likely(!rte_flow_template_table_resizable(dev->data->port_id,
+									&jump_table->cfg.attr))) {
+					acts->rule_acts[dr_pos].action =
+						jump_table->matcher_info[0].jump;
+				} else {
+					uint32_t selector;
+					rte_rwlock_read_lock(&jump_table->matcher_replace_rwlk);
+					selector = jump_table->matcher_selector;
+					acts->rule_acts[dr_pos].action =
+						jump_table->matcher_info[selector].jump;
+					rte_rwlock_read_unlock(&jump_table->matcher_replace_rwlk);
+				}
+			} else if (__flow_hw_act_data_general_append
+					(priv, acts, actions->type,
+					 src_pos, dr_pos)){
+				goto err;
+			}
+			break;
 		case RTE_FLOW_ACTION_TYPE_END:
 			actions_end = true;
 			break;
@@ -3527,6 +3558,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
 		cnt_id_t cnt_id;
 		uint32_t *cnt_queue;
 		uint32_t mtr_id;
+		struct rte_flow_template_table *jump_table;
 
 		action = &actions[act_data->action_src];
 		/*
@@ -3759,6 +3791,25 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
 			rule_acts[act_data->action_dst].action =
 				priv->action_nat64[table->type][nat64_c->type];
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+			jump_table = ((const struct rte_flow_action_jump_to_table_index *)
+						action->conf)->table;
+			if (likely(!rte_flow_template_table_resizable(dev->data->port_id,
+								      &table->cfg.attr))) {
+				rule_acts[act_data->action_dst].action =
+					jump_table->matcher_info[0].jump;
+			} else {
+				uint32_t selector;
+				rte_rwlock_read_lock(&table->matcher_replace_rwlk);
+				selector = table->matcher_selector;
+				rule_acts[act_data->action_dst].action =
+					jump_table->matcher_info[selector].jump;
+				rte_rwlock_read_unlock(&table->matcher_replace_rwlk);
+			}
+			rule_acts[act_data->action_dst].jump_to_matcher.offset =
+				((const struct rte_flow_action_jump_to_table_index *)
+				action->conf)->index;
+			break;
 		default:
 			break;
 		}
@@ -4963,6 +5014,10 @@ flow_hw_table_create(struct rte_eth_dev *dev,
 	};
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5dr_matcher_attr matcher_attr = {0};
+	struct mlx5dr_action_jump_to_matcher_attr jump_attr = {
+		.type = MLX5DR_ACTION_JUMP_TO_MATCHER_BY_INDEX,
+		.matcher = NULL,
+	};
 	struct rte_flow_template_table *tbl = NULL;
 	struct mlx5_flow_group *grp;
 	struct mlx5dr_match_template *mt[MLX5_HW_TBL_MAX_ITEM_TEMPLATE];
@@ -5153,6 +5208,13 @@ flow_hw_table_create(struct rte_eth_dev *dev,
 	tbl->type = attr->flow_attr.transfer ? MLX5DR_TABLE_TYPE_FDB :
 		    (attr->flow_attr.egress ? MLX5DR_TABLE_TYPE_NIC_TX :
 		    MLX5DR_TABLE_TYPE_NIC_RX);
+	if (matcher_attr.isolated) {
+		jump_attr.matcher = tbl->matcher_info[0].matcher;
+		tbl->matcher_info[0].jump = mlx5dr_action_create_jump_to_matcher(priv->dr_ctx,
+				&jump_attr, mlx5_hw_act_flag[!!attr->flow_attr.group][tbl->type]);
+		if (!tbl->matcher_info[0].jump)
+			goto jtm_error;
+	}
 	/*
 	 * Only the matcher supports update and needs more than 1 WQE, an additional
 	 * index is needed. Or else the flow index can be reused.
@@ -5175,6 +5237,9 @@ flow_hw_table_create(struct rte_eth_dev *dev,
 	rte_rwlock_init(&tbl->matcher_replace_rwlk);
 	return tbl;
 res_error:
+	if (tbl->matcher_info[0].jump)
+		mlx5dr_action_destroy(tbl->matcher_info[0].jump);
+jtm_error:
 	if (tbl->matcher_info[0].matcher)
 		(void)mlx5dr_matcher_destroy(tbl->matcher_info[0].matcher);
 at_error:
@@ -5439,8 +5504,12 @@ flow_hw_table_destroy(struct rte_eth_dev *dev,
 				   1, rte_memory_order_relaxed);
 	}
 	flow_hw_destroy_table_multi_pattern_ctx(table);
+	if (table->matcher_info[0].jump)
+		mlx5dr_action_destroy(table->matcher_info[0].jump);
 	if (table->matcher_info[0].matcher)
 		mlx5dr_matcher_destroy(table->matcher_info[0].matcher);
+	if (table->matcher_info[1].jump)
+		mlx5dr_action_destroy(table->matcher_info[1].jump);
 	if (table->matcher_info[1].matcher)
 		mlx5dr_matcher_destroy(table->matcher_info[1].matcher);
 	mlx5_hlist_unregister(priv->sh->groups, &table->grp->entry);
@@ -6545,6 +6614,7 @@ flow_hw_template_expand_modify_field(struct rte_flow_action actions[],
 		case RTE_FLOW_ACTION_TYPE_DROP:
 		case RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL:
 		case RTE_FLOW_ACTION_TYPE_JUMP:
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
 		case RTE_FLOW_ACTION_TYPE_QUEUE:
 		case RTE_FLOW_ACTION_TYPE_RSS:
 		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
@@ -6761,6 +6831,43 @@ flow_hw_validate_action_jump(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+mlx5_flow_validate_action_jump_to_table_index(const struct rte_flow_action *action,
+			     const struct rte_flow_action *mask,
+			     struct rte_flow_error *error)
+{
+	const struct rte_flow_action_jump_to_table_index *m = mask->conf;
+	const struct rte_flow_action_jump_to_table_index *v = action->conf;
+	struct mlx5dr_action *jump_action;
+	uint32_t t_group = 0;
+
+	if (!m || !m->table)
+		return 0;
+	if (!v)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, action,
+					  "Invalid jump to matcher action configuration");
+	t_group = v->table->grp->group_id;
+	if (t_group == 0)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, action,
+					  "Unsupported action - jump to root table");
+	if (likely(!rte_flow_template_table_resizable(0, &v->table->cfg.attr))) {
+		jump_action = v->table->matcher_info[0].jump;
+	} else {
+		uint32_t selector;
+		rte_rwlock_read_lock(&v->table->matcher_replace_rwlk);
+		selector = v->table->matcher_selector;
+		jump_action = v->table->matcher_info[selector].jump;
+		rte_rwlock_read_unlock(&v->table->matcher_replace_rwlk);
+	}
+	if (jump_action == NULL)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, action,
+					  "Unsupported action - table is not an rule array");
+	return 0;
+}
+
 static int
 mlx5_hw_validate_action_mark(struct rte_eth_dev *dev,
 			     const struct rte_flow_action *template_action,
@@ -7242,6 +7349,12 @@ mlx5_flow_hw_actions_validate(struct rte_eth_dev *dev,
 				return ret;
 			action_flags |= MLX5_FLOW_ACTION_DEFAULT_MISS;
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+			ret = mlx5_flow_validate_action_jump_to_table_index(action, mask, error);
+			if (ret < 0)
+				return ret;
+			action_flags |= MLX5_FLOW_ACTION_JUMP_TO_TABLE_INDEX;
+			break;
 		default:
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -7286,6 +7399,7 @@ static enum mlx5dr_action_type mlx5_hw_dr_action_types[] = {
 	[RTE_FLOW_ACTION_TYPE_IPV6_EXT_PUSH] = MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT,
 	[RTE_FLOW_ACTION_TYPE_IPV6_EXT_REMOVE] = MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT,
 	[RTE_FLOW_ACTION_TYPE_NAT64] = MLX5DR_ACTION_TYP_NAT64,
+	[RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX] = MLX5DR_ACTION_TYP_JUMP_TO_MATCHER,
 };
 
 static inline void
@@ -7513,6 +7627,11 @@ flow_hw_parse_flow_actions_to_dr_actions(struct rte_eth_dev *dev,
 			at->dr_off[i] = curr_off;
 			action_types[curr_off++] = MLX5DR_ACTION_TYP_MISS;
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+			*tmpl_flags |= MLX5DR_ACTION_TEMPLATE_FLAG_RELAXED_ORDER;
+			at->dr_off[i] = curr_off;
+			action_types[curr_off++] = MLX5DR_ACTION_TYP_JUMP_TO_MATCHER;
+			break;
 		default:
 			type = mlx5_hw_dr_action_types[at->actions[i].type];
 			at->dr_off[i] = curr_off;
@@ -13944,6 +14063,7 @@ mlx5_mirror_destroy_clone(struct rte_eth_dev *dev,
 	case RTE_FLOW_ACTION_TYPE_JUMP:
 		flow_hw_jump_release(dev, clone->action_ctx);
 		break;
+	case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
 	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 	case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
 	case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
@@ -13977,6 +14097,7 @@ mlx5_mirror_terminal_action(const struct rte_flow_action *action)
 	case RTE_FLOW_ACTION_TYPE_QUEUE:
 	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 	case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
+	case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
 		return true;
 	default:
 		break;
@@ -14019,6 +14140,8 @@ mlx5_mirror_validate_sample_action(struct rte_eth_dev *dev,
 		    action[1].type != RTE_FLOW_ACTION_TYPE_RAW_ENCAP)
 			return false;
 		break;
+	case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+		break;
 	default:
 		return false;
 	}
@@ -14753,8 +14876,14 @@ flow_hw_table_resize(struct rte_eth_dev *dev,
 	struct mlx5dr_action_template *at[MLX5_HW_TBL_MAX_ACTION_TEMPLATE];
 	struct mlx5dr_match_template *mt[MLX5_HW_TBL_MAX_ITEM_TEMPLATE];
 	struct mlx5dr_matcher_attr matcher_attr = table->matcher_attr;
+	struct mlx5dr_action_jump_to_matcher_attr jump_attr = {
+		.type = MLX5DR_ACTION_JUMP_TO_MATCHER_BY_INDEX,
+		.matcher = NULL,
+	};
 	struct mlx5_multi_pattern_segment *segment = NULL;
 	struct mlx5dr_matcher *matcher = NULL;
+	struct mlx5dr_action *jump = NULL;
+	struct mlx5_priv *priv = dev->data->dev_private;
 	uint32_t i, selector = table->matcher_selector;
 	uint32_t other_selector = (selector + 1) & 1;
 	int ret;
@@ -14802,6 +14931,17 @@ flow_hw_table_resize(struct rte_eth_dev *dev,
 					 table, "failed to create new matcher");
 		goto error;
 	}
+	if (matcher_attr.isolated) {
+		jump_attr.matcher = matcher;
+		jump = mlx5dr_action_create_jump_to_matcher(priv->dr_ctx, &jump_attr,
+			mlx5_hw_act_flag[!!table->cfg.attr.flow_attr.group][table->type]);
+		if (!jump) {
+			ret = rte_flow_error_set(error, rte_errno,
+						RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						table, "failed to create jump to matcher action");
+			goto error;
+		}
+	}
 	rte_rwlock_write_lock(&table->matcher_replace_rwlk);
 	ret = mlx5dr_matcher_resize_set_target
 			(table->matcher_info[selector].matcher, matcher);
@@ -14814,6 +14954,7 @@ flow_hw_table_resize(struct rte_eth_dev *dev,
 	}
 	table->cfg.attr.nb_flows = nb_flows;
 	table->matcher_info[other_selector].matcher = matcher;
+	table->matcher_info[other_selector].jump = jump;
 	table->matcher_selector = other_selector;
 	rte_atomic_store_explicit(&table->matcher_info[other_selector].refcnt,
 				  0, rte_memory_order_relaxed);
@@ -14822,6 +14963,8 @@ flow_hw_table_resize(struct rte_eth_dev *dev,
 error:
 	if (segment)
 		mlx5_destroy_multi_pattern_segment(segment);
+	if (jump)
+		mlx5dr_action_destroy(jump);
 	if (matcher) {
 		ret = mlx5dr_matcher_destroy(matcher);
 		return rte_flow_error_set(error, rte_errno,
@@ -14852,6 +14995,8 @@ flow_hw_table_resize_complete(__rte_unused struct rte_eth_dev *dev,
 		return rte_flow_error_set(error, EBUSY,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  table, "cannot complete table resize");
+	if (matcher_info->jump)
+		mlx5dr_action_destroy(matcher_info->jump);
 	ret = mlx5dr_matcher_destroy(matcher_info->matcher);
 	if (ret)
 		return rte_flow_error_set(error, rte_errno,
-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 0/5] jump to table index support in mlx5
  2024-10-24 15:41 [PATCH v3 0/5] jump to table index support in mlx5 Alexander Kozyrev
                   ` (4 preceding siblings ...)
  2024-10-24 15:41 ` [PATCH v3 5/5] net/mlx5: implement jump to table index action Alexander Kozyrev
@ 2024-10-24 17:50 ` Alexander Kozyrev
  2024-10-24 17:50   ` [PATCH v4 1/5] net/mlx5/hws: introduce new matcher type Alexander Kozyrev
                     ` (5 more replies)
  5 siblings, 6 replies; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 17:50 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

Support the new Flow API JUMP_TO_TABLE_INDEX action in mlx5.

Seried-acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>

Alexander Kozyrev (3):
  net/mlx5: create array ste matcher
  net/mlx5: add flow rule insertion by index with pattern
  net/mlx5: implement jump to table index action

Hamdan Igbaria (2):
  net/mlx5/hws: introduce new matcher type
  net/mlx5/hws: introduce jump to matcher action

 doc/guides/nics/features/default.ini          |   1 +
 doc/guides/nics/features/mlx5.ini             |   1 +
 doc/guides/prog_guide/ethdev/flow_offload.rst |  24 +
 doc/guides/rel_notes/release_24_11.rst        |   3 +
 drivers/net/mlx5/hws/mlx5dr.h                 |  42 +-
 drivers/net/mlx5/hws/mlx5dr_action.c          |  87 +++-
 drivers/net/mlx5/hws/mlx5dr_action.h          |   3 +
 drivers/net/mlx5/hws/mlx5dr_debug.c           |  13 +-
 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.h                  |   8 +-
 drivers/net/mlx5/mlx5_flow_hw.c               | 435 ++++++++++--------
 15 files changed, 520 insertions(+), 232 deletions(-)

-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 1/5] net/mlx5/hws: introduce new matcher type
  2024-10-24 17:50 ` [PATCH v4 0/5] jump to table index support in mlx5 Alexander Kozyrev
@ 2024-10-24 17:50   ` Alexander Kozyrev
  2024-10-25 13:55     ` Dariusz Sosnowski
  2024-10-24 17:50   ` [PATCH v4 2/5] net/mlx5/hws: introduce jump to matcher action Alexander Kozyrev
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 17:50 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

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(-)

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;
-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 2/5] net/mlx5/hws: introduce jump to matcher action
  2024-10-24 17:50 ` [PATCH v4 0/5] jump to table index support in mlx5 Alexander Kozyrev
  2024-10-24 17:50   ` [PATCH v4 1/5] net/mlx5/hws: introduce new matcher type Alexander Kozyrev
@ 2024-10-24 17:50   ` Alexander Kozyrev
  2024-10-25 13:55     ` Dariusz Sosnowski
  2024-10-24 17:50   ` [PATCH v4 3/5] net/mlx5: create array ste matcher Alexander Kozyrev
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 17:50 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

From: Hamdan Igbaria <hamdani@nvidia.com>

Introduce jump to matcher action, this action will allow
jumping to another matcher.
For now this jump restricted to STE array matchers and
matchers of size 1.

Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr.h        | 29 ++++++++++
 drivers/net/mlx5/hws/mlx5dr_action.c | 87 +++++++++++++++++++++++++++-
 drivers/net/mlx5/hws/mlx5dr_action.h |  3 +
 drivers/net/mlx5/hws/mlx5dr_debug.c  |  1 +
 4 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h
index 8a1a389a3f..1b58eeb2c7 100644
--- a/drivers/net/mlx5/hws/mlx5dr.h
+++ b/drivers/net/mlx5/hws/mlx5dr.h
@@ -52,6 +52,7 @@ enum mlx5dr_action_type {
 	MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT,
 	MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT,
 	MLX5DR_ACTION_TYP_NAT64,
+	MLX5DR_ACTION_TYP_JUMP_TO_MATCHER,
 	MLX5DR_ACTION_TYP_MAX,
 };
 
@@ -287,6 +288,10 @@ struct mlx5dr_rule_action {
 			uint32_t offset;
 			enum mlx5dr_action_aso_ct_flags direction;
 		} aso_ct;
+
+		struct {
+			uint32_t offset;
+		} jump_to_matcher;
 	};
 };
 
@@ -304,6 +309,15 @@ struct mlx5dr_action_dest_attr {
 	} reformat;
 };
 
+enum mlx5dr_action_jump_to_matcher_type {
+	MLX5DR_ACTION_JUMP_TO_MATCHER_BY_INDEX,
+};
+
+struct mlx5dr_action_jump_to_matcher_attr {
+	enum mlx5dr_action_jump_to_matcher_type type;
+	struct mlx5dr_matcher *matcher;
+};
+
 union mlx5dr_crc_encap_entropy_hash_ip_field {
 	uint8_t  ipv6_addr[16];
 	struct {
@@ -938,6 +952,21 @@ mlx5dr_action_create_nat64(struct mlx5dr_context *ctx,
 			   struct mlx5dr_action_nat64_attr *attr,
 			   uint32_t flags);
 
+/* Create direct rule jump to matcher action.
+ *
+ * @param[in] ctx
+ *	The context in which the new action will be created.
+ * @param[in] attr
+ *	The relevant attribute of the action.
+ * @param[in] flags
+ *	Action creation flags. (enum mlx5dr_action_flags)
+ * @return pointer to mlx5dr_action on success NULL otherwise.
+ */
+struct mlx5dr_action *
+mlx5dr_action_create_jump_to_matcher(struct mlx5dr_context *ctx,
+				     struct mlx5dr_action_jump_to_matcher_attr *attr,
+				     uint32_t flags);
+
 /* Destroy direct rule action.
  *
  * @param[in] action
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c
index 3fceb96de2..3412a96894 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.c
+++ b/drivers/net/mlx5/hws/mlx5dr_action.c
@@ -42,7 +42,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_TIR) |
 		BIT(MLX5DR_ACTION_TYP_DROP) |
 		BIT(MLX5DR_ACTION_TYP_DEST_ROOT) |
-		BIT(MLX5DR_ACTION_TYP_DEST_ARRAY),
+		BIT(MLX5DR_ACTION_TYP_DEST_ARRAY) |
+		BIT(MLX5DR_ACTION_TYP_JUMP_TO_MATCHER),
 		BIT(MLX5DR_ACTION_TYP_LAST),
 	},
 	[MLX5DR_TABLE_TYPE_NIC_TX] = {
@@ -62,7 +63,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_TBL) |
 		BIT(MLX5DR_ACTION_TYP_MISS) |
 		BIT(MLX5DR_ACTION_TYP_DROP) |
-		BIT(MLX5DR_ACTION_TYP_DEST_ROOT),
+		BIT(MLX5DR_ACTION_TYP_DEST_ROOT) |
+		BIT(MLX5DR_ACTION_TYP_JUMP_TO_MATCHER),
 		BIT(MLX5DR_ACTION_TYP_LAST),
 	},
 	[MLX5DR_TABLE_TYPE_FDB] = {
@@ -88,7 +90,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_VPORT) |
 		BIT(MLX5DR_ACTION_TYP_DROP) |
 		BIT(MLX5DR_ACTION_TYP_DEST_ROOT) |
-		BIT(MLX5DR_ACTION_TYP_DEST_ARRAY),
+		BIT(MLX5DR_ACTION_TYP_DEST_ARRAY) |
+		BIT(MLX5DR_ACTION_TYP_JUMP_TO_MATCHER),
 		BIT(MLX5DR_ACTION_TYP_LAST),
 	},
 };
@@ -1091,6 +1094,13 @@ static void mlx5dr_action_fill_stc_attr(struct mlx5dr_action *action,
 		attr->action_offset = MLX5DR_ACTION_OFFSET_DW5;
 		attr->reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS;
 		break;
+	case MLX5DR_ACTION_TYP_JUMP_TO_MATCHER:
+		attr->action_type = MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE;
+		attr->action_offset = MLX5DR_ACTION_OFFSET_HIT;
+		attr->ste_table.ste = action->jump_to_matcher.matcher->match_ste.ste;
+		attr->ste_table.ste_pool = action->jump_to_matcher.matcher->match_ste.pool;
+		attr->ste_table.match_definer_id = action->ctx->caps->trivial_match_definer;
+		break;
 	default:
 		DR_LOG(ERR, "Invalid action type %d", action->type);
 		assert(false);
@@ -3078,6 +3088,57 @@ mlx5dr_action_create_nat64(struct mlx5dr_context *ctx,
 	return NULL;
 }
 
+struct mlx5dr_action *
+mlx5dr_action_create_jump_to_matcher(struct mlx5dr_context *ctx,
+				     struct mlx5dr_action_jump_to_matcher_attr *attr,
+				     uint32_t flags)
+{
+	struct mlx5dr_matcher *matcher = attr->matcher;
+	struct mlx5dr_matcher_attr *m_attr;
+	struct mlx5dr_action *action;
+
+	if (attr->type != MLX5DR_ACTION_JUMP_TO_MATCHER_BY_INDEX) {
+		DR_LOG(ERR, "Only jump to matcher by index is supported");
+		goto enotsup;
+	}
+
+	if (mlx5dr_action_is_root_flags(flags)) {
+		DR_LOG(ERR, "Action flags must be only non root (HWS)");
+		goto enotsup;
+	}
+
+	if (mlx5dr_table_is_root(matcher->tbl)) {
+		DR_LOG(ERR, "Root matcher cannot be set as destination");
+		goto enotsup;
+	}
+
+	m_attr = &matcher->attr;
+
+	if (!(matcher->flags & MLX5DR_MATCHER_FLAGS_STE_ARRAY) &&
+	    (m_attr->resizable || m_attr->table.sz_col_log || m_attr->table.sz_row_log)) {
+		DR_LOG(ERR, "Only STE array or matcher of size 1 can be set as destination");
+		goto enotsup;
+	}
+
+	action = mlx5dr_action_create_generic(ctx, flags, MLX5DR_ACTION_TYP_JUMP_TO_MATCHER);
+	if (!action)
+		return NULL;
+
+	action->jump_to_matcher.matcher = matcher;
+
+	if (mlx5dr_action_create_stcs(action, NULL)) {
+		DR_LOG(ERR, "Failed to create action jump to matcher STC");
+		simple_free(action);
+		return NULL;
+	}
+
+	return action;
+
+enotsup:
+	rte_errno = ENOTSUP;
+	return NULL;
+}
+
 static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)
 {
 	struct mlx5dr_devx_obj *obj = NULL;
@@ -3100,6 +3161,7 @@ static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)
 	case MLX5DR_ACTION_TYP_PUSH_VLAN:
 	case MLX5DR_ACTION_TYP_REMOVE_HEADER:
 	case MLX5DR_ACTION_TYP_VPORT:
+	case MLX5DR_ACTION_TYP_JUMP_TO_MATCHER:
 		mlx5dr_action_destroy_stcs(action);
 		break;
 	case MLX5DR_ACTION_TYP_DEST_ROOT:
@@ -3618,6 +3680,19 @@ mlx5dr_action_setter_default_hit(struct mlx5dr_actions_apply_data *apply,
 		htobe32(apply->common_res->default_stc->default_hit.offset);
 }
 
+static void
+mlx5dr_action_setter_hit_matcher(struct mlx5dr_actions_apply_data *apply,
+				 struct mlx5dr_actions_wqe_setter *setter)
+{
+	struct mlx5dr_rule_action *rule_action;
+
+	rule_action = &apply->rule_action[setter->idx_hit];
+
+	apply->wqe_data[MLX5DR_ACTION_OFFSET_HIT_LSB] =
+		htobe32(rule_action->jump_to_matcher.offset << 6);
+	mlx5dr_action_apply_stc(apply, MLX5DR_ACTION_STC_IDX_HIT, setter->idx_hit);
+}
+
 static void
 mlx5dr_action_setter_hit_next_action(struct mlx5dr_actions_apply_data *apply,
 				     __rte_unused struct mlx5dr_actions_wqe_setter *setter)
@@ -3965,6 +4040,12 @@ int mlx5dr_action_template_process(struct mlx5dr_action_template *at)
 			}
 			break;
 
+		case MLX5DR_ACTION_TYP_JUMP_TO_MATCHER:
+			last_setter->flags |= ASF_HIT;
+			last_setter->set_hit = &mlx5dr_action_setter_hit_matcher;
+			last_setter->idx_hit = i;
+			break;
+
 		default:
 			DR_LOG(ERR, "Unsupported action type: %d", action_type[i]);
 			rte_errno = ENOTSUP;
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.h b/drivers/net/mlx5/hws/mlx5dr_action.h
index ba4ce55228..8ce4ecd5ba 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.h
+++ b/drivers/net/mlx5/hws/mlx5dr_action.h
@@ -223,6 +223,9 @@ struct mlx5dr_action {
 				struct {
 					struct mlx5dr_action *stages[MLX5DR_ACTION_NAT64_STAGES];
 				} nat64;
+				struct {
+					struct mlx5dr_matcher *matcher;
+				} jump_to_matcher;
 			};
 		};
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c
index f15ad96598..8684a8197a 100644
--- a/drivers/net/mlx5/hws/mlx5dr_debug.c
+++ b/drivers/net/mlx5/hws/mlx5dr_debug.c
@@ -29,6 +29,7 @@ const char *mlx5dr_debug_action_type_str[] = {
 	[MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT] = "POP_IPV6_ROUTE_EXT",
 	[MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT] = "PUSH_IPV6_ROUTE_EXT",
 	[MLX5DR_ACTION_TYP_NAT64] = "NAT64",
+	[MLX5DR_ACTION_TYP_JUMP_TO_MATCHER] = "JUMP_TO_MATCHER",
 };
 
 static_assert(ARRAY_SIZE(mlx5dr_debug_action_type_str) == MLX5DR_ACTION_TYP_MAX,
-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 3/5] net/mlx5: create array ste matcher
  2024-10-24 17:50 ` [PATCH v4 0/5] jump to table index support in mlx5 Alexander Kozyrev
  2024-10-24 17:50   ` [PATCH v4 1/5] net/mlx5/hws: introduce new matcher type Alexander Kozyrev
  2024-10-24 17:50   ` [PATCH v4 2/5] net/mlx5/hws: introduce jump to matcher action Alexander Kozyrev
@ 2024-10-24 17:50   ` Alexander Kozyrev
  2024-10-25 13:56     ` Dariusz Sosnowski
  2024-10-24 17:50   ` [PATCH v4 4/5] net/mlx5: add flow rule insertion by index with pattern Alexander Kozyrev
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 17:50 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

Create an array STE matcher for a template table
in case of insertion by index with pattern is selected.
Packets will be matched on a pattern at the index.
This table is isolated from any other tables in a group.
That means packets missed the rule won't go to a lower
priority tables, but proceed with the default miss instead.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow_hw.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index c21eb1eaed..c236831e21 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -5157,8 +5157,15 @@ 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 (matcher_attr.insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX) {
+		if (attr->insertion_type == RTE_FLOW_TABLE_INSERTION_TYPE_INDEX_WITH_PATTERN) {
+			matcher_attr.isolated = true;
+			matcher_attr.match_mode = MLX5DR_MATCHER_MATCH_MODE_DEFAULT;
+		} else {
+			matcher_attr.isolated = false;
+			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;
-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 4/5] net/mlx5: add flow rule insertion by index with pattern
  2024-10-24 17:50 ` [PATCH v4 0/5] jump to table index support in mlx5 Alexander Kozyrev
                     ` (2 preceding siblings ...)
  2024-10-24 17:50   ` [PATCH v4 3/5] net/mlx5: create array ste matcher Alexander Kozyrev
@ 2024-10-24 17:50   ` Alexander Kozyrev
  2024-10-25 13:56     ` Dariusz Sosnowski
  2024-10-24 17:50   ` [PATCH v4 5/5] net/mlx5: implement jump to table index action Alexander Kozyrev
  2024-10-30 14:23   ` [PATCH v4 0/5] jump to table index support in mlx5 Raslan Darawsheh
  5 siblings, 1 reply; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 17:50 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

Implement rte_flow_async_create_by_index_with_pattern() function.
Rework the driver implementation to reduce code duplication by
providing a single flow insertion routine, that can be called with
different parameters depending on the insertion type.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/rel_notes/release_24_11.rst |   2 +
 drivers/net/mlx5/mlx5_flow_hw.c        | 281 +++++++------------------
 2 files changed, 83 insertions(+), 200 deletions(-)

diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst
index fa4822d928..07a8435b19 100644
--- a/doc/guides/rel_notes/release_24_11.rst
+++ b/doc/guides/rel_notes/release_24_11.rst
@@ -247,6 +247,8 @@ New Features
   Added ability for node to advertise and update multiple xstat counters,
   that can be retrieved using ``rte_graph_cluster_stats_get``.
 
+* **Updated NVIDIA MLX5 net driver.**
+  * Added rte_flow_async_create_by_index_with_pattern() support.
 
 Removed Items
 -------------
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index c236831e21..412d927efb 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -335,18 +335,13 @@ static __rte_always_inline uint32_t flow_hw_tx_tag_regc_value(struct rte_eth_dev
 static int flow_hw_async_create_validate(struct rte_eth_dev *dev,
 					 const uint32_t queue,
 					 const struct rte_flow_template_table *table,
+					 enum rte_flow_table_insertion_type insertion_type,
+					 const uint32_t rule_index,
 					 const struct rte_flow_item items[],
 					 const uint8_t pattern_template_index,
 					 const struct rte_flow_action actions[],
 					 const uint8_t action_template_index,
 					 struct rte_flow_error *error);
-static int flow_hw_async_create_by_index_validate(struct rte_eth_dev *dev,
-						  const uint32_t queue,
-						  const struct rte_flow_template_table *table,
-						  const uint32_t rule_index,
-						  const struct rte_flow_action actions[],
-						  const uint8_t action_template_index,
-						  struct rte_flow_error *error);
 static int flow_hw_async_update_validate(struct rte_eth_dev *dev,
 					 const uint32_t queue,
 					 const struct rte_flow_hw *flow,
@@ -3884,6 +3879,12 @@ flow_hw_get_rule_items(struct rte_eth_dev *dev,
  *   The queue to create the flow.
  * @param[in] attr
  *   Pointer to the flow operation attributes.
+ * @param[in] table
+ *   Pointer to the template table.
+ * @param[in] insertion_type
+ *   Insertion type for flow rules.
+ * @param[in] rule_index
+ *   The item pattern flow follows from the table.
  * @param[in] items
  *   Items with flow spec value.
  * @param[in] pattern_template_index
@@ -3900,17 +3901,19 @@ flow_hw_get_rule_items(struct rte_eth_dev *dev,
  * @return
  *    Flow pointer on success, NULL otherwise and rte_errno is set.
  */
-static struct rte_flow *
-flow_hw_async_flow_create(struct rte_eth_dev *dev,
-			  uint32_t queue,
-			  const struct rte_flow_op_attr *attr,
-			  struct rte_flow_template_table *table,
-			  const struct rte_flow_item items[],
-			  uint8_t pattern_template_index,
-			  const struct rte_flow_action actions[],
-			  uint8_t action_template_index,
-			  void *user_data,
-			  struct rte_flow_error *error)
+static __rte_always_inline struct rte_flow *
+flow_hw_async_flow_create_generic(struct rte_eth_dev *dev,
+				  uint32_t queue,
+				  const struct rte_flow_op_attr *attr,
+				  struct rte_flow_template_table *table,
+				  enum rte_flow_table_insertion_type insertion_type,
+				  uint32_t rule_index,
+				  const struct rte_flow_item items[],
+				  uint8_t pattern_template_index,
+				  const struct rte_flow_action actions[],
+				  uint8_t action_template_index,
+				  void *user_data,
+				  struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5dr_rule_attr rule_attr = {
@@ -3928,8 +3931,8 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
 	int ret;
 
 	if (mlx5_fp_debug_enabled()) {
-		if (flow_hw_async_create_validate(dev, queue, table, items, pattern_template_index,
-						  actions, action_template_index, error))
+		if (flow_hw_async_create_validate(dev, queue, table, insertion_type, rule_index,
+			items, pattern_template_index, actions, action_template_index, error))
 			return NULL;
 	}
 	flow = mlx5_ipool_malloc(table->flow, &flow_idx);
@@ -3967,7 +3970,7 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
 	 * Indexed pool returns 1-based indices, but mlx5dr expects 0-based indices
 	 * for rule insertion hints.
 	 */
-	flow->rule_idx = flow->res_idx - 1;
+	flow->rule_idx = (rule_index == UINT32_MAX) ? flow->res_idx - 1 : rule_index;
 	rule_attr.rule_idx = flow->rule_idx;
 	/*
 	 * Construct the flow actions based on the input actions.
@@ -4023,33 +4026,26 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
 	return NULL;
 }
 
-/**
- * Enqueue HW steering flow creation by index.
- *
- * The flow will be applied to the HW only if the postpone bit is not set or
- * the extra push function is called.
- * The flow creation status should be checked from dequeue result.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to create the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] rule_index
- *   The item pattern flow follows from the table.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Flow pointer on success, NULL otherwise and rte_errno is set.
- */
+static struct rte_flow *
+flow_hw_async_flow_create(struct rte_eth_dev *dev,
+			  uint32_t queue,
+			  const struct rte_flow_op_attr *attr,
+			  struct rte_flow_template_table *table,
+			  const struct rte_flow_item items[],
+			  uint8_t pattern_template_index,
+			  const struct rte_flow_action actions[],
+			  uint8_t action_template_index,
+			  void *user_data,
+			  struct rte_flow_error *error)
+{
+	uint32_t rule_index = UINT32_MAX;
+
+	return flow_hw_async_flow_create_generic(dev, queue, attr, table,
+		RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN, rule_index,
+		items, pattern_template_index, actions, action_template_index,
+		user_data, error);
+}
+
 static struct rte_flow *
 flow_hw_async_flow_create_by_index(struct rte_eth_dev *dev,
 			  uint32_t queue,
@@ -4062,105 +4058,31 @@ flow_hw_async_flow_create_by_index(struct rte_eth_dev *dev,
 			  struct rte_flow_error *error)
 {
 	struct rte_flow_item items[] = {{.type = RTE_FLOW_ITEM_TYPE_END,}};
-	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5dr_rule_attr rule_attr = {
-		.queue_id = queue,
-		.user_data = user_data,
-		.burst = attr->postpone,
-	};
-	struct mlx5dr_rule_action *rule_acts;
-	struct mlx5_flow_hw_action_params ap;
-	struct rte_flow_hw *flow = NULL;
-	uint32_t flow_idx = 0;
-	uint32_t res_idx = 0;
-	int ret;
+	uint8_t pattern_template_index = 0;
 
-	if (mlx5_fp_debug_enabled()) {
-		if (flow_hw_async_create_by_index_validate(dev, queue, table, rule_index,
-							   actions, action_template_index, error))
-			return NULL;
-	}
-	flow = mlx5_ipool_malloc(table->flow, &flow_idx);
-	if (!flow) {
-		rte_errno = ENOMEM;
-		goto error;
-	}
-	rule_acts = flow_hw_get_dr_action_buffer(priv, table, action_template_index, queue);
-	/*
-	 * Set the table here in order to know the destination table
-	 * when free the flow afterwards.
-	 */
-	flow->table = table;
-	flow->mt_idx = 0;
-	flow->idx = flow_idx;
-	if (table->resource) {
-		mlx5_ipool_malloc(table->resource, &res_idx);
-		if (!res_idx) {
-			rte_errno = ENOMEM;
-			goto error;
-		}
-		flow->res_idx = res_idx;
-	} else {
-		flow->res_idx = flow_idx;
-	}
-	flow->flags = 0;
-	/*
-	 * Set the flow operation type here in order to know if the flow memory
-	 * should be freed or not when get the result from dequeue.
-	 */
-	flow->operation_type = MLX5_FLOW_HW_FLOW_OP_TYPE_CREATE;
-	flow->user_data = user_data;
-	rule_attr.user_data = flow;
-	/* Set the rule index. */
-	flow->rule_idx = rule_index;
-	rule_attr.rule_idx = flow->rule_idx;
-	/*
-	 * Construct the flow actions based on the input actions.
-	 * The implicitly appended action is always fixed, like metadata
-	 * copy action from FDB to NIC Rx.
-	 * No need to copy and contrust a new "actions" list based on the
-	 * user's input, in order to save the cost.
-	 */
-	if (flow_hw_actions_construct(dev, flow, &ap,
-				      &table->ats[action_template_index],
-				      table->its[0]->item_flags, table,
-				      actions, rule_acts, queue, error)) {
-		rte_errno = EINVAL;
-		goto error;
-	}
-	if (likely(!rte_flow_template_table_resizable(dev->data->port_id, &table->cfg.attr))) {
-		ret = mlx5dr_rule_create(table->matcher_info[0].matcher,
-					 0, items, action_template_index,
-					 rule_acts, &rule_attr,
-					 (struct mlx5dr_rule *)flow->rule);
-	} else {
-		struct rte_flow_hw_aux *aux = mlx5_flow_hw_aux(dev->data->port_id, flow);
-		uint32_t selector;
+	return flow_hw_async_flow_create_generic(dev, queue, attr, table,
+		RTE_FLOW_TABLE_INSERTION_TYPE_INDEX, rule_index,
+		items, pattern_template_index, actions, action_template_index,
+		user_data, error);
+}
 
-		flow->operation_type = MLX5_FLOW_HW_FLOW_OP_TYPE_RSZ_TBL_CREATE;
-		rte_rwlock_read_lock(&table->matcher_replace_rwlk);
-		selector = table->matcher_selector;
-		ret = mlx5dr_rule_create(table->matcher_info[selector].matcher,
-					 0, items, action_template_index,
-					 rule_acts, &rule_attr,
-					 (struct mlx5dr_rule *)flow->rule);
-		rte_rwlock_read_unlock(&table->matcher_replace_rwlk);
-		aux->matcher_selector = selector;
-		flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_MATCHER_SELECTOR;
-	}
-	if (likely(!ret)) {
-		flow_hw_q_inc_flow_ops(priv, queue);
-		return (struct rte_flow *)flow;
-	}
-error:
-	if (table->resource && res_idx)
-		mlx5_ipool_free(table->resource, res_idx);
-	if (flow_idx)
-		mlx5_ipool_free(table->flow, flow_idx);
-	rte_flow_error_set(error, rte_errno,
-			   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-			   "fail to create rte flow");
-	return NULL;
+static struct rte_flow *
+flow_hw_async_flow_create_by_index_with_pattern(struct rte_eth_dev *dev,
+						uint32_t queue,
+						const struct rte_flow_op_attr *attr,
+						struct rte_flow_template_table *table,
+						uint32_t rule_index,
+						const struct rte_flow_item items[],
+						uint8_t pattern_template_index,
+						const struct rte_flow_action actions[],
+						uint8_t action_template_index,
+						void *user_data,
+						struct rte_flow_error *error)
+{
+	return flow_hw_async_flow_create_generic(dev, queue, attr, table,
+		RTE_FLOW_TABLE_INSERTION_TYPE_INDEX_WITH_PATTERN, rule_index,
+		items, pattern_template_index, actions, action_template_index,
+		user_data, error);
 }
 
 /**
@@ -16770,6 +16692,8 @@ flow_hw_async_op_validate(struct rte_eth_dev *dev,
  *   The queue to create the flow.
  * @param[in] table
  *   Pointer to template table.
+ * @param[in] rule_index
+ *   The item pattern flow follows from the table.
  * @param[in] items
  *   Items with flow spec value.
  * @param[in] pattern_template_index
@@ -16789,6 +16713,8 @@ static int
 flow_hw_async_create_validate(struct rte_eth_dev *dev,
 			      const uint32_t queue,
 			      const struct rte_flow_template_table *table,
+			      enum rte_flow_table_insertion_type insertion_type,
+			      uint32_t rule_index,
 			      const struct rte_flow_item items[],
 			      const uint8_t pattern_template_index,
 			      const struct rte_flow_action actions[],
@@ -16798,63 +16724,18 @@ flow_hw_async_create_validate(struct rte_eth_dev *dev,
 	if (flow_hw_async_op_validate(dev, queue, table, error))
 		return -rte_errno;
 
-	if (table->cfg.attr.insertion_type != RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN)
-		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "Only pattern insertion is allowed on this table");
-
-	if (flow_hw_validate_rule_pattern(dev, table, pattern_template_index, items, error))
-		return -rte_errno;
-
-	if (flow_hw_validate_rule_actions(dev, table, action_template_index, actions, error))
-		return -rte_errno;
-
-	return 0;
-}
+	if (insertion_type != table->cfg.attr.insertion_type)
+		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					  NULL, "Flow rule insertion type mismatch with table configuration");
 
-/**
- * Validate user input for rte_flow_async_create_by_index() implementation.
- *
- * If RTE_LIBRTE_MLX5_DEBUG macro is not defined, this function is a no-op.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to create the flow.
- * @param[in] table
- *   Pointer to template table.
- * @param[in] rule_index
- *   Rule index in the table.
- *   Inserting a rule to already occupied index results in undefined behavior.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 if user input is valid.
- *    Negative errno otherwise, rte_errno and error struct is set.
- */
-static int
-flow_hw_async_create_by_index_validate(struct rte_eth_dev *dev,
-				       const uint32_t queue,
-				       const struct rte_flow_template_table *table,
-				       const uint32_t rule_index,
-				       const struct rte_flow_action actions[],
-				       const uint8_t action_template_index,
-				       struct rte_flow_error *error)
-{
-	if (flow_hw_async_op_validate(dev, queue, table, error))
-		return -rte_errno;
+	if (table->cfg.attr.insertion_type != RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN)
+		if (rule_index >= table->cfg.attr.nb_flows)
+			return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						  NULL, "Flow rule index exceeds table size");
 
 	if (table->cfg.attr.insertion_type != RTE_FLOW_TABLE_INSERTION_TYPE_INDEX)
-		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "Only index insertion is allowed on this table");
-
-	if (rule_index >= table->cfg.attr.nb_flows)
-		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "Flow rule index exceeds table size");
+		if (flow_hw_validate_rule_pattern(dev, table, pattern_template_index, items, error))
+			return -rte_errno;
 
 	if (flow_hw_validate_rule_actions(dev, table, action_template_index, actions, error))
 		return -rte_errno;
@@ -16862,7 +16743,6 @@ flow_hw_async_create_by_index_validate(struct rte_eth_dev *dev,
 	return 0;
 }
 
-
 /**
  * Validate user input for rte_flow_async_update() implementation.
  *
@@ -16935,6 +16815,7 @@ flow_hw_async_destroy_validate(struct rte_eth_dev *dev,
 static struct rte_flow_fp_ops mlx5_flow_hw_fp_ops = {
 	.async_create = flow_hw_async_flow_create,
 	.async_create_by_index = flow_hw_async_flow_create_by_index,
+	.async_create_by_index_with_pattern = flow_hw_async_flow_create_by_index_with_pattern,
 	.async_actions_update = flow_hw_async_flow_update,
 	.async_destroy = flow_hw_async_flow_destroy,
 	.push = flow_hw_push,
-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 5/5] net/mlx5: implement jump to table index action
  2024-10-24 17:50 ` [PATCH v4 0/5] jump to table index support in mlx5 Alexander Kozyrev
                     ` (3 preceding siblings ...)
  2024-10-24 17:50   ` [PATCH v4 4/5] net/mlx5: add flow rule insertion by index with pattern Alexander Kozyrev
@ 2024-10-24 17:50   ` Alexander Kozyrev
  2024-10-25 13:56     ` Dariusz Sosnowski
  2024-10-30 14:23   ` [PATCH v4 0/5] jump to table index support in mlx5 Raslan Darawsheh
  5 siblings, 1 reply; 18+ messages in thread
From: Alexander Kozyrev @ 2024-10-24 17:50 UTC (permalink / raw)
  To: dev
  Cc: rasland, viacheslavo, matan, hamdani, valex, dsosnowski, orika,
	bingz, suanmingm

Implement RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX action.
Create the hardware steering jump to matcher action,
associated with the template matcher. Use this action and
provide the rule index as an offset in the matcher.
Note that it is only supported by the isolated matcher,
i.e. the table insertion type is by index with pattern.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/nics/features/default.ini          |   1 +
 doc/guides/nics/features/mlx5.ini             |   1 +
 doc/guides/prog_guide/ethdev/flow_offload.rst |  24 +++
 doc/guides/rel_notes/release_24_11.rst        |   1 +
 drivers/net/mlx5/mlx5_flow.h                  |   8 +-
 drivers/net/mlx5/mlx5_flow_hw.c               | 145 ++++++++++++++++++
 6 files changed, 178 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
index 1e9a156a2a..a730365a16 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -221,3 +221,4 @@ skip_cman            =
 vf                   =
 vxlan_decap          =
 vxlan_encap          =
+jump_to_table_index  =
diff --git a/doc/guides/nics/features/mlx5.ini b/doc/guides/nics/features/mlx5.ini
index 056e04275b..55bc52c666 100644
--- a/doc/guides/nics/features/mlx5.ini
+++ b/doc/guides/nics/features/mlx5.ini
@@ -150,3 +150,4 @@ set_tp_src           = Y
 set_ttl              = Y
 vxlan_decap          = Y
 vxlan_encap          = Y
+jump_to_table_index  = Y
diff --git a/doc/guides/prog_guide/ethdev/flow_offload.rst b/doc/guides/prog_guide/ethdev/flow_offload.rst
index 2d6187ed11..bff0b5a794 100644
--- a/doc/guides/prog_guide/ethdev/flow_offload.rst
+++ b/doc/guides/prog_guide/ethdev/flow_offload.rst
@@ -3535,6 +3535,30 @@ Send packets to the kernel, without going to userspace at all.
 The packets will be received by the kernel driver sharing the same device
 as the DPDK port on which this action is configured.
 
+Action: ``JUMP_TO_TABLE_INDEX``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Redirects packets to a particular index in a flow table.
+
+Bypassing a hierarchy of groups, this action redirects the matched flow to
+the specified index in the particular template table on the device.
+
+If a matched flow is redirected to a non-existing template table or
+the table which doesn't contain a rule at the specified index,
+then the behavior is undefined and the resulting behavior is up to driver.
+
+.. _table_rte_flow_action_jump_to_table_index:
+
+.. table:: JUMP_TO_TABLE_INDEX
+
+   +-----------+-------------------------------------------+
+   | Field     | Value                                     |
+   +===========+===========================================+
+   | ``table`` | Template table to redirect packets to     |
+   +-----------+-------------------------------------------+
+   | ``index`` | Index in the table to redirect packets to |
+   +-----------+-------------------------------------------+
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst
index 07a8435b19..dbef29706c 100644
--- a/doc/guides/rel_notes/release_24_11.rst
+++ b/doc/guides/rel_notes/release_24_11.rst
@@ -249,6 +249,7 @@ New Features
 
 * **Updated NVIDIA MLX5 net driver.**
   * Added rte_flow_async_create_by_index_with_pattern() support.
+  * Added RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX support.
 
 Removed Items
 -------------
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index db56ae051d..90ad23c94a 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -398,6 +398,7 @@ enum mlx5_feature_name {
 #define MLX5_FLOW_ACTION_IPV6_ROUTING_REMOVE (1ull << 48)
 #define MLX5_FLOW_ACTION_IPV6_ROUTING_PUSH (1ull << 49)
 #define MLX5_FLOW_ACTION_NAT64 (1ull << 50)
+#define MLX5_FLOW_ACTION_JUMP_TO_TABLE_INDEX (1ull << 51)
 
 #define MLX5_FLOW_DROP_INCLUSIVE_ACTIONS \
 	(MLX5_FLOW_ACTION_COUNT | MLX5_FLOW_ACTION_SAMPLE | MLX5_FLOW_ACTION_AGE)
@@ -408,12 +409,14 @@ enum mlx5_feature_name {
 	 MLX5_FLOW_ACTION_DEFAULT_MISS | \
 	 MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY | \
 	 MLX5_FLOW_ACTION_SEND_TO_KERNEL | \
-	 MLX5_FLOW_ACTION_PORT_REPRESENTOR)
+	 MLX5_FLOW_ACTION_PORT_REPRESENTOR | \
+	 MLX5_FLOW_ACTION_JUMP_TO_TABLE_INDEX)
 
 #define MLX5_FLOW_FATE_ESWITCH_ACTIONS \
 	(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_PORT_ID | \
 	 MLX5_FLOW_ACTION_SEND_TO_KERNEL | \
-	 MLX5_FLOW_ACTION_JUMP | MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY)
+	 MLX5_FLOW_ACTION_JUMP | MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY | \
+	 MLX5_FLOW_ACTION_JUMP_TO_TABLE_INDEX)
 
 #define MLX5_FLOW_MODIFY_HDR_ACTIONS (MLX5_FLOW_ACTION_SET_IPV4_SRC | \
 				      MLX5_FLOW_ACTION_SET_IPV4_DST | \
@@ -1704,6 +1707,7 @@ struct mlx5_flow_template_table_cfg {
 
 struct mlx5_matcher_info {
 	struct mlx5dr_matcher *matcher; /* Template matcher. */
+	struct mlx5dr_action *jump; /* Jump to matcher action. */
 	RTE_ATOMIC(uint32_t) refcnt;
 };
 
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 412d927efb..0ef7844fd8 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -729,6 +729,9 @@ flow_hw_action_flags_get(const struct rte_flow_action actions[],
 		case MLX5_RTE_FLOW_ACTION_TYPE_DEFAULT_MISS:
 			action_flags |= MLX5_FLOW_ACTION_DEFAULT_MISS;
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+			action_flags |= MLX5_FLOW_ACTION_JUMP_TO_TABLE_INDEX;
+			break;
 		case RTE_FLOW_ACTION_TYPE_VOID:
 		case RTE_FLOW_ACTION_TYPE_END:
 			break;
@@ -2925,6 +2928,34 @@ __flow_hw_translate_actions_template(struct rte_eth_dev *dev,
 								     src_pos, dr_pos))
 				goto err;
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+			if (masks->conf &&
+			    ((const struct rte_flow_action_jump_to_table_index *)
+			     masks->conf)->table) {
+				struct rte_flow_template_table *jump_table =
+					((const struct rte_flow_action_jump_to_table_index *)
+					actions->conf)->table;
+				acts->rule_acts[dr_pos].jump_to_matcher.offset =
+					((const struct rte_flow_action_jump_to_table_index *)
+					actions->conf)->index;
+				if (likely(!rte_flow_template_table_resizable(dev->data->port_id,
+									&jump_table->cfg.attr))) {
+					acts->rule_acts[dr_pos].action =
+						jump_table->matcher_info[0].jump;
+				} else {
+					uint32_t selector;
+					rte_rwlock_read_lock(&jump_table->matcher_replace_rwlk);
+					selector = jump_table->matcher_selector;
+					acts->rule_acts[dr_pos].action =
+						jump_table->matcher_info[selector].jump;
+					rte_rwlock_read_unlock(&jump_table->matcher_replace_rwlk);
+				}
+			} else if (__flow_hw_act_data_general_append
+					(priv, acts, actions->type,
+					 src_pos, dr_pos)){
+				goto err;
+			}
+			break;
 		case RTE_FLOW_ACTION_TYPE_END:
 			actions_end = true;
 			break;
@@ -3527,6 +3558,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
 		cnt_id_t cnt_id;
 		uint32_t *cnt_queue;
 		uint32_t mtr_id;
+		struct rte_flow_template_table *jump_table;
 
 		action = &actions[act_data->action_src];
 		/*
@@ -3759,6 +3791,25 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
 			rule_acts[act_data->action_dst].action =
 				priv->action_nat64[table->type][nat64_c->type];
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+			jump_table = ((const struct rte_flow_action_jump_to_table_index *)
+						action->conf)->table;
+			if (likely(!rte_flow_template_table_resizable(dev->data->port_id,
+								      &table->cfg.attr))) {
+				rule_acts[act_data->action_dst].action =
+					jump_table->matcher_info[0].jump;
+			} else {
+				uint32_t selector;
+				rte_rwlock_read_lock(&table->matcher_replace_rwlk);
+				selector = table->matcher_selector;
+				rule_acts[act_data->action_dst].action =
+					jump_table->matcher_info[selector].jump;
+				rte_rwlock_read_unlock(&table->matcher_replace_rwlk);
+			}
+			rule_acts[act_data->action_dst].jump_to_matcher.offset =
+				((const struct rte_flow_action_jump_to_table_index *)
+				action->conf)->index;
+			break;
 		default:
 			break;
 		}
@@ -4963,6 +5014,10 @@ flow_hw_table_create(struct rte_eth_dev *dev,
 	};
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5dr_matcher_attr matcher_attr = {0};
+	struct mlx5dr_action_jump_to_matcher_attr jump_attr = {
+		.type = MLX5DR_ACTION_JUMP_TO_MATCHER_BY_INDEX,
+		.matcher = NULL,
+	};
 	struct rte_flow_template_table *tbl = NULL;
 	struct mlx5_flow_group *grp;
 	struct mlx5dr_match_template *mt[MLX5_HW_TBL_MAX_ITEM_TEMPLATE];
@@ -5153,6 +5208,13 @@ flow_hw_table_create(struct rte_eth_dev *dev,
 	tbl->type = attr->flow_attr.transfer ? MLX5DR_TABLE_TYPE_FDB :
 		    (attr->flow_attr.egress ? MLX5DR_TABLE_TYPE_NIC_TX :
 		    MLX5DR_TABLE_TYPE_NIC_RX);
+	if (matcher_attr.isolated) {
+		jump_attr.matcher = tbl->matcher_info[0].matcher;
+		tbl->matcher_info[0].jump = mlx5dr_action_create_jump_to_matcher(priv->dr_ctx,
+				&jump_attr, mlx5_hw_act_flag[!!attr->flow_attr.group][tbl->type]);
+		if (!tbl->matcher_info[0].jump)
+			goto jtm_error;
+	}
 	/*
 	 * Only the matcher supports update and needs more than 1 WQE, an additional
 	 * index is needed. Or else the flow index can be reused.
@@ -5175,6 +5237,9 @@ flow_hw_table_create(struct rte_eth_dev *dev,
 	rte_rwlock_init(&tbl->matcher_replace_rwlk);
 	return tbl;
 res_error:
+	if (tbl->matcher_info[0].jump)
+		mlx5dr_action_destroy(tbl->matcher_info[0].jump);
+jtm_error:
 	if (tbl->matcher_info[0].matcher)
 		(void)mlx5dr_matcher_destroy(tbl->matcher_info[0].matcher);
 at_error:
@@ -5439,8 +5504,12 @@ flow_hw_table_destroy(struct rte_eth_dev *dev,
 				   1, rte_memory_order_relaxed);
 	}
 	flow_hw_destroy_table_multi_pattern_ctx(table);
+	if (table->matcher_info[0].jump)
+		mlx5dr_action_destroy(table->matcher_info[0].jump);
 	if (table->matcher_info[0].matcher)
 		mlx5dr_matcher_destroy(table->matcher_info[0].matcher);
+	if (table->matcher_info[1].jump)
+		mlx5dr_action_destroy(table->matcher_info[1].jump);
 	if (table->matcher_info[1].matcher)
 		mlx5dr_matcher_destroy(table->matcher_info[1].matcher);
 	mlx5_hlist_unregister(priv->sh->groups, &table->grp->entry);
@@ -6545,6 +6614,7 @@ flow_hw_template_expand_modify_field(struct rte_flow_action actions[],
 		case RTE_FLOW_ACTION_TYPE_DROP:
 		case RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL:
 		case RTE_FLOW_ACTION_TYPE_JUMP:
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
 		case RTE_FLOW_ACTION_TYPE_QUEUE:
 		case RTE_FLOW_ACTION_TYPE_RSS:
 		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
@@ -6761,6 +6831,43 @@ flow_hw_validate_action_jump(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+mlx5_flow_validate_action_jump_to_table_index(const struct rte_flow_action *action,
+			     const struct rte_flow_action *mask,
+			     struct rte_flow_error *error)
+{
+	const struct rte_flow_action_jump_to_table_index *m = mask->conf;
+	const struct rte_flow_action_jump_to_table_index *v = action->conf;
+	struct mlx5dr_action *jump_action;
+	uint32_t t_group = 0;
+
+	if (!m || !m->table)
+		return 0;
+	if (!v)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, action,
+					  "Invalid jump to matcher action configuration");
+	t_group = v->table->grp->group_id;
+	if (t_group == 0)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, action,
+					  "Unsupported action - jump to root table");
+	if (likely(!rte_flow_template_table_resizable(0, &v->table->cfg.attr))) {
+		jump_action = v->table->matcher_info[0].jump;
+	} else {
+		uint32_t selector;
+		rte_rwlock_read_lock(&v->table->matcher_replace_rwlk);
+		selector = v->table->matcher_selector;
+		jump_action = v->table->matcher_info[selector].jump;
+		rte_rwlock_read_unlock(&v->table->matcher_replace_rwlk);
+	}
+	if (jump_action == NULL)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, action,
+					  "Unsupported action - table is not an rule array");
+	return 0;
+}
+
 static int
 mlx5_hw_validate_action_mark(struct rte_eth_dev *dev,
 			     const struct rte_flow_action *template_action,
@@ -7242,6 +7349,12 @@ mlx5_flow_hw_actions_validate(struct rte_eth_dev *dev,
 				return ret;
 			action_flags |= MLX5_FLOW_ACTION_DEFAULT_MISS;
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+			ret = mlx5_flow_validate_action_jump_to_table_index(action, mask, error);
+			if (ret < 0)
+				return ret;
+			action_flags |= MLX5_FLOW_ACTION_JUMP_TO_TABLE_INDEX;
+			break;
 		default:
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -7286,6 +7399,7 @@ static enum mlx5dr_action_type mlx5_hw_dr_action_types[] = {
 	[RTE_FLOW_ACTION_TYPE_IPV6_EXT_PUSH] = MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT,
 	[RTE_FLOW_ACTION_TYPE_IPV6_EXT_REMOVE] = MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT,
 	[RTE_FLOW_ACTION_TYPE_NAT64] = MLX5DR_ACTION_TYP_NAT64,
+	[RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX] = MLX5DR_ACTION_TYP_JUMP_TO_MATCHER,
 };
 
 static inline void
@@ -7513,6 +7627,11 @@ flow_hw_parse_flow_actions_to_dr_actions(struct rte_eth_dev *dev,
 			at->dr_off[i] = curr_off;
 			action_types[curr_off++] = MLX5DR_ACTION_TYP_MISS;
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+			*tmpl_flags |= MLX5DR_ACTION_TEMPLATE_FLAG_RELAXED_ORDER;
+			at->dr_off[i] = curr_off;
+			action_types[curr_off++] = MLX5DR_ACTION_TYP_JUMP_TO_MATCHER;
+			break;
 		default:
 			type = mlx5_hw_dr_action_types[at->actions[i].type];
 			at->dr_off[i] = curr_off;
@@ -13944,6 +14063,7 @@ mlx5_mirror_destroy_clone(struct rte_eth_dev *dev,
 	case RTE_FLOW_ACTION_TYPE_JUMP:
 		flow_hw_jump_release(dev, clone->action_ctx);
 		break;
+	case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
 	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 	case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
 	case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
@@ -13977,6 +14097,7 @@ mlx5_mirror_terminal_action(const struct rte_flow_action *action)
 	case RTE_FLOW_ACTION_TYPE_QUEUE:
 	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 	case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
+	case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
 		return true;
 	default:
 		break;
@@ -14019,6 +14140,8 @@ mlx5_mirror_validate_sample_action(struct rte_eth_dev *dev,
 		    action[1].type != RTE_FLOW_ACTION_TYPE_RAW_ENCAP)
 			return false;
 		break;
+	case RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX:
+		break;
 	default:
 		return false;
 	}
@@ -14753,8 +14876,14 @@ flow_hw_table_resize(struct rte_eth_dev *dev,
 	struct mlx5dr_action_template *at[MLX5_HW_TBL_MAX_ACTION_TEMPLATE];
 	struct mlx5dr_match_template *mt[MLX5_HW_TBL_MAX_ITEM_TEMPLATE];
 	struct mlx5dr_matcher_attr matcher_attr = table->matcher_attr;
+	struct mlx5dr_action_jump_to_matcher_attr jump_attr = {
+		.type = MLX5DR_ACTION_JUMP_TO_MATCHER_BY_INDEX,
+		.matcher = NULL,
+	};
 	struct mlx5_multi_pattern_segment *segment = NULL;
 	struct mlx5dr_matcher *matcher = NULL;
+	struct mlx5dr_action *jump = NULL;
+	struct mlx5_priv *priv = dev->data->dev_private;
 	uint32_t i, selector = table->matcher_selector;
 	uint32_t other_selector = (selector + 1) & 1;
 	int ret;
@@ -14802,6 +14931,17 @@ flow_hw_table_resize(struct rte_eth_dev *dev,
 					 table, "failed to create new matcher");
 		goto error;
 	}
+	if (matcher_attr.isolated) {
+		jump_attr.matcher = matcher;
+		jump = mlx5dr_action_create_jump_to_matcher(priv->dr_ctx, &jump_attr,
+			mlx5_hw_act_flag[!!table->cfg.attr.flow_attr.group][table->type]);
+		if (!jump) {
+			ret = rte_flow_error_set(error, rte_errno,
+						RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						table, "failed to create jump to matcher action");
+			goto error;
+		}
+	}
 	rte_rwlock_write_lock(&table->matcher_replace_rwlk);
 	ret = mlx5dr_matcher_resize_set_target
 			(table->matcher_info[selector].matcher, matcher);
@@ -14814,6 +14954,7 @@ flow_hw_table_resize(struct rte_eth_dev *dev,
 	}
 	table->cfg.attr.nb_flows = nb_flows;
 	table->matcher_info[other_selector].matcher = matcher;
+	table->matcher_info[other_selector].jump = jump;
 	table->matcher_selector = other_selector;
 	rte_atomic_store_explicit(&table->matcher_info[other_selector].refcnt,
 				  0, rte_memory_order_relaxed);
@@ -14822,6 +14963,8 @@ flow_hw_table_resize(struct rte_eth_dev *dev,
 error:
 	if (segment)
 		mlx5_destroy_multi_pattern_segment(segment);
+	if (jump)
+		mlx5dr_action_destroy(jump);
 	if (matcher) {
 		ret = mlx5dr_matcher_destroy(matcher);
 		return rte_flow_error_set(error, rte_errno,
@@ -14852,6 +14995,8 @@ flow_hw_table_resize_complete(__rte_unused struct rte_eth_dev *dev,
 		return rte_flow_error_set(error, EBUSY,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  table, "cannot complete table resize");
+	if (matcher_info->jump)
+		mlx5dr_action_destroy(matcher_info->jump);
 	ret = mlx5dr_matcher_destroy(matcher_info->matcher);
 	if (ret)
 		return rte_flow_error_set(error, rte_errno,
-- 
2.43.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH v4 1/5] net/mlx5/hws: introduce new matcher type
  2024-10-24 17:50   ` [PATCH v4 1/5] net/mlx5/hws: introduce new matcher type Alexander Kozyrev
@ 2024-10-25 13:55     ` Dariusz Sosnowski
  0 siblings, 0 replies; 18+ messages in thread
From: Dariusz Sosnowski @ 2024-10-25 13:55 UTC (permalink / raw)
  To: Alexander Kozyrev, dev
  Cc: Raslan Darawsheh, Slava Ovsiienko, Matan Azrad, Hamdan Agbariya,
	Alex Vesker, Ori Kam, Bing Zhao, Suanming Mou



> -----Original Message-----
> From: Alexander Kozyrev <akozyrev@nvidia.com>
> Sent: Thursday, October 24, 2024 19:50
> To: dev@dpdk.org
> Cc: Raslan Darawsheh <rasland@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Matan Azrad <matan@nvidia.com>; Hamdan
> Agbariya <hamdani@nvidia.com>; Alex Vesker <valex@nvidia.com>; Dariusz
> Sosnowski <dsosnowski@nvidia.com>; Ori Kam <orika@nvidia.com>; Bing Zhao
> <bingz@nvidia.com>; Suanming Mou <suanmingm@nvidia.com>
> Subject: [PATCH v4 1/5] net/mlx5/hws: introduce new matcher type
> 
> 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>

Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>

Best regards,
Dariusz Sosnowski

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH v4 2/5] net/mlx5/hws: introduce jump to matcher action
  2024-10-24 17:50   ` [PATCH v4 2/5] net/mlx5/hws: introduce jump to matcher action Alexander Kozyrev
@ 2024-10-25 13:55     ` Dariusz Sosnowski
  0 siblings, 0 replies; 18+ messages in thread
From: Dariusz Sosnowski @ 2024-10-25 13:55 UTC (permalink / raw)
  To: Alexander Kozyrev, dev
  Cc: Raslan Darawsheh, Slava Ovsiienko, Matan Azrad, Hamdan Agbariya,
	Alex Vesker, Ori Kam, Bing Zhao, Suanming Mou



> -----Original Message-----
> From: Alexander Kozyrev <akozyrev@nvidia.com>
> Sent: Thursday, October 24, 2024 19:50
> To: dev@dpdk.org
> Cc: Raslan Darawsheh <rasland@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Matan Azrad <matan@nvidia.com>; Hamdan
> Agbariya <hamdani@nvidia.com>; Alex Vesker <valex@nvidia.com>; Dariusz
> Sosnowski <dsosnowski@nvidia.com>; Ori Kam <orika@nvidia.com>; Bing Zhao
> <bingz@nvidia.com>; Suanming Mou <suanmingm@nvidia.com>
> Subject: [PATCH v4 2/5] net/mlx5/hws: introduce jump to matcher action
> 
> From: Hamdan Igbaria <hamdani@nvidia.com>
> 
> Introduce jump to matcher action, this action will allow jumping to another
> matcher.
> For now this jump restricted to STE array matchers and matchers of size 1.
> 
> Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com>

Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>

Best regards,
Dariusz Sosnowski

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH v4 3/5] net/mlx5: create array ste matcher
  2024-10-24 17:50   ` [PATCH v4 3/5] net/mlx5: create array ste matcher Alexander Kozyrev
@ 2024-10-25 13:56     ` Dariusz Sosnowski
  0 siblings, 0 replies; 18+ messages in thread
From: Dariusz Sosnowski @ 2024-10-25 13:56 UTC (permalink / raw)
  To: Alexander Kozyrev, dev
  Cc: Raslan Darawsheh, Slava Ovsiienko, Matan Azrad, Hamdan Agbariya,
	Alex Vesker, Ori Kam, Bing Zhao, Suanming Mou



> -----Original Message-----
> From: Alexander Kozyrev <akozyrev@nvidia.com>
> Sent: Thursday, October 24, 2024 19:50
> To: dev@dpdk.org
> Cc: Raslan Darawsheh <rasland@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Matan Azrad <matan@nvidia.com>; Hamdan
> Agbariya <hamdani@nvidia.com>; Alex Vesker <valex@nvidia.com>; Dariusz
> Sosnowski <dsosnowski@nvidia.com>; Ori Kam <orika@nvidia.com>; Bing Zhao
> <bingz@nvidia.com>; Suanming Mou <suanmingm@nvidia.com>
> Subject: [PATCH v4 3/5] net/mlx5: create array ste matcher
> 
> Create an array STE matcher for a template table in case of insertion by index
> with pattern is selected.
> Packets will be matched on a pattern at the index.
> This table is isolated from any other tables in a group.
> That means packets missed the rule won't go to a lower priority tables, but
> proceed with the default miss instead.
> 
> Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>

Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>

Best regards,
Dariusz Sosnowski

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH v4 4/5] net/mlx5: add flow rule insertion by index with pattern
  2024-10-24 17:50   ` [PATCH v4 4/5] net/mlx5: add flow rule insertion by index with pattern Alexander Kozyrev
@ 2024-10-25 13:56     ` Dariusz Sosnowski
  0 siblings, 0 replies; 18+ messages in thread
From: Dariusz Sosnowski @ 2024-10-25 13:56 UTC (permalink / raw)
  To: Alexander Kozyrev, dev
  Cc: Raslan Darawsheh, Slava Ovsiienko, Matan Azrad, Hamdan Agbariya,
	Alex Vesker, Ori Kam, Bing Zhao, Suanming Mou



> -----Original Message-----
> From: Alexander Kozyrev <akozyrev@nvidia.com>
> Sent: Thursday, October 24, 2024 19:50
> To: dev@dpdk.org
> Cc: Raslan Darawsheh <rasland@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Matan Azrad <matan@nvidia.com>; Hamdan
> Agbariya <hamdani@nvidia.com>; Alex Vesker <valex@nvidia.com>; Dariusz
> Sosnowski <dsosnowski@nvidia.com>; Ori Kam <orika@nvidia.com>; Bing Zhao
> <bingz@nvidia.com>; Suanming Mou <suanmingm@nvidia.com>
> Subject: [PATCH v4 4/5] net/mlx5: add flow rule insertion by index with pattern
> 
> Implement rte_flow_async_create_by_index_with_pattern() function.
> Rework the driver implementation to reduce code duplication by providing a
> single flow insertion routine, that can be called with different parameters
> depending on the insertion type.
> 
> Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>

Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>

Best regards,
Dariusz Sosnowski

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH v4 5/5] net/mlx5: implement jump to table index action
  2024-10-24 17:50   ` [PATCH v4 5/5] net/mlx5: implement jump to table index action Alexander Kozyrev
@ 2024-10-25 13:56     ` Dariusz Sosnowski
  0 siblings, 0 replies; 18+ messages in thread
From: Dariusz Sosnowski @ 2024-10-25 13:56 UTC (permalink / raw)
  To: Alexander Kozyrev, dev
  Cc: Raslan Darawsheh, Slava Ovsiienko, Matan Azrad, Hamdan Agbariya,
	Alex Vesker, Ori Kam, Bing Zhao, Suanming Mou



> -----Original Message-----
> From: Alexander Kozyrev <akozyrev@nvidia.com>
> Sent: Thursday, October 24, 2024 19:50
> To: dev@dpdk.org
> Cc: Raslan Darawsheh <rasland@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Matan Azrad <matan@nvidia.com>; Hamdan
> Agbariya <hamdani@nvidia.com>; Alex Vesker <valex@nvidia.com>; Dariusz
> Sosnowski <dsosnowski@nvidia.com>; Ori Kam <orika@nvidia.com>; Bing Zhao
> <bingz@nvidia.com>; Suanming Mou <suanmingm@nvidia.com>
> Subject: [PATCH v4 5/5] net/mlx5: implement jump to table index action
> 
> Implement RTE_FLOW_ACTION_TYPE_JUMP_TO_TABLE_INDEX action.
> Create the hardware steering jump to matcher action, associated with the
> template matcher. Use this action and provide the rule index as an offset in the
> matcher.
> Note that it is only supported by the isolated matcher, i.e. the table insertion type
> is by index with pattern.
> 
> Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>

Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>

Best regards,
Dariusz Sosnowski

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v4 0/5] jump to table index support in mlx5
  2024-10-24 17:50 ` [PATCH v4 0/5] jump to table index support in mlx5 Alexander Kozyrev
                     ` (4 preceding siblings ...)
  2024-10-24 17:50   ` [PATCH v4 5/5] net/mlx5: implement jump to table index action Alexander Kozyrev
@ 2024-10-30 14:23   ` Raslan Darawsheh
  5 siblings, 0 replies; 18+ messages in thread
From: Raslan Darawsheh @ 2024-10-30 14:23 UTC (permalink / raw)
  To: Alexander Kozyrev, dev
  Cc: Slava Ovsiienko, Matan Azrad, Hamdan Agbariya, Alex Vesker,
	Dariusz Sosnowski, Ori Kam, Bing Zhao, Suanming Mou

Hi,

From: Alexander Kozyrev <akozyrev@nvidia.com>
Sent: Thursday, October 24, 2024 8:50 PM
To: dev@dpdk.org
Cc: Raslan Darawsheh; Slava Ovsiienko; Matan Azrad; Hamdan Agbariya; Alex Vesker; Dariusz Sosnowski; Ori Kam; Bing Zhao; Suanming Mou
Subject: [PATCH v4 0/5] jump to table index support in mlx5

Support the new Flow API JUMP_TO_TABLE_INDEX action in mlx5.

Seried-acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>

Alexander Kozyrev (3):
  net/mlx5: create array ste matcher
  net/mlx5: add flow rule insertion by index with pattern
  net/mlx5: implement jump to table index action

Hamdan Igbaria (2):
  net/mlx5/hws: introduce new matcher type
  net/mlx5/hws: introduce jump to matcher action

 doc/guides/nics/features/default.ini          |   1 +
 doc/guides/nics/features/mlx5.ini             |   1 +
 doc/guides/prog_guide/ethdev/flow_offload.rst |  24 +
 doc/guides/rel_notes/release_24_11.rst        |   3 +
 drivers/net/mlx5/hws/mlx5dr.h                 |  42 +-
 drivers/net/mlx5/hws/mlx5dr_action.c          |  87 +++-
 drivers/net/mlx5/hws/mlx5dr_action.h          |   3 +
 drivers/net/mlx5/hws/mlx5dr_debug.c           |  13 +-
 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.h                  |   8 +-
 drivers/net/mlx5/mlx5_flow_hw.c               | 435 ++++++++++--------
 15 files changed, 520 insertions(+), 232 deletions(-)

--
2.43.5

series applied to next-net-mlx,

Kindest regards,
Raslan Darawsheh

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2024-10-30 14:24 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-24 15:41 [PATCH v3 0/5] jump to table index support in mlx5 Alexander Kozyrev
2024-10-24 15:41 ` [PATCH v3 1/5] net/mlx5/hws: introduce new matcher type Alexander Kozyrev
2024-10-24 15:41 ` [PATCH v3 2/5] net/mlx5/hws: introduce jump to matcher action Alexander Kozyrev
2024-10-24 15:41 ` [PATCH v3 3/5] net/mlx5: create array ste matcher Alexander Kozyrev
2024-10-24 15:41 ` [PATCH v3 4/5] net/mlx5: add flow rule insertion by index with pattern Alexander Kozyrev
2024-10-24 15:41 ` [PATCH v3 5/5] net/mlx5: implement jump to table index action Alexander Kozyrev
2024-10-24 17:50 ` [PATCH v4 0/5] jump to table index support in mlx5 Alexander Kozyrev
2024-10-24 17:50   ` [PATCH v4 1/5] net/mlx5/hws: introduce new matcher type Alexander Kozyrev
2024-10-25 13:55     ` Dariusz Sosnowski
2024-10-24 17:50   ` [PATCH v4 2/5] net/mlx5/hws: introduce jump to matcher action Alexander Kozyrev
2024-10-25 13:55     ` Dariusz Sosnowski
2024-10-24 17:50   ` [PATCH v4 3/5] net/mlx5: create array ste matcher Alexander Kozyrev
2024-10-25 13:56     ` Dariusz Sosnowski
2024-10-24 17:50   ` [PATCH v4 4/5] net/mlx5: add flow rule insertion by index with pattern Alexander Kozyrev
2024-10-25 13:56     ` Dariusz Sosnowski
2024-10-24 17:50   ` [PATCH v4 5/5] net/mlx5: implement jump to table index action Alexander Kozyrev
2024-10-25 13:56     ` Dariusz Sosnowski
2024-10-30 14:23   ` [PATCH v4 0/5] jump to table index support in mlx5 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).