DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] net/mana: fix MR length truncation for chunks over 4GB
@ 2026-08-05 15:44 Rita Ruvinsky
  2026-08-05 15:44 ` [PATCH 2/2] net/mana: fix double free of mbuf on Rx WQE post failure Rita Ruvinsky
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Rita Ruvinsky @ 2026-08-05 15:44 UTC (permalink / raw)
  To: dev; +Cc: longli, weh, Rita Ruvinsky, stable

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@dpdk.org
Signed-off-by: Rita Ruvinsky <rita.ruvinsky@weka.io>
---
 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 7d94840dc4..552865ff9d 100644
--- a/drivers/net/mana/mana.h
+++ b/drivers/net/mana/mana.h
@@ -553,7 +553,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"
@@ -562,7 +562,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);
 
 void 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 5467d385ce..5cc29de3a1 100644
--- a/drivers/net/mana/mp.c
+++ b/drivers/net/mana/mp.c
@@ -17,7 +17,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;
@@ -257,7 +257,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 c4045141bc..7405755df8 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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] net/mana: fix double free of mbuf on Rx WQE post failure
  2026-08-05 15:44 [PATCH 1/2] net/mana: fix MR length truncation for chunks over 4GB Rita Ruvinsky
@ 2026-08-05 15:44 ` Rita Ruvinsky
  2026-08-06  0:31   ` [EXTERNAL] " Long Li
  2026-08-06  0:29 ` [EXTERNAL] [PATCH 1/2] net/mana: fix MR length truncation for chunks over 4GB Long Li
  2026-08-06 17:02 ` Stephen Hemminger
  2 siblings, 1 reply; 5+ messages in thread
From: Rita Ruvinsky @ 2026-08-05 15:44 UTC (permalink / raw)
  To: dev; +Cc: longli, weh, Rita Ruvinsky, stable

mana_post_rx_wqe() frees the mbuf when mana_alloc_pmd_mr() fails, but
the caller already frees the un-posted range starting at that same
mbuf via rte_pktmbuf_free_bulk(&mbufs[i], batch_count - i), so the
mbuf is returned to the mempool twice and can be handed out to two
consumers at once.

The free was correct before the bulk allocation rework, when this
function allocated the mbuf itself. Now that the caller owns it, leave
the mbuf to the caller on every error path.

Fixes: eeb37809601b ("net/mana: use bulk mbuf allocation for Rx WQEs")
Cc: stable@dpdk.org
Signed-off-by: Rita Ruvinsky <rita.ruvinsky@weka.io>
---
 drivers/net/mana/rx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/mana/rx.c b/drivers/net/mana/rx.c
index f196d43aee..2bca004dfa 100644
--- a/drivers/net/mana/rx.c
+++ b/drivers/net/mana/rx.c
@@ -68,10 +68,10 @@ mana_post_rx_wqe(struct mana_rxq *rxq, struct rte_mbuf *mbuf)
 	int ret;
 	struct mana_mr_cache *mr;
 
+	/* Don't free mbuf on error: the caller bulk-frees it from &mbufs[i]. */
 	mr = mana_alloc_pmd_mr(&rxq->mr_btree, priv, mbuf);
 	if (!mr) {
 		DP_LOG(ERR, "failed to register RX MR");
-		rte_pktmbuf_free(mbuf);
 		return -ENOMEM;
 	}
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* RE: [EXTERNAL] [PATCH 1/2] net/mana: fix MR length truncation for chunks over 4GB
  2026-08-05 15:44 [PATCH 1/2] net/mana: fix MR length truncation for chunks over 4GB Rita Ruvinsky
  2026-08-05 15:44 ` [PATCH 2/2] net/mana: fix double free of mbuf on Rx WQE post failure Rita Ruvinsky
@ 2026-08-06  0:29 ` Long Li
  2026-08-06 17:02 ` Stephen Hemminger
  2 siblings, 0 replies; 5+ messages in thread
From: Long Li @ 2026-08-06  0:29 UTC (permalink / raw)
  To: Rita Ruvinsky, dev@dpdk.org; +Cc: Wei Hu, stable@dpdk.org

> 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@dpdk.org
> Signed-off-by: Rita Ruvinsky <rita.ruvinsky@weka.io>

Reviewed-by: Long Li <longli@microsoft.com>


