patch 'net/ena: fix mbuf double free in fast free mode' has been queued to stable release 22.11.5

luca.boccassi at gmail.com luca.boccassi at gmail.com
Mon Mar 25 13:08:17 CET 2024


Hi,

FYI, your patch has been queued to stable release 22.11.5

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 03/27/24. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/bluca/dpdk-stable

This queued commit can be viewed at:
https://github.com/bluca/dpdk-stable/commit/3894e82ac5267b7d24e0a21791351115254be8ea

Thanks.

Luca Boccassi

---
>From 3894e82ac5267b7d24e0a21791351115254be8ea Mon Sep 17 00:00:00 2001
From: Shai Brandes <shaibran at amazon.com>
Date: Wed, 20 Mar 2024 16:52:32 +0200
Subject: [PATCH] net/ena: fix mbuf double free in fast free mode

[ upstream commit 237407f0c3dff2d0a6bbeb5f35c8b32fe5c8afed ]

Fixed an issue of double free of mbufs which is exposed
in mbuf fast free mode when handling multi-mbuf packets.

The faulty patch mishandled free of non-head mbufs as it
iterated over linked mbufs and collected them into an array,
which was then passed to rte_pktmbuf_free_bulk.
However, rte_pktmbuf_free_bulk already performs an internal iteration
over mbufs that are linked together which led to double free.

Fixes: 89b081e154c5 ("net/ena: fix fast mbuf free")

Signed-off-by: Shai Brandes <shaibran at amazon.com>
Acked-by: Ferruh Yigit <ferruh.yigit at amd.com>
---
 drivers/net/ena/ena_ethdev.c | 39 +++++++++++-------------------------
 1 file changed, 12 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 2c4e3505d0..29782a7fb6 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -37,10 +37,10 @@
 #define ENA_MIN_RING_DESC	128
 
 /*
- * We should try to keep ENA_CLEANUP_BUF_SIZE lower than
+ * We should try to keep ENA_CLEANUP_BUF_THRESH lower than
  * RTE_MEMPOOL_CACHE_MAX_SIZE, so we can fit this in mempool local cache.
  */
-#define ENA_CLEANUP_BUF_SIZE	256
+#define ENA_CLEANUP_BUF_THRESH	256
 
 #define ENA_PTYPE_HAS_HASH	(RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP)
 
@@ -3018,32 +3018,12 @@ static int ena_xmit_mbuf(struct ena_ring *tx_ring, struct rte_mbuf *mbuf)
 	return 0;
 }
 
-static __rte_always_inline size_t
-ena_tx_cleanup_mbuf_fast(struct rte_mbuf **mbufs_to_clean,
-			 struct rte_mbuf *mbuf,
-			 size_t mbuf_cnt,
-			 size_t buf_size)
-{
-	struct rte_mbuf *m_next;
-
-	while (mbuf != NULL) {
-		m_next = mbuf->next;
-		mbufs_to_clean[mbuf_cnt++] = mbuf;
-		if (mbuf_cnt == buf_size) {
-			rte_pktmbuf_free_bulk(mbufs_to_clean, mbuf_cnt);
-			mbuf_cnt = 0;
-		}
-		mbuf = m_next;
-	}
-
-	return mbuf_cnt;
-}
-
 static int ena_tx_cleanup(void *txp, uint32_t free_pkt_cnt)
 {
-	struct rte_mbuf *mbufs_to_clean[ENA_CLEANUP_BUF_SIZE];
+	struct rte_mbuf *pkts_to_clean[ENA_CLEANUP_BUF_THRESH];
 	struct ena_ring *tx_ring = (struct ena_ring *)txp;
 	size_t mbuf_cnt = 0;
+	size_t pkt_cnt = 0;
 	unsigned int total_tx_descs = 0;
 	unsigned int total_tx_pkts = 0;
 	uint16_t cleanup_budget;
@@ -3074,8 +3054,13 @@ static int ena_tx_cleanup(void *txp, uint32_t free_pkt_cnt)
 
 		mbuf = tx_info->mbuf;
 		if (fast_free) {
-			mbuf_cnt = ena_tx_cleanup_mbuf_fast(mbufs_to_clean, mbuf, mbuf_cnt,
-				ENA_CLEANUP_BUF_SIZE);
+			pkts_to_clean[pkt_cnt++] = mbuf;
+			mbuf_cnt += mbuf->nb_segs;
+			if (mbuf_cnt >= ENA_CLEANUP_BUF_THRESH) {
+				rte_pktmbuf_free_bulk(pkts_to_clean, pkt_cnt);
+				mbuf_cnt = 0;
+				pkt_cnt = 0;
+			}
 		} else {
 			rte_pktmbuf_free(mbuf);
 		}
@@ -3099,7 +3084,7 @@ static int ena_tx_cleanup(void *txp, uint32_t free_pkt_cnt)
 	}
 
 	if (mbuf_cnt != 0)
-		rte_pktmbuf_free_bulk(mbufs_to_clean, mbuf_cnt);
+		rte_pktmbuf_free_bulk(pkts_to_clean, pkt_cnt);
 
 	/* Notify completion handler that full cleanup was performed */
 	if (free_pkt_cnt == 0 || total_tx_pkts < cleanup_budget)
-- 
2.39.2

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2024-03-25 11:28:37.366765928 +0000
+++ 0002-net-ena-fix-mbuf-double-free-in-fast-free-mode.patch	2024-03-25 11:28:37.176388004 +0000
@@ -1 +1 @@
-From 237407f0c3dff2d0a6bbeb5f35c8b32fe5c8afed Mon Sep 17 00:00:00 2001
+From 3894e82ac5267b7d24e0a21791351115254be8ea Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit 237407f0c3dff2d0a6bbeb5f35c8b32fe5c8afed ]
+
@@ -16 +17,0 @@
-Cc: stable at dpdk.org
@@ -25 +26 @@
-index 7b697c150a..66fc287faf 100644
+index 2c4e3505d0..29782a7fb6 100644
@@ -28,2 +29,2 @@
-@@ -48,10 +48,10 @@
- #define MAX_WIDE_LLQ_DEPTH_UNSUPPORTED 0
+@@ -37,10 +37,10 @@
+ #define ENA_MIN_RING_DESC	128
@@ -41 +42 @@
-@@ -3180,32 +3180,12 @@ static int ena_xmit_mbuf(struct ena_ring *tx_ring, struct rte_mbuf *mbuf)
+@@ -3018,32 +3018,12 @@ static int ena_xmit_mbuf(struct ena_ring *tx_ring, struct rte_mbuf *mbuf)
@@ -76 +77 @@
-@@ -3236,8 +3216,13 @@ static int ena_tx_cleanup(void *txp, uint32_t free_pkt_cnt)
+@@ -3074,8 +3054,13 @@ static int ena_tx_cleanup(void *txp, uint32_t free_pkt_cnt)
@@ -92 +93 @@
-@@ -3260,7 +3245,7 @@ static int ena_tx_cleanup(void *txp, uint32_t free_pkt_cnt)
+@@ -3099,7 +3084,7 @@ static int ena_tx_cleanup(void *txp, uint32_t free_pkt_cnt)


More information about the stable mailing list