[PATCH v2 1/2] net/mana: fix MR length truncation for chunks over 4GB

Rita Ruvinsky rita.ruvinsky at weka.io
Thu Aug 6 19:26:39 CEST 2026


mana_range.len is a uint32_t, so a mempool chunk of 4GB or more
truncates modulo 2^32 -- exactly 4GB becomes 0, 15GB becomes 3GB.

The guard against priv->max_mr_size cannot catch this because it
compares the already-truncated value, and the device advertises
max_mr_size as UINT64_MAX. ibv_reg_mr() then fails with EINVAL on a
zero length, or silently registers a region far shorter than the pool,
so lookups for buffers past that boundary never find an MR and no Rx
WQE can be posted.

Widen the length to uint64_t through the MR path, including the
multi-process request that forwards it to the primary process.

Fixes: 0f5db3c68ba7 ("net/mana: implement memory registration")
Cc: stable at dpdk.org
Signed-off-by: Rita Ruvinsky <rita.ruvinsky at weka.io>
Reviewed-by: Long Li <longli at microsoft.com>
---
v2:
- Rebased on main; resolves the conflict with the device reset
  changes in mana.h reported by Stephen Hemminger and the Intel CI.
- Added Reviewed-by from Long Li.

 drivers/net/mana/mana.h |  4 ++--
 drivers/net/mana/mp.c   |  4 ++--
 drivers/net/mana/mr.c   | 11 ++++++-----
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/net/mana/mana.h b/drivers/net/mana/mana.h
index a7b301484a..79879b7626 100644
--- a/drivers/net/mana/mana.h
+++ b/drivers/net/mana/mana.h
@@ -602,7 +602,7 @@ struct mana_mp_param {
 
 	/* MANA_MP_REQ_CREATE_MR */
 	uintptr_t addr;
-	uint32_t len;
+	uint64_t len;
 };
 
 #define MANA_MP_NAME	"net_mana_mp"
@@ -611,7 +611,7 @@ int mana_mp_init_secondary(void);
 void mana_mp_uninit_primary(void);
 void mana_mp_uninit_secondary(void);
 int mana_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev);
-int mana_mp_req_mr_create(struct mana_priv *priv, uintptr_t addr, uint32_t len);
+int mana_mp_req_mr_create(struct mana_priv *priv, uintptr_t addr, uint64_t len);
 int mana_map_doorbell_secondary(struct rte_eth_dev *eth_dev, int fd);
 
 int mana_mp_req_on_rxtx(struct rte_eth_dev *dev, enum mana_mp_req_type type);
diff --git a/drivers/net/mana/mp.c b/drivers/net/mana/mp.c
index 1670f1ea9c..f278bcdce5 100644
--- a/drivers/net/mana/mp.c
+++ b/drivers/net/mana/mp.c
@@ -20,7 +20,7 @@ extern struct mana_shared_data *mana_shared_data;
  * Process MR request from secondary process.
  */
 static int
-mana_mp_mr_create(struct mana_priv *priv, uintptr_t addr, uint32_t len)
+mana_mp_mr_create(struct mana_priv *priv, uintptr_t addr, uint64_t len)
 {
 	struct ibv_mr *ibv_mr;
 	int ret;
@@ -331,7 +331,7 @@ mana_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)
  * Request the primary process to register a MR.
  */
 int
-mana_mp_req_mr_create(struct mana_priv *priv, uintptr_t addr, uint32_t len)
+mana_mp_req_mr_create(struct mana_priv *priv, uintptr_t addr, uint64_t len)
 {
 	struct rte_mp_msg mp_req = {0};
 	struct rte_mp_msg *mp_res;
diff --git a/drivers/net/mana/mr.c b/drivers/net/mana/mr.c
index 8914f4cf04..0ce1a76ed5 100644
--- a/drivers/net/mana/mr.c
+++ b/drivers/net/mana/mr.c
@@ -13,7 +13,8 @@
 struct mana_range {
 	uintptr_t	start;
 	uintptr_t	end;
-	uint32_t	len;
+	/* 64-bit: a mempool chunk can be 4GB or more, which overflows uint32_t. */
+	uint64_t	len;
 };
 
 void
@@ -47,13 +48,13 @@ mana_new_pmd_mr(struct mana_mr_btree *local_tree, struct mana_priv *priv,
 
 	for (i = 0; i < pool->nb_mem_chunks; i++) {
 		if (ranges[i].len > priv->max_mr_size) {
-			DP_LOG(ERR, "memory chunk size %u exceeding max MR",
+			DP_LOG(ERR, "memory chunk size %" PRIu64 " exceeding max MR",
 			       ranges[i].len);
 			return -ENOMEM;
 		}
 
 		DP_LOG(DEBUG,
-		       "registering memory chunk start 0x%" PRIxPTR " len %u",
+		       "registering memory chunk start 0x%" PRIxPTR " len %" PRIu64,
 		       ranges[i].start, ranges[i].len);
 
 		if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
@@ -62,7 +63,7 @@ mana_new_pmd_mr(struct mana_mr_btree *local_tree, struct mana_priv *priv,
 						    ranges[i].len);
 			if (ret) {
 				DP_LOG(ERR,
-				       "MR failed start 0x%" PRIxPTR " len %u",
+				       "MR failed start 0x%" PRIxPTR " len %" PRIu64,
 				       ranges[i].start, ranges[i].len);
 				return ret;
 			}
@@ -98,7 +99,7 @@ mana_new_pmd_mr(struct mana_mr_btree *local_tree, struct mana_priv *priv,
 				return ret;
 			}
 		} else {
-			DP_LOG(ERR, "MR failed at 0x%" PRIxPTR " len %u",
+			DP_LOG(ERR, "MR failed at 0x%" PRIxPTR " len %" PRIu64,
 			       ranges[i].start, ranges[i].len);
 			return -errno;
 		}
-- 
2.43.0



More information about the dev mailing list