DPDK patches and discussions
 help / color / mirror / Atom feed
From: Xueming Li <xuemingl@nvidia.com>
To: <dev@dpdk.org>, Maxime Coquelin <maxime.coquelin@redhat.com>
Cc: <xuemingl@nvidia.com>
Subject: [PATCH v3 5/7] vdpa/mlx5: cache and reuse hardware resources
Date: Sun, 8 May 2022 17:25:52 +0300	[thread overview]
Message-ID: <20220508142554.560354-6-xuemingl@nvidia.com> (raw)
In-Reply-To: <20220508142554.560354-1-xuemingl@nvidia.com>

During device suspend and resume, resources are not changed normally.
When huge resources were allocated to VM, like huge memory size or lots
of queues, time spent on release and recreate became significant.

To speed up, this patch reuses resources like VM MR and VirtQ memory if
not changed.

Signed-off-by: Xueming Li <xuemingl@nvidia.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/vdpa/mlx5/mlx5_vdpa.c       | 11 ++++-
 drivers/vdpa/mlx5/mlx5_vdpa.h       | 12 ++++-
 drivers/vdpa/mlx5/mlx5_vdpa_mem.c   | 27 ++++++++++-
 drivers/vdpa/mlx5/mlx5_vdpa_virtq.c | 73 +++++++++++++++++++++--------
 4 files changed, 99 insertions(+), 24 deletions(-)

diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c
index 4408aeccfbd..fb5d9276621 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa.c
@@ -241,6 +241,13 @@ mlx5_vdpa_mtu_set(struct mlx5_vdpa_priv *priv)
 	return kern_mtu == vhost_mtu ? 0 : -1;
 }
 
+static void
+mlx5_vdpa_dev_cache_clean(struct mlx5_vdpa_priv *priv)
+{
+	mlx5_vdpa_virtqs_cleanup(priv);
+	mlx5_vdpa_mem_dereg(priv);
+}
+
 static int
 mlx5_vdpa_dev_close(int vid)
 {
@@ -260,7 +267,8 @@ mlx5_vdpa_dev_close(int vid)
 	}
 	mlx5_vdpa_steer_unset(priv);
 	mlx5_vdpa_virtqs_release(priv);
-	mlx5_vdpa_mem_dereg(priv);
+	if (priv->lm_mr.addr)
+		mlx5_os_wrapped_mkey_destroy(&priv->lm_mr);
 	priv->state = MLX5_VDPA_STATE_PROBED;
 	priv->vid = 0;
 	/* The mutex may stay locked after event thread cancel - initiate it. */
