DPDK patches and discussions
 help / color / mirror / Atom feed
From: Dariusz Sosnowski <dsosnowski@nvidia.com>
To: Viacheslav Ovsiienko <viacheslavo@nvidia.com>,
	Ori Kam <orika@nvidia.com>,  Suanming Mou <suanmingm@nvidia.com>,
	Matan Azrad <matan@nvidia.com>
Cc: <dev@dpdk.org>
Subject: [PATCH v3 3/4] net/mlx5: add cross port CT object sharing
Date: Tue, 27 Feb 2024 15:52:23 +0200	[thread overview]
Message-ID: <20240227135224.20066-4-dsosnowski@nvidia.com> (raw)
In-Reply-To: <20240227135224.20066-1-dsosnowski@nvidia.com>

From: Suanming Mou <suanmingm@nvidia.com>

This commit adds cross port CT object sharing.

Shared CT object shares the same DevX objects, but allocate port's
own action locally. Once the CT object is shared between two flows
in different ports, the two flows use their own local action with
the same offset index.

The shared CT object can only be created/updated/queried/destroyed
by host port.

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 doc/guides/rel_notes/release_24_03.rst |   2 +
 drivers/net/mlx5/mlx5_flow_hw.c        | 143 ++++++++++++++-----------
 2 files changed, 83 insertions(+), 62 deletions(-)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 76d2e60f59..23ac6568ac 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -135,6 +135,8 @@ New Features
   * Added support for copy inner fields in HWS flow engine.
   * Added support for sharing indirect action objects of type ``RTE_FLOW_ACTION_TYPE_METER_MARK``
     in HWS flow engine.