> ---
>  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
> 7d94840dc4..552865ff9d 100644
> --- a/drivers/net/mana/mana.h
> +++ b/drivers/net/mana/mana.h
> @@ -553,7 +553,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"
> @@ -562,7 +562,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);
> 
>  void 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
> 5467d385ce..5cc29de3a1 100644
> --- a/drivers/net/mana/mp.c
> +++ b/drivers/net/mana/mp.c
> @@ -17,7 +17,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;
> @@ -257,7 +257,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
> c4045141bc..7405755df8 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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [EXTERNAL] [PATCH 2/2] net/mana: fix double free of mbuf on Rx WQE post failure
  2026-08-05 15:44 ` [PATCH 2/2] net/mana: fix double free of mbuf on Rx WQE post failure Rita Ruvinsky
@ 2026-08-06  0:31   ` Long Li
  0 siblings, 0 replies; 5+ messages in thread
From: Long Li @ 2026-08-06  0:31 UTC (permalink / raw)
  To: Rita Ruvinsky, dev@dpdk.org; +Cc: Wei Hu, stable@dpdk.org


> mana_post_rx_wqe() frees the mbuf when mana_alloc_pmd_mr() fails, but the
> caller already frees the un-posted range starting at that same mbuf via
> rte_pktmbuf_free_bulk(&mbufs[i], batch_count - i), so the mbuf is returned to
> the mempool twice and can be handed out to two consumers at once.
> 
> The free was correct before the bulk allocation rework, when this function
> allocated the mbuf itself. Now that the caller owns it, leave the mbuf to the
> caller on every error path.
> 
> Fixes: eeb37809601b ("net/mana: use bulk mbuf allocation for Rx WQEs")
> Cc: stable@dpdk.org
> Signed-off-by: Rita Ruvinsky <rita.ruvinsky@weka.io>

Reviewed-by: Long Li <longli@microsoft.com>


> ---
>  drivers/net/mana/rx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/mana/rx.c b/drivers/net/mana/rx.c index
> f196d43aee..2bca004dfa 100644
> --- a/drivers/net/mana/rx.c
> +++ b/drivers/net/mana/rx.c
> @@ -68,10 +68,10 @@ mana_post_rx_wqe(struct mana_rxq *rxq, struct
> rte_mbuf *mbuf)
>         int ret;
>         struct mana_mr_cache *mr;
> 
> +       /* Don't free mbuf on error: the caller bulk-frees it from
> + &mbufs[i]. */
>         mr = mana_alloc_pmd_mr(&rxq->mr_btree, priv, mbuf);
>         if (!mr) {
>                 DP_LOG(ERR, "failed to register RX MR");
> -               rte_pktmbuf_free(mbuf);
>                 return -ENOMEM;
>         }
> 
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] net/mana: fix MR length truncation for chunks over 4GB
  2026-08-05 15:44 [PATCH 1/2] net/mana: fix MR length truncation for chunks over 4GB Rita Ruvinsky
  2026-08-05 15:44 ` [PATCH 2/2] net/mana: fix double free of mbuf on Rx WQE post failure Rita Ruvinsky
  2026-08-06  0:29 ` [EXTERNAL] [PATCH 1/2] net/mana: fix MR length truncation for chunks over 4GB Long Li
@ 2026-08-06 17:02 ` Stephen Hemminger
  2 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2026-08-06 17:02 UTC (permalink / raw)
  To: Rita Ruvinsky; +Cc: dev, longli, weh, stable

On Wed,  5 Aug 2026 18:44:06 +0300
Rita Ruvinsky <rita.ruvinsky@weka.io> wrote:

> 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@dpdk.org
> Signed-off-by: Rita Ruvinsky <rita.ruvinsky@weka.io>
> ---

This patch series will not build on main branch.
It has merge conflicts with recent device reset code.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-08-06 17:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-05 15:44 [PATCH 1/2] net/mana: fix MR length truncation for chunks over 4GB Rita Ruvinsky
2026-08-05 15:44 ` [PATCH 2/2] net/mana: fix double free of mbuf on Rx WQE post failure Rita Ruvinsky
2026-08-06  0:31   ` [EXTERNAL] " Long Li
2026-08-06  0:29 ` [EXTERNAL] [PATCH 1/2] net/mana: fix MR length truncation for chunks over 4GB Long Li
2026-08-06 17:02 ` Stephen Hemminger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox