[v2,2/2] net/mana: properly deal with MR cache expansion failure

Message ID 1707437104-23548-2-git-send-email-longli@linuxonhyperv.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series [v2,1/2] net/mana: fix memory leak on MR variable allocation |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/github-robot: build success github build: passed
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-compile-amd64-testing success Testing PASS
ci/iol-unit-amd64-testing success Testing PASS
ci/iol-abi-testing success Testing PASS
ci/Intel-compilation success Compilation OK
ci/iol-unit-arm64-testing success Testing PASS
ci/intel-Testing success Testing PASS
ci/intel-Functional success Functional PASS
ci/iol-compile-arm64-testing success Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-sample-apps-testing success Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS

Commit Message

Long Li Feb. 9, 2024, 12:05 a.m. UTC
  From: Long Li <longli@microsoft.com>

On MR cache expension failure, the request should fail as there is no path
to get a new MR into the tree. Attempting to insert a new MR to the cache
tree will result in memory violation.

Fixes: 0f5db3c68ba7 ("net/mana: implement memory registration")
Cc: stable@dpdk.org
Signed-off-by: Long Li <longli@microsoft.com>
---

Change in v2:
added "Fixes:" tag.

 drivers/net/mana/mana.h |  6 +++---
 drivers/net/mana/mr.c   | 45 ++++++++++++++++++++++++++++-------------
 2 files changed, 34 insertions(+), 17 deletions(-)
  

Patch

diff --git a/drivers/net/mana/mana.h b/drivers/net/mana/mana.h
index eadcd01858..309d553956 100644
--- a/drivers/net/mana/mana.h
+++ b/drivers/net/mana/mana.h
@@ -522,9 +522,9 @@  void mana_del_pmd_mr(struct mana_mr_cache *mr);
 void mana_mempool_chunk_cb(struct rte_mempool *mp, void *opaque,
 			   struct rte_mempool_memhdr *memhdr, unsigned int idx);
 
-struct mana_mr_cache *mana_mr_btree_lookup(struct mana_mr_btree *bt,
-					   uint16_t *idx,
-					   uintptr_t addr, size_t len);
+int mana_mr_btree_lookup(struct mana_mr_btree *bt, uint16_t *idx,
+			 uintptr_t addr, size_t len,
+			 struct mana_mr_cache **cache);
 int mana_mr_btree_insert(struct mana_mr_btree *bt, struct mana_mr_cache *entry);
 int mana_mr_btree_init(struct mana_mr_btree *bt, int n, int socket);
 void mana_mr_btree_free(struct mana_mr_btree *bt);
diff --git a/drivers/net/mana/mr.c b/drivers/net/mana/mr.c
index c9d0f7ef5a..c4045141bc 100644
--- a/drivers/net/mana/mr.c
+++ b/drivers/net/mana/mr.c
@@ -138,8 +138,12 @@  mana_alloc_pmd_mr(struct mana_mr_btree *local_mr_btree, struct mana_priv *priv,
 
 try_again:
 	/* First try to find the MR in local queue tree */
-	mr = mana_mr_btree_lookup(local_mr_btree, &idx,
-				  (uintptr_t)mbuf->buf_addr, mbuf->buf_len);
+	ret = mana_mr_btree_lookup(local_mr_btree, &idx,
+				   (uintptr_t)mbuf->buf_addr, mbuf->buf_len,
+				   &mr);
+	if (ret)
+		return NULL;
+
 	if (mr) {
 		DP_LOG(DEBUG, "Local mr lkey %u addr 0x%" PRIxPTR " len %zu",
 		       mr->lkey, mr->addr, mr->len);
@@ -148,11 +152,14 @@  mana_alloc_pmd_mr(struct mana_mr_btree *local_mr_btree, struct mana_priv *priv,
 
 	/* If not found, try to find the MR in global tree */
 	rte_spinlock_lock(&priv->mr_btree_lock);
-	mr = mana_mr_btree_lookup(&priv->mr_btree, &idx,
-				  (uintptr_t)mbuf->buf_addr,
-				  mbuf->buf_len);
+	ret = mana_mr_btree_lookup(&priv->mr_btree, &idx,
+				   (uintptr_t)mbuf->buf_addr,
+				   mbuf->buf_len, &mr);
 	rte_spinlock_unlock(&priv->mr_btree_lock);
 
+	if (ret)
+		return NULL;
+
 	/* If found in the global tree, add it to the local tree */
 	if (mr) {
 		ret = mana_mr_btree_insert(local_mr_btree, mr);
@@ -228,22 +235,23 @@  mana_mr_btree_expand(struct mana_mr_btree *bt, int n)
 /*
  * Look for a region of memory in MR cache.
  */
-struct mana_mr_cache *
-mana_mr_btree_lookup(struct mana_mr_btree *bt, uint16_t *idx,
-		     uintptr_t addr, size_t len)
+int mana_mr_btree_lookup(struct mana_mr_btree *bt, uint16_t *idx,
+			 uintptr_t addr, size_t len,
+			 struct mana_mr_cache **cache)
 {
 	struct mana_mr_cache *table;
 	uint16_t n;
 	uint16_t base = 0;
 	int ret;
 
-	n = bt->len;
+	*cache = NULL;
 
+	n = bt->len;
 	/* Try to double the cache if it's full */
 	if (n == bt->size) {
 		ret = mana_mr_btree_expand(bt, bt->size << 1);
 		if (ret)
-			return NULL;
+			return ret;
 	}
 
 	table = bt->table;
@@ -262,14 +270,16 @@  mana_mr_btree_lookup(struct mana_mr_btree *bt, uint16_t *idx,
 
 	*idx = base;
 
-	if (addr + len <= table[base].addr + table[base].len)
-		return &table[base];
+	if (addr + len <= table[base].addr + table[base].len) {
+		*cache = &table[base];
+		return 0;
+	}
 
 	DP_LOG(DEBUG,
 	       "addr 0x%" PRIxPTR " len %zu idx %u sum 0x%" PRIxPTR " not found",
 	       addr, len, *idx, addr + len);
 
-	return NULL;
+	return 0;
 }
 
 int
@@ -314,14 +324,21 @@  mana_mr_btree_insert(struct mana_mr_btree *bt, struct mana_mr_cache *entry)
 	struct mana_mr_cache *table;
 	uint16_t idx = 0;
 	uint16_t shift;
+	int ret;
+
+	ret = mana_mr_btree_lookup(bt, &idx, entry->addr, entry->len, &table);
+	if (ret)
+		return ret;
 
-	if (mana_mr_btree_lookup(bt, &idx, entry->addr, entry->len)) {
+	if (table) {
 		DP_LOG(DEBUG, "Addr 0x%" PRIxPTR " len %zu exists in btree",
 		       entry->addr, entry->len);
 		return 0;
 	}
 
 	if (bt->len >= bt->size) {
+		DP_LOG(ERR, "Btree overflow detected len %u size %u",
+		       bt->len, bt->size);
 		bt->overflow = 1;
 		return -1;
 	}