DPDK patches and discussions
 help / color / mirror / Atom feed
From: Erez Shitrit <erezsh@nvidia.com>
To: <dev@dpdk.org>
Cc: <valex@nvidia.com>, <rasland@nvidia.com>,
	Matan Azrad <matan@nvidia.com>,
	 Viacheslav Ovsiienko <viacheslavo@nvidia.com>
Subject: [PATCH v2 08/10] net/mlx5/hws: support shared ibv-context with local one
Date: Thu, 5 Jan 2023 15:03:01 +0200	[thread overview]
Message-ID: <20230105130304.537205-9-erezsh@nvidia.com> (raw)
In-Reply-To: <20230105130304.537205-1-erezsh@nvidia.com>


The idea is to have a shared ibv_context that all the resources
allocated on it (FT + TIR are exceptions)
When ever a resource created locally an alias object to that resource
allocated and it used in the other context.
The connections between the resources are done according to each type of
the resource, to the original resource or to its alias resource.

Signed-off-by: Erez Shitrit <erezsh@nvidia.com>
Reviewed-by: Alex Vesker <valex@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h         |   6 +
 drivers/net/mlx5/hws/mlx5dr.h          |   2 +
 drivers/net/mlx5/hws/mlx5dr_action.c   |   9 +-
 drivers/net/mlx5/hws/mlx5dr_cmd.c      |  19 ++-
 drivers/net/mlx5/hws/mlx5dr_cmd.h      |   7 +-
 drivers/net/mlx5/hws/mlx5dr_context.c  |  34 +++-
 drivers/net/mlx5/hws/mlx5dr_context.h  |  22 +++
 drivers/net/mlx5/hws/mlx5dr_debug.c    |   2 +-
 drivers/net/mlx5/hws/mlx5dr_internal.h |   1 +
 drivers/net/mlx5/hws/mlx5dr_matcher.c  | 218 +++++++++++++++++++++++--
 drivers/net/mlx5/hws/mlx5dr_matcher.h  |   9 +
 drivers/net/mlx5/hws/mlx5dr_table.c    | 191 +++++++++++++++++++++-
 drivers/net/mlx5/hws/mlx5dr_table.h    |   4 +-
 13 files changed, 484 insertions(+), 40 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index fd1ad55f1f..a716a33e84 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -291,6 +291,12 @@
 
 #define MAX_ACTIONS_DATA_IN_HEADER_MODIFY 512
 