@@ -663,6 +671,7 @@ mlx5_vdpa_release_dev_resources(struct mlx5_vdpa_priv *priv)
 {
 	uint32_t i;
 
+	mlx5_vdpa_dev_cache_clean(priv);
 	mlx5_vdpa_event_qp_global_release(priv);
 	mlx5_vdpa_err_event_unset(priv);
 	if (priv->steer.tbl)
diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.h b/drivers/vdpa/mlx5/mlx5_vdpa.h
index e0ba20b953c..540bf87a352 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/mlx5_vdpa.h
@@ -289,13 +289,21 @@ int mlx5_vdpa_err_event_setup(struct mlx5_vdpa_priv *priv);
 void mlx5_vdpa_err_event_unset(struct mlx5_vdpa_priv *priv);
 
 /**
- * Release a virtq and all its related resources.
+ * Release virtqs and resources except that to be reused.
  *
  * @param[in] priv
  *   The vdpa driver private structure.
  */
 void mlx5_vdpa_virtqs_release(struct mlx5_vdpa_priv *priv);
 
+/**
+ * Cleanup cached resources of all virtqs.
+ *
+ * @param[in] priv
+ *   The vdpa driver private structure.
+ */
+void mlx5_vdpa_virtqs_cleanup(struct mlx5_vdpa_priv *priv);
+
 /**
  * Create all the HW virtqs resources and all their related resources.
  *
@@ -323,7 +331,7 @@ int mlx5_vdpa_virtqs_prepare(struct mlx5_vdpa_priv *priv);
 int mlx5_vdpa_virtq_enable(struct mlx5_vdpa_priv *priv, int index, int enable);
 
 /**
- * Unset steering and release all its related resources- stop traffic.
+ * Unset steering - stop traffic.
  *
  * @param[in] priv
  *   The vdpa driver private structure.
diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_mem.c b/drivers/vdpa/mlx5/mlx5_vdpa_mem.c
index 62f5530e91d..d6e3dd664b5 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa_mem.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa_mem.c
@@ -32,8 +32,6 @@ mlx5_vdpa_mem_dereg(struct mlx5_vdpa_priv *priv)
 		entry = next;
 	}
 	SLIST_INIT(&priv->mr_list);
-	if (priv->lm_mr.addr)
-		mlx5_os_wrapped_mkey_destroy(&priv->lm_mr);
 	if (priv->vmem) {
 		free(priv->vmem);
 		priv->vmem = NULL;
@@ -149,6 +147,23 @@ mlx5_vdpa_vhost_mem_regions_prepare(int vid, uint8_t *mode, uint64_t *mem_size,
 	return mem;
 }
 
+static int
+mlx5_vdpa_mem_cmp(struct rte_vhost_memory *mem1, struct rte_vhost_memory *mem2)
+{
+	uint32_t i;
+
+	if (mem1->nregions != mem2->nregions)
+		return -1;
+	for (i = 0; i < mem1->nregions; i++) {
+		if (mem1->regions[i].guest_phys_addr !=
+		    mem2->regions[i].guest_phys_addr)
+			return -1;
+		if (mem1->regions[i].size != mem2->regions[i].size)
+			return -1;
+	}
+	return 0;
+}
+
 #define KLM_SIZE_MAX_ALIGN(sz) ((sz) > MLX5_MAX_KLM_BYTE_COUNT ? \
 				MLX5_MAX_KLM_BYTE_COUNT : (sz))
 
@@ -191,6 +206,14 @@ mlx5_vdpa_mem_register(struct mlx5_vdpa_priv *priv)
 
 	if (!mem)
 		return -rte_errno;
+	if (priv->vmem != NULL) {
+		if (mlx5_vdpa_mem_cmp(mem, priv->vmem) == 0) {
+			/* VM memory not changed, reuse resources. */
+			free(mem);
+			return 0;
+		}
+		mlx5_vdpa_mem_dereg(priv);
+	}
 	priv->vmem = mem;
 	for (i = 0; i < mem->nregions; i++) {
 		reg = &mem->regions[i];
diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
index 5ab63930ce8..0dfeb8fce24 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
@@ -66,10 +66,33 @@ mlx5_vdpa_virtq_kick_handler(void *cb_arg)
 	DRV_LOG(DEBUG, "Ring virtq %u doorbell.", virtq->index);
 }
 
+/* Release cached VQ resources. */
+void
+mlx5_vdpa_virtqs_cleanup(struct mlx5_vdpa_priv *priv)
+{
+	unsigned int i, j;
+
+	for (i = 0; i < priv->caps.max_num_virtio_queues * 2; i++) {
+		struct mlx5_vdpa_virtq *virtq = &priv->virtqs[i];
+
+		for (j = 0; j < RTE_DIM(virtq->umems); ++j) {
+			if (virtq->umems[j].obj) {
+				claim_zero(mlx5_glue->devx_umem_dereg
+							(virtq->umems[j].obj));
+				virtq->umems[j].obj = NULL;
+			}
+			if (virtq->umems[j].buf) {
+				rte_free(virtq->umems[j].buf);
+				virtq->umems[j].buf = NULL;
+			}
+			virtq->umems[j].size = 0;
+		}
+	}
+}
+
 static int
 mlx5_vdpa_virtq_unset(struct mlx5_vdpa_virtq *virtq)
 {
-	unsigned int i;
 	int ret = -EAGAIN;
 
 	if (rte_intr_fd_get(virtq->intr_handle) >= 0) {
@@ -94,13 +117,6 @@ mlx5_vdpa_virtq_unset(struct mlx5_vdpa_virtq *virtq)
 		claim_zero(mlx5_devx_cmd_destroy(virtq->virtq));
 	}
 	virtq->virtq = NULL;
-	for (i = 0; i < RTE_DIM(virtq->umems); ++i) {
-		if (virtq->umems[i].obj)
-			claim_zero(mlx5_glue->devx_umem_dereg
-							 (virtq->umems[i].obj));
-		rte_free(virtq->umems[i].buf);
-	}
-	memset(&virtq->umems, 0, sizeof(virtq->umems));
 	if (virtq->eqp.fw_qp)
 		mlx5_vdpa_event_qp_destroy(&virtq->eqp);
 	virtq->notifier_state = MLX5_VDPA_NOTIFIER_STATE_DISABLED;
@@ -120,7 +136,6 @@ mlx5_vdpa_virtqs_release(struct mlx5_vdpa_priv *priv)
 			claim_zero(mlx5_devx_cmd_destroy(virtq->counters));
 	}
 	priv->features = 0;
