Skip to contentSkip to conversation

common/mlx5: share memory free callback

PATCH In review Michael Baum 2 participants 2 messages Jun 28, 2021 – Jun 30, 2021 Network drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 common/mlx5: share memory free callback

All the mlx5 drivers using MRs for data-path must unregister the mapped memory when it is freed by the dpdk process.

Currently, only the net/eth driver unregisters MRs in free event.

Move the net callback handler from net driver to common.

---
 drivers/common/mlx5/mlx5_common_mr.c | 89 +++++++++++++++++++++++++++
 drivers/common/mlx5/mlx5_common_mr.h |  3 +
 drivers/common/mlx5/version.map      |  1 +
 drivers/net/mlx5/mlx5_mr.c           | 90 +---------------------------
 4 files changed, 95 insertions(+), 88 deletions(-)
drivers/common/mlx5/mlx5_common_mr.c +89 -0
index afb5b3d0a7..98fe8698e2 100644
@@ -1062,6 +1062,95 @@ mlx5_create_mr_ext(void *pd, uintptr_t addr, size_t len, int socket_id,
 	return mr;
 }
 
+/**
+ * Callback for memory free event. Iterate freed memsegs and check whether it
+ * belongs to an existing MR. If found, clear the bit from bitmap of MR. As a
+ * result, the MR would be fragmented. If it becomes empty, the MR will be freed
+ * later by mlx5_mr_garbage_collect(). Even if this callback is called from a
+ * secondary process, the garbage collector will be called in primary process
+ * as the secondary process can't call mlx5_mr_create().
+ *
+ * The global cache must be rebuilt if there's any change and this event has to
+ * be propagated to dataplane threads to flush the local caches.
+ *
+ * @param share_cache
+ *   Pointer to a global shared MR cache.
+ * @param ibdev_name
+ *   Name of ibv device.
+ * @param addr
+ *   Address of freed memory.
+ * @param len
+ *   Size of freed memory.
+ */
+void
+mlx5_free_mr_by_addr(struct mlx5_mr_share_cache *share_cache,
+		     const char *ibdev_name, const void *addr, size_t len)
+{
+	const struct rte_memseg_list *msl;
+	struct mlx5_mr *mr;
+	int ms_n;
+	int i;
+	int rebuild = 0;
+
+	DRV_LOG(DEBUG, "device %s free callback: addr=%p, len=%zu",
+		ibdev_name, addr, len);
+	msl = rte_mem_virt2memseg_list(addr);
+	/* addr and len must be page-aligned. */
+	MLX5_ASSERT((uintptr_t)addr ==
+		    RTE_ALIGN((uintptr_t)addr, msl->page_sz));
+	MLX5_ASSERT(len == RTE_ALIGN(len, msl->page_sz));
+	ms_n = len / msl->page_sz;
+	rte_rwlock_write_lock(&share_cache->rwlock);
+	/* Clear bits of freed memsegs from MR. */
+	for (i = 0; i < ms_n; ++i) {
+		const struct rte_memseg *ms;
+		struct mr_cache_entry entry;
+		uintptr_t start;
+		int ms_idx;
+		uint32_t pos;
+
+		/* Find MR having this memseg. */
+		start = (uintptr_t)addr + i * msl->page_sz;
+		mr = mlx5_mr_lookup_list(share_cache, &entry, start);
+		if (mr == NULL)
+			continue;
+		MLX5_ASSERT(mr->msl); /* Can't be external memory. */
+		ms = rte_mem_virt2memseg((void *)start, msl);
+		MLX5_ASSERT(ms != NULL);
+		MLX5_ASSERT(msl->page_sz == ms->hugepage_sz);
+		ms_idx = rte_fbarray_find_idx(&msl->memseg_arr, ms);
+		pos = ms_idx - mr->ms_base_idx;
+		MLX5_ASSERT(rte_bitmap_get(mr->ms_bmp, pos));
+		MLX5_ASSERT(pos < mr->ms_bmp_n);
+		DRV_LOG(DEBUG, "device %s MR(%p): clear bitmap[%u] for addr %p",
+			ibdev_name, (void *)mr, pos, (void *)start);
+		rte_bitmap_clear(mr->ms_bmp, pos);
+		if (--mr->ms_n == 0) {
+			LIST_REMOVE(mr, mr);
+			LIST_INSERT_HEAD(&share_cache->mr_free_list, mr, mr);
+			DRV_LOG(DEBUG, "device %s remove MR(%p) from list",
+				ibdev_name, (void *)mr);
+		}
+		/*
+		 * MR is fragmented or will be freed. the global cache must be
+		 * rebuilt.
+		 */
+		rebuild = 1;
+	}
+	if (rebuild) {
+		mlx5_mr_rebuild_cache(share_cache);
+		/*
+		 * No explicit wmb is needed after updating dev_gen due to
+		 * store-release ordering in unlock that provides the
+		 * implicit barrier at the software visible level.
+		 */
+		++share_cache->dev_gen;
+		DRV_LOG(DEBUG, "broadcasting local cache flush, gen=%d",
+			share_cache->dev_gen);
+	}
+	rte_rwlock_write_unlock(&share_cache->rwlock);
+}
+
 /**
  * Dump all the created MRs and the global cache entries.
  *
drivers/common/mlx5/mlx5_common_mr.h +3 -0
index 5cc3f097c2..6e465a05e9 100644
@@ -144,6 +144,9 @@ void mlx5_mr_rebuild_cache(struct mlx5_mr_share_cache *share_cache);
 __rte_internal
 void mlx5_mr_flush_local_cache(struct mlx5_mr_ctrl *mr_ctrl);
 __rte_internal
+void mlx5_free_mr_by_addr(struct mlx5_mr_share_cache *share_cache,
+			  const char *ibdev_name, const void *addr, size_t len);
+__rte_internal
 int
 mlx5_mr_insert_cache(struct mlx5_mr_share_cache *share_cache,
 		     struct mlx5_mr *mr);
drivers/common/mlx5/version.map +1 -0
index db4f13f1f7..b8be73a77b 100644
@@ -103,6 +103,7 @@ INTERNAL {
 	mlx5_mr_insert_cache;
 	mlx5_mr_lookup_cache;
 	mlx5_mr_lookup_list;
+	mlx5_free_mr_by_addr;
 	mlx5_mr_rebuild_cache;
 	mlx5_mr_release_cache;
 
drivers/net/mlx5/mlx5_mr.c +2 -88

102 lines not on this page · raw message

Signature · 1 line
2.25.1
#1 lore raw

Hi,

Quoted 14 lines

-----Original Message-----
From: Michael Baum <[email protected]>
Sent: Monday, June 28, 2021 6:06 PM
To: [email protected]
Cc: Matan Azrad <[email protected]>; Raslan Darawsheh <[email protected]>; Slava Ovsiienko <[email protected]>; [email protected]
Subject: [PATCH] common/mlx5: share memory free callback

All the mlx5 drivers using MRs for data-path must unregister the mapped memory when it is freed by the dpdk process.

Currently, only the net/eth driver unregisters MRs in free event.

Quoted 7 lines

Move the net callback handler from net driver to common.

---

Patch applied to next-net-mlx,

Kindest regards,
Raslan Darawsheh