net/ena: fix mbuf double free in fast free mode
PATCH 1/1 net/ena: fix mbuf double free in fast free mode
From: Shai Brandes <[email protected]>
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.
--- drivers/net/ena/ena_ethdev.c | 39 +++++++++++------------------------- 1 file changed, 12 insertions(+), 27 deletions(-)
drivers/net/ena/ena_ethdev.c +12 -27
@@ -48,10 +48,10 @@#define MAX_WIDE_LLQ_DEPTH_UNSUPPORTED 0/* -* 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)
@@ -3180,32 +3180,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;
@@ -3236,8 +3216,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); }
@@ -3260,7 +3245,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)
Signature · 1 line
2.17.1
Quoted 11 lines · On 3/20/2024 2:52 PM, [email protected] wrote:
From: Shai Brandes <[email protected]>
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_bulkalready performs an internal iteration over mbufs that are linked together which led to double free.
Quoted 5 lines
Fixes 89b081e154c5 ("net/ena: fix fast mbuf free")Signed-off-by Shai Brandes <[email protected]>
Applied to dpdk-next-net/main, thanks.