+/* Alias FT id passed to the ALLOW_OTHER_VHCA_ACCESS & CREATE_GENERAL_OBJECT
+ * commands should have the following format:
+ * {table_type: 8bits, table_id: 24bits}.
+ */
+#define FT_ID_FT_TYPE_OFFSET 24
+
 /* Completion mode. */
 enum mlx5_completion_mode {
 	MLX5_COMP_ONLY_ERR = 0x0,
diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h
index f8de27c615..aa36e3111f 100644
--- a/drivers/net/mlx5/hws/mlx5dr.h
+++ b/drivers/net/mlx5/hws/mlx5dr.h
@@ -96,6 +96,8 @@ struct mlx5dr_context_attr {
 	size_t initial_log_ste_memory; /* Currently not in use */
 	/* Optional PD used for allocating res ources */
 	struct ibv_pd *pd;
+	/* Optional other ctx for resources allocation, all objects will be created on it */
+	struct ibv_context *shared_ibv_ctx;
 };
 
 struct mlx5dr_table_attr {
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c
index b0ae4e7693..da19c1ca7d 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.c
+++ b/drivers/net/mlx5/hws/mlx5dr_action.c
@@ -1147,6 +1147,7 @@ mlx5dr_action_create_reformat_root(struct mlx5dr_action *action,
 {
 	enum mlx5dv_flow_table_type ft_type = 0; /*fix compilation warn*/
 	uint32_t verb_reformat_type = 0;
+	struct ibv_context *ibv_ctx;
 	int ret;
 
 	/* Convert action to FT type and verbs reformat type */
@@ -1157,8 +1158,9 @@ mlx5dr_action_create_reformat_root(struct mlx5dr_action *action,
 	mlx5dr_action_conv_reformat_to_verbs(action->type, &verb_reformat_type);
 
 	/* Create the reformat type for root table */
+	ibv_ctx = mlx5dr_context_get_local_ibv(action->ctx);
 	action->flow_action =
-		mlx5_glue->dv_create_flow_action_packet_reformat_root(action->ctx->ibv_ctx,
+		mlx5_glue->dv_create_flow_action_packet_reformat_root(ibv_ctx,
 								      data_sz,
 								      data,
 								      verb_reformat_type,
@@ -1496,14 +1498,17 @@ mlx5dr_action_create_modify_header_root(struct mlx5dr_action *action,
 					__be64 *actions)
 {
 	enum mlx5dv_flow_table_type ft_type = 0;
+	struct ibv_context *local_ibv_ctx;
 	int ret;
 
 	ret = mlx5dr_action_conv_flags_to_ft_type(action->flags, &ft_type);
 	if (ret)
 		return rte_errno;
 
+	local_ibv_ctx = mlx5dr_context_get_local_ibv(action->ctx);
+
 	action->flow_action =
-		mlx5_glue->dv_create_flow_action_modify_header_root(action->ctx->ibv_ctx,
+		mlx5_glue->dv_create_flow_action_modify_header_root(local_ibv_ctx,
 								    actions_sz,
 								    (uint64_t *)actions,
 								    ft_type);
diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c
index d525867de5..754a424bd7 100644
--- a/drivers/net/mlx5/hws/mlx5dr_cmd.c
+++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c
@@ -217,18 +217,23 @@ void mlx5dr_cmd_set_attr_connect_miss_tbl(struct mlx5dr_context *ctx,
 {
 	struct mlx5dr_devx_obj *default_miss_tbl;
 
-	if (type != MLX5DR_TABLE_TYPE_FDB)
+	if (type != MLX5DR_TABLE_TYPE_FDB && !mlx5dr_context_shared_gvmi_used(ctx))
 		return;
 
-	default_miss_tbl = ctx->common_res[type].default_miss->ft;
-	if (!default_miss_tbl) {
-		assert(false);
-		return;
-	}
 	ft_attr->modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION;
 	ft_attr->type = fw_ft_type;
 	ft_attr->table_miss_action = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION_GOTO_TBL;
-	ft_attr->table_miss_id = default_miss_tbl->id;
+
+	if (type == MLX5DR_TABLE_TYPE_FDB) {
+		default_miss_tbl = ctx->common_res[type].default_miss->ft;
+		if (!default_miss_tbl) {
+			assert(false);
+			return;
+		}
+		ft_attr->table_miss_id = default_miss_tbl->id;
+	} else {
+		ft_attr->table_miss_id = ctx->gvmi_res[type].aliased_end_ft->id;
+	}
 }
 
 struct mlx5dr_devx_obj *
diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h
index 8b8d5d00b0..9fe493a8f9 100644
--- a/drivers/net/mlx5/hws/mlx5dr_cmd.h
+++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h
@@ -11,6 +11,8 @@ struct mlx5dr_cmd_ft_create_attr {
 	bool rtc_valid;
 };
 
+#define ACCESS_KEY_LEN	32
+
 struct mlx5dr_cmd_ft_modify_attr {
 	uint8_t type;
 	uint32_t rtc_id_0;
@@ -50,7 +52,7 @@ struct mlx5dr_cmd_alias_obj_create_attr {
 	uint32_t obj_id;
 	uint16_t vhca_id;
 	uint16_t obj_type;
-	uint8_t access_key[32];
+	uint8_t access_key[ACCESS_KEY_LEN];
 };
 
 struct mlx5dr_cmd_stc_create_attr {
@@ -134,7 +136,7 @@ struct mlx5dr_cmd_sq_create_attr {
 struct mlx5dr_cmd_allow_other_vhca_access_attr {
 	uint16_t obj_type;
 	uint32_t obj_id;
-	uint8_t access_key[32];
+	uint8_t access_key[ACCESS_KEY_LEN];
 };
 
 struct mlx5dr_cmd_query_ft_caps {
@@ -178,6 +180,7 @@ struct mlx5dr_cmd_query_caps {
 	uint32_t trivial_match_definer;
 	uint32_t vhca_id;
 	bool cross_vhca_resources;
+	uint32_t shared_vhca_id;
 	char fw_ver[64];
 };
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_context.c b/drivers/net/mlx5/hws/mlx5dr_context.c
index 76ada7bb7f..6627337d9e 100644
--- a/drivers/net/mlx5/hws/mlx5dr_context.c
+++ b/drivers/net/mlx5/hws/mlx5dr_context.c
@@ -178,6 +178,36 @@ static void mlx5dr_context_uninit_hws(struct mlx5dr_context *ctx)
 	mlx5dr_context_uninit_pd(ctx);
 }
 
+static int mlx5dr_context_init_shared_ctx(struct mlx5dr_context *ctx,
+					  struct ibv_context *ibv_ctx,
+					  struct mlx5dr_context_attr *attr)
+{
+	struct mlx5dr_cmd_query_caps shared_caps = {0};
+	int ret;
+
+	if (!attr->shared_ibv_ctx) {
+		ctx->ibv_ctx = ibv_ctx;
+	} else {
+		ctx->ibv_ctx = attr->shared_ibv_ctx;
+		ctx->local_ibv_ctx = ibv_ctx;
+		ret = mlx5dr_cmd_query_caps(attr->shared_ibv_ctx, &shared_caps);
+		if (ret || !shared_caps.cross_vhca_resources) {
+			DR_LOG(INFO, "No cross_vhca_resources cap for shared ibv");
+			rte_errno = ENOTSUP;
+			return rte_errno;
+		}
+		ctx->caps->shared_vhca_id = shared_caps.vhca_id;
+	}
+
+	if (ctx->local_ibv_ctx && !ctx->caps->cross_vhca_resources) {
+		DR_LOG(INFO, "No cross_vhca_resources cap for local ibv");
+		rte_errno = ENOTSUP;
+		return rte_errno;
+	}
+
+	return 0;
+}
+
 struct mlx5dr_context *mlx5dr_context_open(struct ibv_context *ibv_ctx,
 					   struct mlx5dr_context_attr *attr)
 {
@@ -190,7 +220,6 @@ struct mlx5dr_context *mlx5dr_context_open(struct ibv_context *ibv_ctx,
 		return NULL;
 	}
 
-	ctx->ibv_ctx = ibv_ctx;
 	pthread_spin_init(&ctx->ctrl_lock, PTHREAD_PROCESS_PRIVATE);
 
 	ctx->caps = simple_calloc(1, sizeof(*ctx->caps));
@@ -201,6 +230,9 @@ struct mlx5dr_context *mlx5dr_context_open(struct ibv_context *ibv_ctx,
 	if (ret)
 		goto free_caps;
 
+	if (mlx5dr_context_init_shared_ctx(ctx, ibv_ctx, attr))
+		goto free_caps;
+
 	ret = mlx5dr_context_init_hws(ctx, attr);
 	if (ret)
 		goto free_caps;
diff --git a/drivers/net/mlx5/hws/mlx5dr_context.h b/drivers/net/mlx5/hws/mlx5dr_context.h
index b0c7802daf..a38d9484b3 100644
--- a/drivers/net/mlx5/hws/mlx5dr_context.h
+++ b/drivers/net/mlx5/hws/mlx5dr_context.h
@@ -22,13 +22,22 @@ struct mlx5dr_context_common_res {
 	struct mlx5dr_cmd_forward_tbl *default_miss;
 };
 
+struct mlx5dr_context_shared_gvmi_res {
+	struct mlx5dr_devx_obj *end_ft;
+	struct mlx5dr_devx_obj *aliased_end_ft;
+	uint32_t refcount;
+};
+
 struct mlx5dr_context {
 	struct ibv_context *ibv_ctx;
+	/* When local_ibv_ctx is not NULL means we are using shared_ibv for resources */
+	struct ibv_context *local_ibv_ctx;
 	struct mlx5dr_cmd_query_caps *caps;
 	struct ibv_pd *pd;
 	uint32_t pd_num;
 	struct mlx5dr_pool *stc_pool[MLX5DR_TABLE_TYPE_MAX];
 	struct mlx5dr_context_common_res common_res[MLX5DR_TABLE_TYPE_MAX];
+	struct mlx5dr_context_shared_gvmi_res gvmi_res[MLX5DR_TABLE_TYPE_MAX];
 	struct mlx5dr_pattern_cache *pattern_cache;
 	pthread_spinlock_t ctrl_lock;
 	enum mlx5dr_context_flags flags;
@@ -37,4 +46,17 @@ struct mlx5dr_context {
 	LIST_HEAD(table_head, mlx5dr_table) head;
 };
 
+static inline bool mlx5dr_context_shared_gvmi_used(struct mlx5dr_context *ctx)
+{
+	return ctx->local_ibv_ctx ? true : false;
+}
+
+static inline struct ibv_context *
+mlx5dr_context_get_local_ibv(struct mlx5dr_context *ctx)
+{
+	if (mlx5dr_context_shared_gvmi_used(ctx))
+		return ctx->local_ibv_ctx;
+
+	return ctx->ibv_ctx;
+}
 #endif /* MLX5DR_CONTEXT_H_ */
diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c
index 890a761c48..55011c208d 100644
--- a/drivers/net/mlx5/hws/mlx5dr_debug.c
+++ b/drivers/net/mlx5/hws/mlx5dr_debug.c
@@ -405,7 +405,7 @@ static int mlx5dr_debug_dump_context_info(FILE *f, struct mlx5dr_context *ctx)
 		      MLX5DR_DEBUG_RES_TYPE_CONTEXT,
 		      (uint64_t)(uintptr_t)ctx,
 		      ctx->flags & MLX5DR_CONTEXT_FLAG_HWS_SUPPORT,
-		      mlx5_glue->get_device_name(ctx->ibv_ctx->device),
+		      mlx5_glue->get_device_name(mlx5dr_context_get_local_ibv(ctx)->device),
 		      DEBUG_VERSION);
 	if (ret < 0) {
 		rte_errno = EINVAL;
diff --git a/drivers/net/mlx5/hws/mlx5dr_internal.h b/drivers/net/mlx5/hws/mlx5dr_internal.h
index 586b3e3ea3..faad2bbd0f 100644
--- a/drivers/net/mlx5/hws/mlx5dr_internal.h
+++ b/drivers/net/mlx5/hws/mlx5dr_internal.h
@@ -18,6 +18,7 @@
 #endif
 #include <rte_flow.h>
 #include <rte_gtp.h>
+#include <rte_random.h>
 
 #include "mlx5_prm.h"
 #include "mlx5_glue.h"
diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c
index 2e444c1179..46217b2ab3 100644
--- a/drivers/net/mlx5/hws/mlx5dr_matcher.c
+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c
@@ -19,31 +19,20 @@ static uint8_t mlx5dr_matcher_rules_to_tbl_depth(uint8_t log_num_of_rules)
 	return RTE_MIN(log_num_of_rules, MLX5DR_MATCHER_ASSURED_COL_TBL_DEPTH);
 }
 
-static int mlx5dr_matcher_create_end_ft(struct mlx5dr_matcher *matcher)
-{
-	struct mlx5dr_table *tbl = matcher->tbl;
-
-	matcher->end_ft = mlx5dr_table_create_default_ft(tbl);
-	if (!matcher->end_ft) {
-		DR_LOG(ERR, "Failed to create matcher end flow table");
-		return rte_errno;
-	}
-	return 0;
-}
-
 static void mlx5dr_matcher_destroy_end_ft(struct mlx5dr_matcher *matcher)
 {
 	mlx5dr_table_destroy_default_ft(matcher->tbl, matcher->end_ft);
 }
 
-static int mlx5dr_matcher_free_rtc_pointing(uint32_t fw_ft_type,
+static int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx,
+					    uint32_t fw_ft_type,
 					    enum mlx5dr_table_type type,
 					    struct mlx5dr_devx_obj *devx_obj)
 {
 	struct mlx5dr_cmd_ft_modify_attr ft_attr = {0};
 	int ret;
 
-	if (type != MLX5DR_TABLE_TYPE_FDB)
+	if (type != MLX5DR_TABLE_TYPE_FDB && !mlx5dr_context_shared_gvmi_used(ctx))
 		return 0;
 
 	ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID;
@@ -60,6 +49,136 @@ static int mlx5dr_matcher_free_rtc_pointing(uint32_t fw_ft_type,
 	return 0;
 }
 
+static int mlx5dr_matcher_shared_point_end_ft(struct mlx5dr_matcher *matcher)
+{
+	struct mlx5dr_cmd_ft_modify_attr ft_attr = {0};
+	int ret;
+
+	mlx5dr_cmd_set_attr_connect_miss_tbl(matcher->tbl->ctx,
+					     matcher->tbl->fw_ft_type,
+					     matcher->tbl->type,
+					     &ft_attr);
+
+	ret = mlx5dr_cmd_flow_table_modify(matcher->end_ft, &ft_attr);
+	if (ret) {
+		DR_LOG(ERR, "Failed to connect new matcher to default miss alias RTC");
+		return ret;
+	}
+
+	ret = mlx5dr_matcher_free_rtc_pointing(matcher->tbl->ctx,
+					       matcher->tbl->fw_ft_type,
+					       matcher->tbl->type,
+					       matcher->end_ft);
+
+	return ret;
+}
+
+static int mlx5dr_matcher_shared_create_alias_rtc(struct mlx5dr_matcher *matcher)
+{
+	struct mlx5dr_context *ctx = matcher->tbl->ctx;
+	int ret;
+
+	ret = mlx5dr_matcher_create_aliased_obj(ctx,
+						ctx->ibv_ctx,
+						ctx->local_ibv_ctx,
+						ctx->caps->shared_vhca_id,
+						matcher->match_ste.rtc_0->id,
+						MLX5_GENERAL_OBJ_TYPE_RTC,
+						&matcher->match_ste.aliased_rtc_0);
+	if (ret) {
+		DR_LOG(ERR, "Failed to allocate alias RTC");
+		return ret;
+	}
+	return 0;
+}
+
+static int mlx5dr_matcher_create_init_shared(struct mlx5dr_matcher *matcher)
+{
+	if (!mlx5dr_context_shared_gvmi_used(matcher->tbl->ctx))
+		return 0;
+
+	if (mlx5dr_matcher_shared_point_end_ft(matcher)) {
+		DR_LOG(ERR, "Failed to point shared matcher end flow table");
+		return rte_errno;
+	}
+
+	if (mlx5dr_matcher_shared_create_alias_rtc(matcher)) {
+		DR_LOG(ERR, "Failed to create alias RTC");
+		return rte_errno;
+	}
+
+	return 0;
+}
+
+static void mlx5dr_matcher_create_uninit_shared(struct mlx5dr_matcher *matcher)
+{
+	if (!mlx5dr_context_shared_gvmi_used(matcher->tbl->ctx))
+		return;
+
+	if (matcher->match_ste.aliased_rtc_0) {
+		mlx5dr_cmd_destroy_obj(matcher->match_ste.aliased_rtc_0);
+		matcher->match_ste.aliased_rtc_0 = NULL;
+	}
+}
+
+static int mlx5dr_matcher_create_end_ft(struct mlx5dr_matcher *matcher)
+{
+	struct mlx5dr_table *tbl = matcher->tbl;
+
+	matcher->end_ft = mlx5dr_table_create_default_ft(tbl->ctx->ibv_ctx, tbl);
+	if (!matcher->end_ft) {
+		DR_LOG(ERR, "Failed to create matcher end flow table");
+		return rte_errno;
+	}
+	return 0;
+}
+
+static uint32_t
+mlx5dr_matcher_connect_get_rtc0(struct mlx5dr_matcher *matcher)
+{
+	if (!matcher->match_ste.aliased_rtc_0)
+		return matcher->match_ste.rtc_0->id;
+	else
+		return matcher->match_ste.aliased_rtc_0->id;
+}
+
+/* The function updates tbl->local_ft to the first RTC or 0 if no more matchers */
+static int mlx5dr_matcher_shared_update_local_ft(struct mlx5dr_table *tbl)
+{
+	struct mlx5dr_cmd_ft_modify_attr cur_ft_attr = {0};
+	struct mlx5dr_matcher *first_matcher;
+	int ret;
+
+	if (!mlx5dr_context_shared_gvmi_used(tbl->ctx))
+		return 0;
+
+	first_matcher = LIST_FIRST(&tbl->head);
+	if (!first_matcher) {
+		/* local ft no longer points to any RTC, drop refcount */
+		ret = mlx5dr_matcher_free_rtc_pointing(tbl->ctx,
+						       tbl->fw_ft_type,
+						       tbl->type,
+						       tbl->local_ft);
+		if (ret)
+			DR_LOG(ERR, "Failed to clear local FT to prev alias RTC");
+
+		return ret;
+	}
+
+	/* point local_ft to the first RTC */
+	cur_ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID;
+	cur_ft_attr.type = tbl->fw_ft_type;
+	cur_ft_attr.rtc_id_0 = mlx5dr_matcher_connect_get_rtc0(first_matcher);
+
+	ret = mlx5dr_cmd_flow_table_modify(tbl->local_ft, &cur_ft_attr);
+	if (ret) {
+		DR_LOG(ERR, "Failed to point local FT to alias RTC");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher)
 {
 	struct mlx5dr_cmd_ft_modify_attr ft_attr = {0};
@@ -121,6 +240,12 @@ static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher)
 		goto remove_from_list;
 	}
 
+	ret = mlx5dr_matcher_shared_update_local_ft(tbl);
+	if (ret) {
+		DR_LOG(ERR, "Failed to update local_ft anchor in shared table");
+		goto remove_from_list;
+	}
+
 	return 0;
 
 remove_from_list:
@@ -174,7 +299,8 @@ static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher)
 
 	if (!next) {
 		/* ft no longer points to any RTC, drop refcount */
-		ret = mlx5dr_matcher_free_rtc_pointing(tbl->fw_ft_type,
+		ret = mlx5dr_matcher_free_rtc_pointing(tbl->ctx,
+						       tbl->fw_ft_type,
 						       tbl->type,
 						       prev_ft);
 		if (ret) {
@@ -183,6 +309,12 @@ static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher)
 		}
 	}
 
+	ret = mlx5dr_matcher_shared_update_local_ft(tbl);
+	if (ret) {
+		DR_LOG(ERR, "Failed to update local_ft in shared table");
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -206,6 +338,49 @@ static void mlx5dr_matcher_set_rtc_attr_sz(struct mlx5dr_matcher *matcher,
 	}
 }
 
+int mlx5dr_matcher_create_aliased_obj(struct mlx5dr_context *ctx,
+				      struct ibv_context *ibv_owner,
+				      struct ibv_context *ibv_allowed,
+				      uint16_t vhca_id_to_be_accessed,
+				      uint32_t aliased_object_id,
+				      uint16_t object_type,
+				      struct mlx5dr_devx_obj **obj)
+{
+	struct mlx5dr_cmd_allow_other_vhca_access_attr allow_attr = {0};
+	struct mlx5dr_cmd_alias_obj_create_attr alias_attr = {0};
+	char key[ACCESS_KEY_LEN];
+	int ret;
+	int i;
+
+	if (!mlx5dr_context_shared_gvmi_used(ctx))
+		return 0;
+
+	for (i = 0; i < ACCESS_KEY_LEN; i++)
+		key[i] = rte_rand() & 0xFF;
+
+	memcpy(allow_attr.access_key, key, ACCESS_KEY_LEN);
+	allow_attr.obj_type = object_type;
+	allow_attr.obj_id = aliased_object_id;
+
+	ret = mlx5dr_cmd_allow_other_vhca_access(ibv_owner, &allow_attr);
+	if (ret) {
+		DR_LOG(ERR, "Failed to allow RTC to be aliased");
+		return ret;
+	}
+
+	memcpy(alias_attr.access_key, key, ACCESS_KEY_LEN);
+	alias_attr.obj_id = aliased_object_id;
+	alias_attr.obj_type = object_type;
+	alias_attr.vhca_id = vhca_id_to_be_accessed;
+	*obj = mlx5dr_cmd_alias_obj_create(ibv_allowed, &alias_attr);
+	if (!*obj) {
+		DR_LOG(ERR, "Failed to create alias object");
+		return rte_errno;
+	}
+
+	return 0;
+}
+
 static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher,
 				     bool is_match_rtc)
 {
@@ -573,13 +748,20 @@ static int mlx5dr_matcher_create_and_connect(struct mlx5dr_matcher *matcher)
 	if (ret)
 		goto destroy_end_ft;
 
+	/* Allocate and set shared resources */
+	ret = mlx5dr_matcher_create_init_shared(matcher);
+	if (ret)
+		goto destroy_rtc;
+
 	/* Connect the matcher to the matcher list */
 	ret = mlx5dr_matcher_connect(matcher);
 	if (ret)
-		goto destroy_rtc;
+		goto destroy_shared;
 
 	return 0;
 
+destroy_shared:
+	mlx5dr_matcher_create_uninit_shared(matcher);
 destroy_rtc:
 	mlx5dr_matcher_destroy_rtc(matcher, true);
 destroy_end_ft:
@@ -594,6 +776,7 @@ static int mlx5dr_matcher_create_and_connect(struct mlx5dr_matcher *matcher)
 static void mlx5dr_matcher_destroy_and_disconnect(struct mlx5dr_matcher *matcher)
 {
 	mlx5dr_matcher_disconnect(matcher);
+	mlx5dr_matcher_create_uninit_shared(matcher);
 	mlx5dr_matcher_destroy_rtc(matcher, true);
 	mlx5dr_matcher_destroy_end_ft(matcher);
 	mlx5dr_matcher_unbind_at(matcher);
@@ -766,7 +949,8 @@ static int mlx5dr_matcher_init_root(struct mlx5dr_matcher *matcher)
 	attr.priority = matcher->attr.priority;
 
 	matcher->dv_matcher =
-		mlx5_glue->dv_create_flow_matcher_root(ctx->ibv_ctx, &attr);
+		mlx5_glue->dv_create_flow_matcher_root(mlx5dr_context_get_local_ibv(ctx),
+						       &attr);
 	if (!matcher->dv_matcher) {
 		DR_LOG(ERR, "Failed to create DV flow matcher");
 		rte_errno = errno;
diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h
index b7bf94762c..62004078cf 100644
--- a/drivers/net/mlx5/hws/mlx5dr_matcher.h
+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h
@@ -42,6 +42,8 @@ struct mlx5dr_matcher_match_ste {
 	struct mlx5dr_devx_obj *rtc_0;
 	struct mlx5dr_devx_obj *rtc_1;
 	struct mlx5dr_pool *pool;
+	/* Currently not support FDB aliased */
+	struct mlx5dr_devx_obj *aliased_rtc_0;
 };
 
 struct mlx5dr_matcher_action_ste {
@@ -73,4 +75,11 @@ int mlx5dr_matcher_conv_items_to_prm(uint64_t *match_buf,
 				     uint8_t *match_criteria,
 				     bool is_value);
 
+int mlx5dr_matcher_create_aliased_obj(struct mlx5dr_context *ctx,
+				      struct ibv_context *ibv_owner,
+				      struct ibv_context *ibv_allowed,
+				      uint16_t vhca_id_to_be_accessed,
+				      uint32_t aliased_object_id,
+				      uint16_t object_type,
+				      struct mlx5dr_devx_obj **obj);
 #endif /* MLX5DR_MATCHER_H_ */
diff --git a/drivers/net/mlx5/hws/mlx5dr_table.c b/drivers/net/mlx5/hws/mlx5dr_table.c
index 33052abce8..327e2ec710 100644
--- a/drivers/net/mlx5/hws/mlx5dr_table.c
+++ b/drivers/net/mlx5/hws/mlx5dr_table.c
@@ -40,7 +40,8 @@ mlx5dr_table_up_default_fdb_miss_tbl(struct mlx5dr_table *tbl)
 	assert(ctx->caps->eswitch_manager);
 	vport = ctx->caps->eswitch_manager_vport_number;
 
-	default_miss = mlx5dr_cmd_miss_ft_create(ctx->ibv_ctx, &ft_attr, vport);
+	default_miss = mlx5dr_cmd_miss_ft_create(mlx5dr_context_get_local_ibv(ctx),
+						 &ft_attr, vport);
 	if (!default_miss) {
 		DR_LOG(ERR, "Failed to default miss table type: 0x%x", tbl_type);
 		return rte_errno;
@@ -96,7 +97,8 @@ mlx5dr_table_connect_to_default_miss_tbl(struct mlx5dr_table *tbl,
 }
 
 struct mlx5dr_devx_obj *
-mlx5dr_table_create_default_ft(struct mlx5dr_table *tbl)
+mlx5dr_table_create_default_ft(struct ibv_context *ibv,
+			       struct mlx5dr_table *tbl)
 {
 	struct mlx5dr_cmd_ft_create_attr ft_attr = {0};
 	struct mlx5dr_devx_obj *ft_obj;
@@ -104,7 +106,7 @@ mlx5dr_table_create_default_ft(struct mlx5dr_table *tbl)
 
 	mlx5dr_table_init_next_ft_attr(tbl, &ft_attr);
 
-	ft_obj = mlx5dr_cmd_flow_table_create(tbl->ctx->ibv_ctx, &ft_attr);
+	ft_obj = mlx5dr_cmd_flow_table_create(ibv, &ft_attr);
 	if (ft_obj && tbl->type == MLX5DR_TABLE_TYPE_FDB) {
 		/* Take/create ref over the default miss */
 		ret = mlx5dr_table_up_default_fdb_miss_tbl(tbl);
@@ -128,6 +130,171 @@ mlx5dr_table_create_default_ft(struct mlx5dr_table *tbl)
 	return NULL;
 }
 
+static int
+mlx5dr_table_init_check_hws_support(struct mlx5dr_context *ctx,
+				    struct mlx5dr_table *tbl)
+{
+	if (!(ctx->flags & MLX5DR_CONTEXT_FLAG_HWS_SUPPORT)) {
+		DR_LOG(ERR, "HWS not supported, cannot create mlx5dr_table");
+		rte_errno = EOPNOTSUPP;
+		return rte_errno;
+	}
+
+	if (mlx5dr_context_shared_gvmi_used(ctx) && tbl->type == MLX5DR_TABLE_TYPE_FDB) {
+		DR_LOG(ERR, "FDB with shared port resources is not supported");
+		rte_errno = EOPNOTSUPP;
+		return rte_errno;
+	}
+
+	return 0;
+}
+
+static int
+mlx5dr_table_shared_gvmi_resource_create(struct mlx5dr_context *ctx,
+					 enum mlx5dr_table_type type,
+					 struct mlx5dr_context_shared_gvmi_res *gvmi_res)
+{
+	struct mlx5dr_cmd_ft_create_attr ft_attr = {0};
+	uint32_t calculated_ft_id;
+	int ret;
+
+	if (!mlx5dr_context_shared_gvmi_used(ctx))
+		return 0;
+
+	ft_attr.type = mlx5dr_table_get_res_fw_ft_type(type, false);
+	ft_attr.level = ctx->caps->nic_ft.max_level - 1;
+	ft_attr.rtc_valid = true;
+
+	gvmi_res->end_ft =
+		mlx5dr_cmd_flow_table_create(mlx5dr_context_get_local_ibv(ctx),
+					     &ft_attr);
+	if (!gvmi_res->end_ft) {
+		DR_LOG(ERR, "Failed to create end-ft");
+		return rte_errno;
+	}
+
+	calculated_ft_id =
+		mlx5dr_table_get_res_fw_ft_type(type, false) << FT_ID_FT_TYPE_OFFSET;
+	calculated_ft_id |= gvmi_res->end_ft->id;
+
+	/* create alias to that FT */
+	ret = mlx5dr_matcher_create_aliased_obj(ctx,
+						ctx->local_ibv_ctx,
+						ctx->ibv_ctx,
+						ctx->caps->vhca_id,
+						calculated_ft_id,
+						MLX5_GENERAL_OBJ_TYPE_FT_ALIAS,
+						&gvmi_res->aliased_end_ft);
+	if (ret) {
+		DR_LOG(ERR, "Failed to create alias end-ft");
+		goto free_end_ft;
+	}
+
+	return 0;
+
+free_end_ft:
+	mlx5dr_cmd_destroy_obj(gvmi_res->end_ft);
+
+	return rte_errno;
+}
+
+static void
+mlx5dr_table_shared_gvmi_resourse_destroy(struct mlx5dr_context *ctx,
+					  struct mlx5dr_context_shared_gvmi_res *gvmi_res)
+{
+	if (!mlx5dr_context_shared_gvmi_used(ctx))
+		return;
+
+	if (gvmi_res->aliased_end_ft) {
+		mlx5dr_cmd_destroy_obj(gvmi_res->aliased_end_ft);
+		gvmi_res->aliased_end_ft = NULL;
+	}
+	if (gvmi_res->end_ft) {
+		mlx5dr_cmd_destroy_obj(gvmi_res->end_ft);
+		gvmi_res->end_ft = NULL;
+	}
+}
+
+/* called under spinlock ctx->ctrl_lock */
+static struct mlx5dr_context_shared_gvmi_res *
+mlx5dr_table_get_shared_gvmi_res(struct mlx5dr_context *ctx, enum mlx5dr_table_type type)
+{
+	int ret;
+
+	if (!mlx5dr_context_shared_gvmi_used(ctx))
+		return NULL;
+
+	if (ctx->gvmi_res[type].aliased_end_ft) {
+		ctx->gvmi_res[type].refcount++;
+		return &ctx->gvmi_res[type];
+	}
+
+	ret = mlx5dr_table_shared_gvmi_resource_create(ctx, type, &ctx->gvmi_res[type]);
+	if (ret) {
+		DR_LOG(ERR, "Failed to create shared gvmi res for type: %d", type);
+		goto out;
+	}
+
+	ctx->gvmi_res[type].refcount = 1;
+
+	return &ctx->gvmi_res[type];
+
+out:
+	return NULL;
+}
+
+/* called under spinlock ctx->ctrl_lock */
+static void mlx5dr_table_put_shared_gvmi_res(struct mlx5dr_table *tbl)
+{
+	struct mlx5dr_context *ctx = tbl->ctx;
+
+	if (!mlx5dr_context_shared_gvmi_used(ctx))
+		return;
+
+	if (--ctx->gvmi_res[tbl->type].refcount)
+		return;
+
+	mlx5dr_table_shared_gvmi_resourse_destroy(ctx, &ctx->gvmi_res[tbl->type]);
+}
+
+static void mlx5dr_table_uninit_shared_ctx_res(struct mlx5dr_table *tbl)
+{
+	struct mlx5dr_context *ctx = tbl->ctx;
+
+	if (!mlx5dr_context_shared_gvmi_used(ctx))
+		return;
+
+	mlx5dr_cmd_destroy_obj(tbl->local_ft);
+
+	mlx5dr_table_put_shared_gvmi_res(tbl);
+}
+
+/* called under spin_lock ctx->ctrl_lock */
+static int mlx5dr_table_init_shared_ctx_res(struct mlx5dr_context *ctx, struct mlx5dr_table *tbl)
+{
+	if (!mlx5dr_context_shared_gvmi_used(ctx))
+		return 0;
+
+	/* create local-ft for root access */
+	tbl->local_ft =
+		mlx5dr_table_create_default_ft(mlx5dr_context_get_local_ibv(ctx), tbl);
+	if (!tbl->local_ft) {
+		DR_LOG(ERR, "Failed to create local-ft");
+		return rte_errno;
+	}
+
+	if (!mlx5dr_table_get_shared_gvmi_res(tbl->ctx, tbl->type)) {
+		DR_LOG(ERR, "Failed to shared gvmi resources");
+		goto clean_local_ft;
+	}
+
+	return 0;
+
+clean_local_ft:
+	mlx5dr_table_destroy_default_ft(tbl, tbl->local_ft);
+	return rte_errno;
+}
+
 void mlx5dr_table_destroy_default_ft(struct mlx5dr_table *tbl,
 				     struct mlx5dr_devx_obj *ft_obj)
 {
@@ -143,11 +310,9 @@ static int mlx5dr_table_init(struct mlx5dr_table *tbl)
 	if (mlx5dr_table_is_root(tbl))
 		return 0;
 
-	if (!(tbl->ctx->flags & MLX5DR_CONTEXT_FLAG_HWS_SUPPORT)) {
-		DR_LOG(ERR, "HWS not supported, cannot create mlx5dr_table");
-		rte_errno = EOPNOTSUPP;
-		return rte_errno;
-	}
+	ret = mlx5dr_table_init_check_hws_support(ctx, tbl);
+	if (ret)
+		return ret;
 
 	switch (tbl->type) {
 	case MLX5DR_TABLE_TYPE_NIC_RX:
@@ -165,7 +330,7 @@ static int mlx5dr_table_init(struct mlx5dr_table *tbl)
 	}
 
 	pthread_spin_lock(&ctx->ctrl_lock);
-	tbl->ft = mlx5dr_table_create_default_ft(tbl);
+	tbl->ft = mlx5dr_table_create_default_ft(tbl->ctx->ibv_ctx, tbl);
 	if (!tbl->ft) {
 		DR_LOG(ERR, "Failed to create flow table devx object");
 		pthread_spin_unlock(&ctx->ctrl_lock);
@@ -175,10 +340,17 @@ static int mlx5dr_table_init(struct mlx5dr_table *tbl)
 	ret = mlx5dr_action_get_default_stc(ctx, tbl->type);
 	if (ret)
 		goto tbl_destroy;
+
+	ret = mlx5dr_table_init_shared_ctx_res(ctx, tbl);
+	if (ret)
+		goto put_stc;
+
 	pthread_spin_unlock(&ctx->ctrl_lock);
 
 	return 0;
 
+put_stc:
+	mlx5dr_action_put_default_stc(ctx, tbl->type);
 tbl_destroy:
 	mlx5dr_table_destroy_default_ft(tbl, tbl->ft);
 	pthread_spin_unlock(&ctx->ctrl_lock);
@@ -192,6 +364,7 @@ static void mlx5dr_table_uninit(struct mlx5dr_table *tbl)
 	pthread_spin_lock(&tbl->ctx->ctrl_lock);
 	mlx5dr_action_put_default_stc(tbl->ctx, tbl->type);
 	mlx5dr_table_destroy_default_ft(tbl, tbl->ft);
+	mlx5dr_table_uninit_shared_ctx_res(tbl);
 	pthread_spin_unlock(&tbl->ctx->ctrl_lock);
 }
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_table.h b/drivers/net/mlx5/hws/mlx5dr_table.h
index 786dddfaa4..362d8a9048 100644
--- a/drivers/net/mlx5/hws/mlx5dr_table.h
+++ b/drivers/net/mlx5/hws/mlx5dr_table.h
@@ -10,6 +10,7 @@
 struct mlx5dr_table {
 	struct mlx5dr_context *ctx;
 	struct mlx5dr_devx_obj *ft;
+	struct mlx5dr_devx_obj *local_ft;
 	enum mlx5dr_table_type type;
 	uint32_t fw_ft_type;
 	uint32_t level;
@@ -37,7 +38,8 @@ static inline bool mlx5dr_table_is_root(struct mlx5dr_table *tbl)
 	return (tbl->level == MLX5DR_ROOT_LEVEL);
 }
 
-struct mlx5dr_devx_obj *mlx5dr_table_create_default_ft(struct mlx5dr_table *tbl);
+struct mlx5dr_devx_obj *mlx5dr_table_create_default_ft(struct ibv_context *ibv,
+						       struct mlx5dr_table *tbl);
 
 void mlx5dr_table_destroy_default_ft(struct mlx5dr_table *tbl,
 				     struct mlx5dr_devx_obj *ft_obj);
-- 
2.18.2


  parent reply	other threads:[~2023-01-05 13:04 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-19  8:24 [PATCH V1 00/11] Support resource sharing among ibv_devices Erez Shitrit
2022-12-19  8:24 ` [PATCH V1 01/11] mailmap: add new contributors to the list Erez Shitrit
2022-12-19  8:24 ` [PATCH V1 02/11] net/mlx5/hws: add capabilities fields for vhca access Erez Shitrit
2022-12-27 15:47   ` Slava Ovsiienko
2023-01-05 13:02   ` [PATCH v2 00/10] Support resource sharing among ibv_devices Erez Shitrit
2023-01-05 13:02     ` [PATCH v2 01/10] net/mlx5/hws: add capabilities fields for vhca access Erez Shitrit
2023-01-05 13:02     ` [PATCH v2 02/10] net/mlx5/hws: remove wrong PRM capability macros Erez Shitrit
2023-01-05 13:02     ` [PATCH v2 03/10] net/mlx5/hws: add PRM definitions for cross-vhca capabilities Erez Shitrit
2023-01-05 13:02     ` [PATCH v2 04/10] net/mlx5/hws: read " Erez Shitrit
2023-01-05 13:02     ` [PATCH v2 05/10] net/mlx5/hws: added allow-other-vhca-access command Erez Shitrit
2023-01-05 13:02     ` [PATCH v2 06/10] net/mlx5/hws: added command to create alias objects Erez Shitrit
2023-01-05 13:03     ` [PATCH v2 07/10] net/mlx5/hws: add vhca identifier ID to the caps Erez Shitrit
2023-01-05 13:03     ` Erez Shitrit [this message]
2023-01-05 13:03     ` [PATCH v2 09/10] net/mlx5/hws: support actions while shared resources is used Erez Shitrit
2023-01-05 13:03     ` [PATCH v2 10/10] net/mlx5/hws: add debug details for cross gvmi Erez Shitrit
2023-01-10  9:01     ` [PATCH v2 00/10] Support resource sharing among ibv_devices Raslan Darawsheh
2022-12-19  8:24 ` [PATCH V1 03/11] net/mlx5/hws: remove wrong PRM capability macros Erez Shitrit
2022-12-27 15:47   ` Slava Ovsiienko
2022-12-19  8:24 ` [PATCH V1 04/11] net/mlx5/hws: add PRM definitions for cross-vhca capabilities Erez Shitrit
2022-12-27 15:47   ` Slava Ovsiienko
2022-12-19  8:24 ` [PATCH V1 05/11] net/mlx5/hws: read " Erez Shitrit
2022-12-27 15:47   ` Slava Ovsiienko
2022-12-19  8:24 ` [PATCH V1 06/11] net/mlx5/hws: added allow-other-vhca-access command Erez Shitrit
2022-12-27 15:48   ` Slava Ovsiienko
2022-12-19  8:24 ` [PATCH V1 07/11] net/mlx5/hws: added command to create alias objects Erez Shitrit
2022-12-27 15:48   ` Slava Ovsiienko
2022-12-19  8:24 ` [PATCH V1 08/11] net/mlx5/hws: add vhca identifier ID to the caps Erez Shitrit
2022-12-27 15:48   ` Slava Ovsiienko
2022-12-19  8:24 ` [PATCH V1 09/11] net/mlx5/hws: support shared ibv-context with local one Erez Shitrit
2022-12-27 15:49   ` Slava Ovsiienko
2022-12-19  8:24 ` [PATCH V1 10/11] net/mlx5/hws: support actions while shared resources is used Erez Shitrit
2022-12-27 15:49   ` Slava Ovsiienko
2022-12-19  8:24 ` [PATCH V1 11/11] net/mlx5/hws: add debug details for cross gvmi Erez Shitrit
2022-12-27 15:48   ` Slava Ovsiienko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230105130304.537205-9-erezsh@nvidia.com \
    --to=erezsh@nvidia.com \
    --cc=dev@dpdk.org \
    --cc=matan@nvidia.com \
    --cc=rasland@nvidia.com \
    --cc=valex@nvidia.com \
    --cc=viacheslavo@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).