DPDK patches and discussions
 help / color / mirror / Atom feed
From: Suanming Mou <suanmingm@nvidia.com>
To: <viacheslavo@nvidia.com>, <matan@nvidia.com>
Cc: <rasland@nvidia.com>, <orika@nvidia.com>, <dev@dpdk.org>
Subject: [PATCH 03/13] net/mlx5: add port flow configuration
Date: Thu, 10 Feb 2022 18:29:16 +0200	[thread overview]
Message-ID: <20220210162926.20436-4-suanmingm@nvidia.com> (raw)
In-Reply-To: <20220210162926.20436-1-suanmingm@nvidia.com>

The hardware steering is backend to support rte_flow_q API in mlx5
PMD. The port configuration function creates the queues and needed
flow management resources.

The PMD layer configuration function allocates the queues' context
and per-queue job descriptor. The job descriptor size is equal to
the queue size, and the job descriptors will be popped from LIFO
to convey the flow information during flow insertion/destruction.
So when polling the result, the flow information will be extracted
from the descriptor and then the job descriptor will be push back
to the LIFO.

The commit creates the flow port queue and the job descriptors.

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
---
 drivers/net/mlx5/mlx5.c         |   3 +
 drivers/net/mlx5/mlx5.h         |  26 ++++++-
 drivers/net/mlx5/mlx5_flow.c    |  37 +++++++++
 drivers/net/mlx5/mlx5_flow.h    |   9 +++
 drivers/net/mlx5/mlx5_flow_hw.c | 132 ++++++++++++++++++++++++++++++++
 5 files changed, 206 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index a4826a583b..f1933fd253 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1567,6 +1567,9 @@ mlx5_dev_close(struct rte_eth_dev *dev)
 	/* Free the eCPRI flex parser resource. */
 	mlx5_flex_parser_ecpri_release(dev);
 	mlx5_flex_item_port_cleanup(dev);
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
+	flow_hw_resource_release(dev);
+#endif
 	if (priv->rxq_privs != NULL) {
 		/* XXX race condition if mlx5_rx_burst() is still running. */
 		rte_delay_us_sleep(1000);
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index f3b991e549..31a13ca69a 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -33,7 +33,7 @@
 #include "mlx5_utils.h"
 #include "mlx5_os.h"
 #include "mlx5_autoconf.h"
-
+#include "mlx5dr.h"
 
 #define MLX5_SH(dev) (((struct mlx5_priv *)(dev)->data->dev_private)->sh)
 
@@ -324,6 +324,26 @@ struct mlx5_lb_ctx {
 	uint16_t refcnt; /* Reference count for representors. */
 };
 
+/* HW steering queue job descriptor type. */
+enum {
+	MLX5_HW_Q_JOB_TYPE_CREATE, /* Flow create job type. */
+	MLX5_HW_Q_JOB_TYPE_DESTROY, /* Flow destroy job type. */
+};
+
+/* HW steering flow management job descriptor. */
+struct mlx5_hw_q_job {
+	uint32_t type; /* Job type. */
+	struct rte_flow *flow; /* Flow attached to the job. */
+	void *user_data; /* Job user data. */
+};
+
+/* HW steering job descriptor LIFO header . */
+struct mlx5_hw_q {
+	uint32_t job_idx; /* Free job index. */
+	uint32_t size; /* LIFO size. */
+	struct mlx5_hw_q_job **job; /* LIFO pointer. */
+} __rte_cache_aligned;
+
 #define MLX5_COUNTERS_PER_POOL 512
 #define MLX5_MAX_PENDING_QUERIES 4
 #define MLX5_CNT_CONTAINER_RESIZE 64
@@ -1480,6 +1500,10 @@ struct mlx5_priv {
 	struct mlx5_flex_item flex_item[MLX5_PORT_FLEX_ITEM_NUM];
 	/* Flex items have been created on the port. */
 	uint32_t flex_item_map; /* Map of allocated flex item elements. */
+	struct mlx5dr_context *dr_ctx; /**< HW steering DR context. */
+	uint32_t nb_queue; /* HW steering queue number. */
+	/* HW steering queue polling mechanism job descriptor LIFO. */
+	struct mlx5_hw_q *hw_q;
 };
 
 #define PORT_ID(priv) ((priv)->dev_data->port_id)
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 21d17aca44..5ff96642b4 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -805,6 +805,12 @@ static int
 mlx5_flow_flex_item_release(struct rte_eth_dev *dev,
 			    const struct rte_flow_item_flex_handle *handle,
 			    struct rte_flow_error *error);
+static int
+mlx5_flow_port_configure(struct rte_eth_dev *dev,
+			 const struct rte_flow_port_attr *port_attr,
+			 uint16_t nb_queue,
+			 const struct rte_flow_queue_attr *queue_attr[],
+			 struct rte_flow_error *err);
 
 static const struct rte_flow_ops mlx5_flow_ops = {
 	.validate = mlx5_flow_validate,
@@ -826,6 +832,7 @@ static const struct rte_flow_ops mlx5_flow_ops = {
 	.get_restore_info = mlx5_flow_tunnel_get_restore_info,
 	.flex_item_create = mlx5_flow_flex_item_create,
 	.flex_item_release = mlx5_flow_flex_item_release,
+	.configure = mlx5_flow_port_configure,
 };
 
 /* Tunnel information. */
@@ -7814,6 +7821,36 @@ mlx5_counter_query(struct rte_eth_dev *dev, uint32_t cnt,
 	return -ENOTSUP;
 }
 
+/**
+ * Configure port HWS resources.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] port_attr
+ *   Port configuration attributes.
+ * @param[in] nb_queue
+ *   Number of queue.
+ * @param[in] queue_attr
+ *   Array that holds attributes for each flow queue.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_port_configure(struct rte_eth_dev *dev,
+			 const struct rte_flow_port_attr *port_attr,
+			 uint16_t nb_queue,
+			 const struct rte_flow_queue_attr *queue_attr[],
+			 struct rte_flow_error *err)
+{
+	const struct mlx5_flow_driver_ops *fops =
+			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
+
+	return fops->configure(dev, port_attr, nb_queue, queue_attr, err);
+}
+
 /**
  * Allocate a new memory for the counter values wrapped by all the needed
  * management.
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 26f5d97a7d..731478ff05 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1257,6 +1257,12 @@ typedef int (*mlx5_flow_item_update_t)
 			 const struct rte_flow_item_flex_handle *handle,
 			 const struct rte_flow_item_flex_conf *conf,
 			 struct rte_flow_error *error);
+typedef int (*mlx5_flow_port_configure_t)
+			(struct rte_eth_dev *dev,
+			 const struct rte_flow_port_attr *port_attr,
+			 uint16_t nb_queue,
+			 const struct rte_flow_queue_attr *queue_attr[],
+			 struct rte_flow_error *err);
 
 struct mlx5_flow_driver_ops {
 	mlx5_flow_validate_t validate;
@@ -1295,6 +1301,7 @@ struct mlx5_flow_driver_ops {
 	mlx5_flow_item_create_t item_create;
 	mlx5_flow_item_release_t item_release;
 	mlx5_flow_item_update_t item_update;
+	mlx5_flow_port_configure_t configure;
 };
 
 /* mlx5_flow.c */
@@ -1767,4 +1774,6 @@ const struct mlx5_flow_tunnel *
 mlx5_get_tof(const struct rte_flow_item *items,
 	     const struct rte_flow_action *actions,
 	     enum mlx5_tof_rule_type *rule_type);
+void
+flow_hw_resource_release(struct rte_eth_dev *dev);
 #endif /* RTE_PMD_MLX5_FLOW_H_ */
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 33875c7d08..4194f81ee9 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -4,10 +4,142 @@
 
 #include <rte_flow.h>
 
+#include <mlx5_malloc.h>
+#include "mlx5_defs.h"
 #include "mlx5_flow.h"
 
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 
 const struct mlx5_flow_driver_ops mlx5_flow_hw_drv_ops;
 
+/**
+ * Configure port HWS resources.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] port_attr
+ *   Port configuration attributes.
+ * @param[in] nb_queue
+ *   Number of queue.
+ * @param[in] queue_attr
+ *   Array that holds attributes for each flow queue.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_hw_configure(struct rte_eth_dev *dev,
+		  const struct rte_flow_port_attr *port_attr,
+		  uint16_t nb_queue,
+		  const struct rte_flow_queue_attr *queue_attr[],
+		  struct rte_flow_error *error)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5dr_context *dr_ctx = NULL;
+	struct mlx5dr_context_attr dr_ctx_attr = {0};
+	struct mlx5_hw_q *hw_q;
+	struct mlx5_hw_q_job *job = NULL;
+	uint32_t mem_size, i, j;
+
+	if (!port_attr || !nb_queue || !queue_attr) {
+		rte_errno = EINVAL;
+		goto err;
+	}
+	/* In case re-configuring, release existing context at first. */
+	if (priv->dr_ctx) {
+		/* */
+		for (i = 0; i < nb_queue; i++) {
+			hw_q = &priv->hw_q[i];
+			/* Make sure all queues are empty. */
+			if (hw_q->size != hw_q->job_idx) {
+				rte_errno = EBUSY;
+				goto err;
+			}
+		}
+		flow_hw_resource_release(dev);
+	}
+	/* Allocate the queue job descriptor LIFO. */
+	mem_size = sizeof(priv->hw_q[0]) * nb_queue;
+	for (i = 0; i < nb_queue; i++) {
+		/*
+		 * Check if the queues' size are all the same as the
+		 * limitation from HWS layer.
+		 */
+		if (queue_attr[i]->size != queue_attr[0]->size) {
+			rte_errno = EINVAL;
+			goto err;
+		}
+		mem_size += (sizeof(struct mlx5_hw_q_job *) +
+			    sizeof(struct mlx5_hw_q_job)) *
+			    queue_attr[0]->size;
+	}
+	priv->hw_q = mlx5_malloc(MLX5_MEM_ZERO, mem_size,
+				 64, SOCKET_ID_ANY);
+	if (!priv->hw_q) {
+		rte_errno = ENOMEM;
+		goto err;
+	}
+	for (i = 0; i < nb_queue; i++) {
+		priv->hw_q[i].job_idx = queue_attr[i]->size;
+		priv->hw_q[i].size = queue_attr[i]->size;
+		if (i == 0)
+			priv->hw_q[i].job = (struct mlx5_hw_q_job **)
+					    &priv->hw_q[nb_queue];
+		else
+			priv->hw_q[i].job = (struct mlx5_hw_q_job **)
+					    &job[queue_attr[i - 1]->size];
+		job = (struct mlx5_hw_q_job *)
+		      &priv->hw_q[i].job[queue_attr[i]->size];
+		for (j = 0; j < queue_attr[i]->size; j++)
+			priv->hw_q[i].job[j] = &job[j];
+	}
+	dr_ctx_attr.pd = priv->sh->cdev->pd;
+	dr_ctx_attr.queues = nb_queue;
+	/* Queue size should all be the same. Take the first one. */
+	dr_ctx_attr.queue_size = queue_attr[0]->size;
+	dr_ctx = mlx5dr_context_open(priv->sh->cdev->ctx, &dr_ctx_attr);
+	/* rte_errno has been updated by HWS layer. */
+	if (!dr_ctx)
+		goto err;
+	priv->dr_ctx = dr_ctx;
+	priv->nb_queue = nb_queue;
+	return 0;
+err:
+	if (dr_ctx)
+		claim_zero(mlx5dr_context_close(dr_ctx));
+	if (priv->hw_q) {
+		mlx5_free(priv->hw_q);
+		priv->hw_q = NULL;
+	}
+	return rte_flow_error_set(error, rte_errno,
+				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  "fail to configure port");
+}
+
+/**
+ * Release HWS resources.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ */
+void
+flow_hw_resource_release(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+
+	if (!priv->dr_ctx)
+		return;
+	mlx5_free(priv->hw_q);
+	priv->hw_q = NULL;
+	claim_zero(mlx5dr_context_close(priv->dr_ctx));
+	priv->dr_ctx = NULL;
+	priv->nb_queue = 0;
+}
+
+const struct mlx5_flow_driver_ops mlx5_flow_hw_drv_ops = {
+	.configure = flow_hw_configure,
+};
+
 #endif
-- 
2.25.1


  parent reply	other threads:[~2022-02-10 16:30 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-10 16:29 [PATCH 00/13] net/mlx5: add hardware steering Suanming Mou
2022-02-10 16:29 ` [PATCH 01/13] net/mlx5: introduce hardware steering operation Suanming Mou
2022-02-10 16:29 ` [PATCH 02/13] net/mlx5: introduce hardware steering enable routine Suanming Mou
2022-02-10 16:29 ` Suanming Mou [this message]
2022-02-10 16:29 ` [PATCH 04/13] net/mlx5: add pattern template management Suanming Mou
2022-02-10 16:29 ` [PATCH 05/13] net/mlx5: add action " Suanming Mou
2022-02-10 16:29 ` [PATCH 06/13] net/mlx5: add table management Suanming Mou
2022-02-10 16:29 ` [PATCH 07/13] net/mlx5: add basic flow queue operation Suanming Mou
2022-02-10 16:29 ` [PATCH 08/13] net/mlx5: add flow flush function Suanming Mou
2022-02-10 16:29 ` [PATCH 09/13] net/mlx5: add flow jump action Suanming Mou
2022-02-10 16:29 ` [PATCH 10/13] net/mlx5: add queue and RSS action Suanming Mou
2022-02-10 16:29 ` [PATCH 11/13] net/mlx5: add mark action Suanming Mou
2022-02-10 16:29 ` [PATCH 12/13] net/mlx5: add indirect action Suanming Mou
2022-02-10 16:29 ` [PATCH 13/13] net/mlx5: add header reformat action Suanming Mou
2022-02-22  8:51 ` [PATCH v2 00/14] net/mlx5: add hardware steering Suanming Mou
2022-02-22  8:51   ` [PATCH v2 01/14] net/mlx5: introduce hardware steering operation Suanming Mou
2022-02-22  8:51   ` [PATCH v2 02/14] net/mlx5: add HW steering low-level abstract code Suanming Mou
2022-02-22  8:51   ` [PATCH v2 03/14] net/mlx5: introduce hardware steering enable routine Suanming Mou
2022-02-22  8:51   ` [PATCH v2 04/14] net/mlx5: add port flow configuration Suanming Mou
2022-02-22  8:51   ` [PATCH v2 05/14] net/mlx5: add pattern template management Suanming Mou
2022-02-22  8:51   ` [PATCH v2 06/14] net/mlx5: add action " Suanming Mou
2022-02-22  8:51   ` [PATCH v2 07/14] net/mlx5: add table management Suanming Mou
2022-02-22  8:51   ` [PATCH v2 08/14] net/mlx5: add basic flow queue operation Suanming Mou
2022-02-22  8:51   ` [PATCH v2 09/14] net/mlx5: add flow flush function Suanming Mou
2022-02-22  8:51   ` [PATCH v2 10/14] net/mlx5: add flow jump action Suanming Mou
2022-02-22  8:51   ` [PATCH v2 11/14] net/mlx5: add queue and RSS action Suanming Mou
2022-02-22  8:51   ` [PATCH v2 12/14] net/mlx5: add mark action Suanming Mou
2022-02-22  8:51   ` [PATCH v2 13/14] net/mlx5: add indirect action Suanming Mou
2022-02-22  8:51   ` [PATCH v2 14/14] net/mlx5: add header reformat action Suanming Mou
2022-02-24  3:10 ` [PATCH v3 00/14] net/mlx5: add hardware steering Suanming Mou
2022-02-24  3:10   ` [PATCH v3 01/14] net/mlx5: introduce hardware steering operation Suanming Mou
2022-02-24  3:10   ` [PATCH v3 02/14] net/mlx5: add HW steering low-level abstract code Suanming Mou
2022-02-24  3:10   ` [PATCH v3 03/14] net/mlx5: introduce hardware steering enable routine Suanming Mou
2022-02-24  3:10   ` [PATCH v3 04/14] net/mlx5: add port flow configuration Suanming Mou
2022-02-24  3:10   ` [PATCH v3 05/14] net/mlx5: add pattern template management Suanming Mou
2022-02-24  3:10   ` [PATCH v3 06/14] net/mlx5: add action " Suanming Mou
2022-02-24  3:10   ` [PATCH v3 07/14] net/mlx5: add table management Suanming Mou
2022-02-24  3:10   ` [PATCH v3 08/14] net/mlx5: add basic flow queue operation Suanming Mou
2022-02-24  3:10   ` [PATCH v3 09/14] net/mlx5: add flow flush function Suanming Mou
2022-02-24  3:10   ` [PATCH v3 10/14] net/mlx5: add flow jump action Suanming Mou
2022-02-24  3:10   ` [PATCH v3 11/14] net/mlx5: add queue and RSS action Suanming Mou
2022-02-24  3:10   ` [PATCH v3 12/14] net/mlx5: add mark action Suanming Mou
2022-02-24  3:10   ` [PATCH v3 13/14] net/mlx5: add indirect action Suanming Mou
2022-02-24  3:10   ` [PATCH v3 14/14] net/mlx5: add header reformat action Suanming Mou
2022-02-24 13:40 ` [PATCH v4 00/14] net/mlx5: add hardware steering Suanming Mou
2022-02-24 13:40   ` [PATCH v4 01/14] net/mlx5: introduce hardware steering operation Suanming Mou
2022-02-24 13:40   ` [PATCH v4 02/14] net/mlx5: add HW steering low-level abstract code Suanming Mou
2022-02-24 22:57     ` Ferruh Yigit
2022-02-24 23:49       ` Suanming Mou
2022-02-24 13:40   ` [PATCH v4 03/14] net/mlx5: introduce hardware steering enable routine Suanming Mou
2022-02-24 13:40   ` [PATCH v4 04/14] net/mlx5: add port flow configuration Suanming Mou
2022-02-24 13:40   ` [PATCH v4 05/14] net/mlx5: add pattern template management Suanming Mou
2022-02-24 13:40   ` [PATCH v4 06/14] net/mlx5: add action " Suanming Mou
2022-02-24 13:40   ` [PATCH v4 07/14] net/mlx5: add table management Suanming Mou
2022-02-24 13:40   ` [PATCH v4 08/14] net/mlx5: add basic flow queue operation Suanming Mou
2022-02-24 13:40   ` [PATCH v4 09/14] net/mlx5: add flow flush function Suanming Mou
2022-02-24 13:40   ` [PATCH v4 10/14] net/mlx5: add flow jump action Suanming Mou
2022-02-24 13:40   ` [PATCH v4 11/14] net/mlx5: add queue and RSS action Suanming Mou
2022-02-24 13:40   ` [PATCH v4 12/14] net/mlx5: add mark action Suanming Mou
2022-02-24 13:40   ` [PATCH v4 13/14] net/mlx5: add indirect action Suanming Mou
2022-02-24 13:40   ` [PATCH v4 14/14] net/mlx5: add header reformat action Suanming Mou
2022-02-24 21:12   ` [PATCH v4 00/14] net/mlx5: add hardware steering 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=20220210162926.20436-4-suanmingm@nvidia.com \
    --to=suanmingm@nvidia.com \
    --cc=dev@dpdk.org \
    --cc=matan@nvidia.com \
    --cc=orika@nvidia.com \
    --cc=rasland@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).