+  * Added support for sharing indirect action objects of type ``RTE_FLOW_ACTION_TYPE_CONNTRACK``
+    with HW steering flow engine.
 
 * **Updated Marvell cnxk crypto driver.**
 
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index a8e2c9cc9e..2550e0604f 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -564,7 +564,7 @@ flow_hw_ct_compile(struct rte_eth_dev *dev,
 	struct mlx5_aso_ct_action *ct;
 
 	ct = mlx5_ipool_get(priv->hws_ctpool->cts, MLX5_ACTION_CTX_CT_GET_IDX(idx));
-	if (!ct || mlx5_aso_ct_available(priv->sh, queue, ct))
+	if (!ct || (!priv->shared_host && mlx5_aso_ct_available(priv->sh, queue, ct)))
 		return -1;
 	rule_act->action = priv->hws_ctpool->dr_action;
 	rule_act->aso_ct.offset = ct->offset;
@@ -3845,10 +3845,10 @@ __flow_hw_pull_indir_action_comp(struct rte_eth_dev *dev,
 		if (ret_comp < n_res && priv->hws_mpool)
 			ret_comp += mlx5_aso_pull_completion(&priv->hws_mpool->sq[queue],
 					&res[ret_comp], n_res - ret_comp);
+		if (ret_comp < n_res && priv->hws_ctpool)
+			ret_comp += mlx5_aso_pull_completion(&priv->ct_mng->aso_sqs[queue],
+					&res[ret_comp], n_res - ret_comp);
 	}
-	if (ret_comp < n_res && priv->hws_ctpool)
-		ret_comp += mlx5_aso_pull_completion(&priv->ct_mng->aso_sqs[queue],
-				&res[ret_comp], n_res - ret_comp);
 	if (ret_comp < n_res && priv->quota_ctx.sq)
 		ret_comp += mlx5_aso_pull_completion(&priv->quota_ctx.sq[queue],
 						     &res[ret_comp],
@@ -9027,15 +9027,19 @@ flow_hw_ct_mng_destroy(struct rte_eth_dev *dev,
 }
 
 static void
-flow_hw_ct_pool_destroy(struct rte_eth_dev *dev __rte_unused,
+flow_hw_ct_pool_destroy(struct rte_eth_dev *dev,
 			struct mlx5_aso_ct_pool *pool)
 {
+	struct mlx5_priv *priv = dev->data->dev_private;
+
 	if (pool->dr_action)
 		mlx5dr_action_destroy(pool->dr_action);
-	if (pool->devx_obj)
-		claim_zero(mlx5_devx_cmd_destroy(pool->devx_obj));
-	if (pool->cts)
-		mlx5_ipool_destroy(pool->cts);
+	if (!priv->shared_host) {
+		if (pool->devx_obj)
+			claim_zero(mlx5_devx_cmd_destroy(pool->devx_obj));
+		if (pool->cts)
+			mlx5_ipool_destroy(pool->cts);
+	}
 	mlx5_free(pool);
 }
 
@@ -9059,51 +9063,56 @@ flow_hw_ct_pool_create(struct rte_eth_dev *dev,
 		.type = "mlx5_hw_ct_action",
 	};
 	int reg_id;
-	uint32_t flags;
+	uint32_t flags = 0;
 
-	if (port_attr->flags & RTE_FLOW_PORT_FLAG_SHARE_INDIRECT) {
-		DRV_LOG(ERR, "Connection tracking is not supported "
-			     "in cross vHCA sharing mode");
-		rte_errno = ENOTSUP;
-		return NULL;
-	}
 	pool = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*pool), 0, SOCKET_ID_ANY);
 	if (!pool) {
 		rte_errno = ENOMEM;
 		return NULL;
 	}
-	obj = mlx5_devx_cmd_create_conn_track_offload_obj(priv->sh->cdev->ctx,
-							  priv->sh->cdev->pdn,
-							  log_obj_size);
-	if (!obj) {
-		rte_errno = ENODATA;
-		DRV_LOG(ERR, "Failed to create conn_track_offload_obj using DevX.");
-		goto err;
+	if (!priv->shared_host) {
+		/*
+		 * No need for local cache if CT number is a small number. Since
+		 * flow insertion rate will be very limited in that case. Here let's
+		 * set the number to less than default trunk size 4K.
+		 */
+		if (nb_cts <= cfg.trunk_size) {
+			cfg.per_core_cache = 0;
+			cfg.trunk_size = nb_cts;
+		} else if (nb_cts <= MLX5_HW_IPOOL_SIZE_THRESHOLD) {
+			cfg.per_core_cache = MLX5_HW_IPOOL_CACHE_MIN;
+		}
+		cfg.max_idx = nb_cts;
+		pool->cts = mlx5_ipool_create(&cfg);
+		if (!pool->cts)
+			goto err;
+		obj = mlx5_devx_cmd_create_conn_track_offload_obj(priv->sh->cdev->ctx,
+								  priv->sh->cdev->pdn,
+								  log_obj_size);
+		if (!obj) {
+			rte_errno = ENODATA;
+			DRV_LOG(ERR, "Failed to create conn_track_offload_obj using DevX.");
+			goto err;
+		}
+		pool->devx_obj = obj;
+	} else {
+		struct rte_eth_dev *host_dev = priv->shared_host;
+		struct mlx5_priv *host_priv = host_dev->data->dev_private;
+
+		pool->devx_obj = host_priv->hws_ctpool->devx_obj;
+		pool->cts = host_priv->hws_ctpool->cts;
+		MLX5_ASSERT(pool->cts);
+		MLX5_ASSERT(!port_attr->nb_conn_tracks);
 	}
-	pool->devx_obj = obj;
 	reg_id = mlx5_flow_get_reg_id(dev, MLX5_ASO_CONNTRACK, 0, NULL);
-	flags = MLX5DR_ACTION_FLAG_HWS_RX | MLX5DR_ACTION_FLAG_HWS_TX;
+	flags |= MLX5DR_ACTION_FLAG_HWS_RX | MLX5DR_ACTION_FLAG_HWS_TX;
 	if (priv->sh->config.dv_esw_en && priv->master)
 		flags |= MLX5DR_ACTION_FLAG_HWS_FDB;
 	pool->dr_action = mlx5dr_action_create_aso_ct(priv->dr_ctx,
-						      (struct mlx5dr_devx_obj *)obj,
+						      (struct mlx5dr_devx_obj *)pool->devx_obj,
 						      reg_id - REG_C_0, flags);
 	if (!pool->dr_action)
 		goto err;
-	/*
-	 * No need for local cache if CT number is a small number. Since
-	 * flow insertion rate will be very limited in that case. Here let's
-	 * set the number to less than default trunk size 4K.
-	 */
-	if (nb_cts <= cfg.trunk_size) {
-		cfg.per_core_cache = 0;
-		cfg.trunk_size = nb_cts;
-	} else if (nb_cts <= MLX5_HW_IPOOL_SIZE_THRESHOLD) {
-		cfg.per_core_cache = MLX5_HW_IPOOL_CACHE_MIN;
-	}
-	pool->cts = mlx5_ipool_create(&cfg);
-	if (!pool->cts)
-		goto err;
 	pool->sq = priv->ct_mng->aso_sqs;
 	/* Assign the last extra ASO SQ as public SQ. */
 	pool->shared_sq = &priv->ct_mng->aso_sqs[priv->nb_queue - 1];
@@ -9980,14 +9989,16 @@ flow_hw_configure(struct rte_eth_dev *dev,
 	if (!priv->shared_host)
 		flow_hw_create_send_to_kernel_actions(priv);
 	if (port_attr->nb_conn_tracks || (host_priv && host_priv->hws_ctpool)) {
-		mem_size = sizeof(struct mlx5_aso_sq) * nb_q_updated +
-			   sizeof(*priv->ct_mng);
-		priv->ct_mng = mlx5_malloc(MLX5_MEM_ZERO, mem_size,
-					   RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
-		if (!priv->ct_mng)
-			goto err;
-		if (mlx5_aso_ct_queue_init(priv->sh, priv->ct_mng, nb_q_updated))
-			goto err;
+		if (!priv->shared_host) {
+			mem_size = sizeof(struct mlx5_aso_sq) * nb_q_updated +
+				sizeof(*priv->ct_mng);
+			priv->ct_mng = mlx5_malloc(MLX5_MEM_ZERO, mem_size,
+						RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
+			if (!priv->ct_mng)
+				goto err;
+			if (mlx5_aso_ct_queue_init(priv->sh, priv->ct_mng, nb_q_updated))
+				goto err;
+		}
 		priv->hws_ctpool = flow_hw_ct_pool_create(dev, port_attr);
 		if (!priv->hws_ctpool)
 			goto err;
@@ -10210,17 +10221,20 @@ flow_hw_clear_port_info(struct rte_eth_dev *dev)
 }
 
 static int
-flow_hw_conntrack_destroy(struct rte_eth_dev *dev __rte_unused,
+flow_hw_conntrack_destroy(struct rte_eth_dev *dev,
 			  uint32_t idx,
 			  struct rte_flow_error *error)
 {
-	uint16_t owner = (uint16_t)MLX5_ACTION_CTX_CT_GET_OWNER(idx);
 	uint32_t ct_idx = MLX5_ACTION_CTX_CT_GET_IDX(idx);
-	struct rte_eth_dev *owndev = &rte_eth_devices[owner];
-	struct mlx5_priv *priv = owndev->data->dev_private;
+	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_aso_ct_pool *pool = priv->hws_ctpool;
 	struct mlx5_aso_ct_action *ct;
 
+	if (priv->shared_host)
+		return rte_flow_error_set(error, ENOTSUP,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"CT destruction is not allowed to guest port");
 	ct = mlx5_ipool_get(pool->cts, ct_idx);
 	if (!ct) {
 		return rte_flow_error_set(error, EINVAL,
@@ -10243,14 +10257,13 @@ flow_hw_conntrack_query(struct rte_eth_dev *dev, uint32_t queue, uint32_t idx,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_aso_ct_pool *pool = priv->hws_ctpool;
 	struct mlx5_aso_ct_action *ct;
-	uint16_t owner = (uint16_t)MLX5_ACTION_CTX_CT_GET_OWNER(idx);
 	uint32_t ct_idx;
 
-	if (owner != PORT_ID(priv))
-		return rte_flow_error_set(error, EACCES,
+	if (priv->shared_host)
+		return rte_flow_error_set(error, ENOTSUP,
 				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 				NULL,
-				"Can't query CT object owned by another port");
+				"CT query is not allowed to guest port");
 	ct_idx = MLX5_ACTION_CTX_CT_GET_IDX(idx);
 	ct = mlx5_ipool_get(pool->cts, ct_idx);
 	if (!ct) {
@@ -10280,15 +10293,14 @@ flow_hw_conntrack_update(struct rte_eth_dev *dev, uint32_t queue,
 	struct mlx5_aso_ct_pool *pool = priv->hws_ctpool;
 	struct mlx5_aso_ct_action *ct;
 	const struct rte_flow_action_conntrack *new_prf;
-	uint16_t owner = (uint16_t)MLX5_ACTION_CTX_CT_GET_OWNER(idx);
 	uint32_t ct_idx;
 	int ret = 0;
 
-	if (PORT_ID(priv) != owner)
-		return rte_flow_error_set(error, EACCES,
-					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-					  NULL,
-					  "Can't update CT object owned by another port");
+	if (priv->shared_host)
+		return rte_flow_error_set(error, ENOTSUP,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"CT update is not allowed to guest port");
 	ct_idx = MLX5_ACTION_CTX_CT_GET_IDX(idx);
 	ct = mlx5_ipool_get(pool->cts, ct_idx);
 	if (!ct) {
@@ -10338,6 +10350,13 @@ flow_hw_conntrack_create(struct rte_eth_dev *dev, uint32_t queue,
 	int ret;
 	bool async = !!(queue != MLX5_HW_INV_QUEUE);
 
+	if (priv->shared_host) {
+		rte_flow_error_set(error, ENOTSUP,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"CT create is not allowed to guest port");
+		return NULL;
+	}
 	if (!pool) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-- 
2.25.1


  parent reply	other threads:[~2024-02-27 13:53 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-21 10:01 [PATCH 0/4] net/mlx5: connection tracking changes Dariusz Sosnowski
2024-02-21 10:01 ` [PATCH 1/4] net/mlx5: fix conntrack action handle representation Dariusz Sosnowski
2024-02-21 10:01 ` [PATCH 2/4] net/mlx5: fix connection tracking action validation Dariusz Sosnowski
2024-02-21 10:01 ` [PATCH 3/4] net/mlx5: add cross port CT object sharing Dariusz Sosnowski
2024-02-21 10:01 ` [PATCH 4/4] net/mlx5: remove port from conntrack handle representation Dariusz Sosnowski
2024-02-23 14:23 ` [PATCH v2 0/4] net/mlx5: connection tracking changes Dariusz Sosnowski
2024-02-23 14:23   ` [PATCH v2 1/4] net/mlx5: fix conntrack action handle representation Dariusz Sosnowski
2024-02-23 14:23   ` [PATCH v2 2/4] net/mlx5: fix connection tracking action validation Dariusz Sosnowski
2024-02-23 14:23   ` [PATCH v2 3/4] net/mlx5: add cross port CT object sharing Dariusz Sosnowski
2024-02-23 14:23   ` [PATCH v2 4/4] net/mlx5: remove port from conntrack handle representation Dariusz Sosnowski
2024-02-27 13:52   ` [PATCH v3 0/4] net/mlx5: connection tracking changes Dariusz Sosnowski
2024-02-27 13:52     ` [PATCH v3 1/4] net/mlx5: fix conntrack action handle representation Dariusz Sosnowski
2024-02-27 13:52     ` [PATCH v3 2/4] net/mlx5: fix connection tracking action validation Dariusz Sosnowski
2024-02-27 13:52     ` Dariusz Sosnowski [this message]
2024-02-27 13:52     ` [PATCH v3 4/4] net/mlx5: remove port from conntrack handle representation Dariusz Sosnowski
2024-02-28 10:12     ` [PATCH v3 0/4] net/mlx5: connection tracking changes Raslan Darawsheh

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=20240227135224.20066-4-dsosnowski@nvidia.com \
    --to=dsosnowski@nvidia.com \
    --cc=dev@dpdk.org \
    --cc=matan@nvidia.com \
    --cc=orika@nvidia.com \
    --cc=suanmingm@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).