-	memset(priv->virtqs, 0, sizeof(*virtq) * priv->nr_virtqs);
 	priv->nr_virtqs = 0;
 }
 
@@ -215,6 +230,8 @@ mlx5_vdpa_virtq_setup(struct mlx5_vdpa_priv *priv, int index)
 	ret = rte_vhost_get_vhost_vring(priv->vid, index, &vq);
 	if (ret)
 		return -1;
+	if (vq.size == 0)
+		return 0;
 	virtq->index = index;
 	virtq->vq_size = vq.size;
 	attr.tso_ipv4 = !!(priv->features & (1ULL << VIRTIO_NET_F_HOST_TSO4));
@@ -259,24 +276,42 @@ mlx5_vdpa_virtq_setup(struct mlx5_vdpa_priv *priv, int index)
 	}
 	/* Setup 3 UMEMs for each virtq. */
 	for (i = 0; i < RTE_DIM(virtq->umems); ++i) {
-		virtq->umems[i].size = priv->caps.umems[i].a * vq.size +
-							  priv->caps.umems[i].b;
-		virtq->umems[i].buf = rte_zmalloc(__func__,
-						  virtq->umems[i].size, 4096);
-		if (!virtq->umems[i].buf) {
+		uint32_t size;
+		void *buf;
+		struct mlx5dv_devx_umem *obj;
+
+		size = priv->caps.umems[i].a * vq.size + priv->caps.umems[i].b;
+		if (virtq->umems[i].size == size &&
+		    virtq->umems[i].obj != NULL) {
+			/* Reuse registered memory. */
+			memset(virtq->umems[i].buf, 0, size);
+			goto reuse;
+		}
+		if (virtq->umems[i].obj)
+			claim_zero(mlx5_glue->devx_umem_dereg
+				   (virtq->umems[i].obj));
+		if (virtq->umems[i].buf)
+			rte_free(virtq->umems[i].buf);
+		virtq->umems[i].size = 0;
+		virtq->umems[i].obj = NULL;
+		virtq->umems[i].buf = NULL;
+		buf = rte_zmalloc(__func__, size, 4096);
+		if (buf == NULL) {
 			DRV_LOG(ERR, "Cannot allocate umem %d memory for virtq"
 				" %u.", i, index);
 			goto error;
 		}
-		virtq->umems[i].obj = mlx5_glue->devx_umem_reg(priv->cdev->ctx,
-							virtq->umems[i].buf,
-							virtq->umems[i].size,
-							IBV_ACCESS_LOCAL_WRITE);
-		if (!virtq->umems[i].obj) {
+		obj = mlx5_glue->devx_umem_reg(priv->cdev->ctx, buf, size,
+					       IBV_ACCESS_LOCAL_WRITE);
+		if (obj == NULL) {
 			DRV_LOG(ERR, "Failed to register umem %d for virtq %u.",
 				i, index);
 			goto error;
 		}
+		virtq->umems[i].size = size;
+		virtq->umems[i].buf = buf;
+		virtq->umems[i].obj = obj;
+reuse:
 		attr.umems[i].id = virtq->umems[i].obj->umem_id;
 		attr.umems[i].offset = 0;
 		attr.umems[i].size = virtq->umems[i].size;
-- 
2.35.1


  parent reply	other threads:[~2022-05-08 14:27 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-24 13:28 [PATCH 0/7] vdpa/mlx5: improve device shutdown time Xueming Li
2022-02-24 13:28 ` [PATCH 1/7] vdpa/mlx5: fix interrupt trash that leads to segment fault Xueming Li
2022-02-24 13:28 ` [PATCH 2/7] vdpa/mlx5: fix dead loop when process interrupted Xueming Li
2022-02-24 13:28 ` [PATCH 3/7] vdpa/mlx5: no kick handling during shutdown Xueming Li
2022-02-24 13:28 ` [PATCH 4/7] vdpa/mlx5: reuse resources in reconfiguration Xueming Li
2022-02-24 13:28 ` [PATCH 5/7] vdpa/mlx5: cache and reuse hardware resources Xueming Li
2022-02-24 13:28 ` [PATCH 6/7] vdpa/mlx5: support device cleanup callback Xueming Li
2022-02-24 13:28 ` [PATCH 7/7] vdpa/mlx5: make statistics counter persistent Xueming Li
2022-02-24 14:38 ` [PATCH v1 0/7] vdpa/mlx5: improve device shutdown time Xueming Li
2022-02-24 14:38   ` [PATCH v1 1/7] vdpa/mlx5: fix interrupt trash that leads to segment fault Xueming Li
2022-02-24 14:38   ` [PATCH v1 2/7] vdpa/mlx5: fix dead loop when process interrupted Xueming Li
2022-02-24 14:38   ` [PATCH v1 3/7] vdpa/mlx5: no kick handling during shutdown Xueming Li
2022-02-24 14:38   ` [PATCH v1 4/7] vdpa/mlx5: reuse resources in reconfiguration Xueming Li
2022-02-24 14:38   ` [PATCH v1 5/7] vdpa/mlx5: cache and reuse hardware resources Xueming Li
2022-02-24 14:38   ` [PATCH v1 6/7] vdpa/mlx5: support device cleanup callback Xueming Li
2022-02-24 14:38   ` [PATCH v1 7/7] vdpa/mlx5: make statistics counter persistent Xueming Li
2022-02-24 15:50 ` [PATCH v2 0/7] vdpa/mlx5: improve device shutdown time Xueming Li
2022-02-24 15:50   ` [PATCH v2 1/7] vdpa/mlx5: fix interrupt trash that leads to segment fault Xueming Li
2022-04-20 10:39     ` Maxime Coquelin
2022-02-24 15:50   ` [PATCH v2 2/7] vdpa/mlx5: fix dead loop when process interrupted Xueming Li
2022-04-20 10:33     ` Maxime Coquelin
2022-02-24 15:50   ` [PATCH v2 3/7] vdpa/mlx5: no kick handling during shutdown Xueming Li
2022-04-20 12:37     ` Maxime Coquelin
2022-04-20 13:23       ` Xueming(Steven) Li
2022-02-24 15:50   ` [PATCH v2 4/7] vdpa/mlx5: reuse resources in reconfiguration Xueming Li
2022-04-20 14:49     ` Maxime Coquelin
2022-02-24 15:50   ` [PATCH v2 5/7] vdpa/mlx5: cache and reuse hardware resources Xueming Li
2022-04-20 15:03     ` Maxime Coquelin
2022-04-25 13:28       ` Xueming(Steven) Li
2022-05-05 20:01         ` Maxime Coquelin
2022-02-24 15:51   ` [PATCH v2 6/7] vdpa/mlx5: support device cleanup callback Xueming Li
2022-04-21  8:19     ` Maxime Coquelin
2022-02-24 15:51   ` [PATCH v2 7/7] vdpa/mlx5: make statistics counter persistent Xueming Li
2022-04-21  8:22     ` Maxime Coquelin
2022-05-08 14:25 ` [PATCH v3 0/7] vdpa/mlx5: improve device shutdown time Xueming Li
2022-05-08 14:25   ` [PATCH v3 1/7] vdpa/mlx5: fix interrupt trash that leads to segment fault Xueming Li
2022-05-08 14:25   ` [PATCH v3 2/7] vdpa/mlx5: fix dead loop when process interrupted Xueming Li
2022-05-08 14:25   ` [PATCH v3 3/7] vdpa/mlx5: no kick handling during shutdown Xueming Li
2022-05-08 14:25   ` [PATCH v3 4/7] vdpa/mlx5: reuse resources in reconfiguration Xueming Li
2022-05-08 14:25   ` Xueming Li [this message]
2022-05-08 14:25   ` [PATCH v3 6/7] vdpa/mlx5: support device cleanup callback Xueming Li
2022-05-08 14:25   ` [PATCH v3 7/7] vdpa/mlx5: make statistics counter persistent Xueming Li
2022-05-09 19:38   ` [PATCH v3 0/7] vdpa/mlx5: improve device shutdown time Maxime Coquelin

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=20220508142554.560354-6-xuemingl@nvidia.com \
    --to=xuemingl@nvidia.com \
    --cc=dev@dpdk.org \
    --cc=maxime.coquelin@redhat.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).