pktmbuf free bulk cleanups
cover pktmbuf free bulk cleanups
Looking at one driver noticed that rte_pktmbuf_free_bulk was not being used. That motivated me to make a coccinelle script to do a tree wide cleanup.
Then noticed that callers were having to check for NULL before calling rte_pktmbuf_free_bulk, so changed it to handle NULL array similar to free() and rte_free().
Do another tree wide pass to fix that and catch some other unnecessary null checks in code.
Stephen Hemminger (20):
devtools/cocci: add transform for rte_pktmbuf_free_bulk
eventdev: use rte_pktmbuf_free_bulk
gso: use rte_pktmbuf_free_bulk
ip_frag: use rte_pktmbuf_free_bulk
pipeline: use rte_pktmbuf_free_bulk
port: use rte_pktmbuf_free_bulk
net/af_xdp: use rte_pktmbuf_free_bulk net/cnxk: use rte_pktmbuf_free_bulk
net/pfe: use rte_pktmbuf_free_bulk
net/virtio: use rte_pktmbuf_free_bulk net/zxdh: use rte_pktmbuf_free_bulk app/compress-perf: use rte_pktmbuf_free_bulk
mbuf: allow NULL array in rte_pktmbuf_free_bulk net/zxdh: remove unnecessary null check net/ice: remove unnecessary null check net/bnxt: remove unnecessary null check
test: use rte_pktmbuf_free_bulk app/test-dma-perf: remove unnecessary null check app/test-compress-perf: remove unnecessary null check
examples: use rte_pktmbuf_free_bulk
.../comp_perf_test_common.c | 8 +-- app/test-compress-perf/main.c | 6 +- app/test-dma-perf/benchmark.c | 6 +- app/test/sample_packet_forward.c | 5 +- app/test/test_distributor.c | 4 +- app/test/test_dmadev.c | 6 +- app/test/test_ipfrag.c | 4 +- app/test/test_link_bonding.c | 13 ++--- app/test/test_pmd_perf.c | 3 +- app/test/test_pmd_tap.c | 3 +- app/test/test_reorder.c | 12 ++-- app/test/test_table_ports.c | 12 ++-- app/test/test_table_tables.c | 21 +++---- devtools/cocci/free_bulk.cocci | 57 +++++++++++++++++++ devtools/cocci/nullfree.cocci | 5 +- doc/guides/rel_notes/release_26_07.rst | 5 ++ drivers/net/af_xdp/rte_eth_af_xdp.c | 3 +- drivers/net/bnxt/tf_core/v3/tfo.c | 6 +- drivers/net/bnxt/tf_ulp/ulp_sc_mgr.c | 6 +- drivers/net/cnxk/cnxk_ethdev.c | 5 +- drivers/net/intel/ice/ice_dcf_sched.c | 6 +- drivers/net/pfe/pfe_ethdev.c | 4 +- drivers/net/virtio/virtio_rxtx.c | 20 +++---- drivers/net/zxdh/zxdh_np.c | 3 +- drivers/net/zxdh/zxdh_queue.c | 7 +-- drivers/net/zxdh/zxdh_rxtx.c | 3 +- examples/bbdev_app/main.c | 4 +- examples/l2fwd-crypto/main.c | 4 +- .../client_server_mp/mp_client/client.c | 7 +-- .../client_server_mp/mp_server/main.c | 5 +- examples/ntb/ntb_fwd.c | 12 ++-- examples/packet_ordering/main.c | 5 +- examples/server_node_efd/efd_node/node.c | 7 +-- examples/server_node_efd/efd_server/main.c | 5 +- examples/vhost/main.c | 3 +- lib/eventdev/rte_event_eth_tx_adapter.c | 4 +- lib/gso/gso_common.c | 5 +- lib/ip_frag/rte_ipv6_fragmentation.c | 4 +- lib/mbuf/rte_mbuf.c | 3 + lib/mbuf/rte_mbuf.h | 1 + lib/pipeline/rte_pipeline.c | 4 +- lib/port/rte_port_fd.c | 6 +- lib/port/rte_swx_port_fd.c | 8 +-- lib/port/rte_swx_port_source_sink.c | 6 +- 44 files changed, 152 insertions(+), 174 deletions(-) create mode 100644 devtools/cocci/free_bulk.cocci
Signature · 1 line
2.53.0
PATCH 1/20 devtools/cocci: add transform for rte_pktmbuf_free_bulk
Convert simple loops freeing mbufs one at a time into a single rte_pktmbuf_free_bulk() call.
--- devtools/cocci/free_bulk.cocci | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 devtools/cocci/free_bulk.cocci
devtools/cocci/free_bulk.cocci new file +57 -0
@@ -0,0 +1,57 @@ +// +// Replace simple loops freeing mbufs one-by-one with rte_pktmbuf_free_bulk(). +// +// rte_pktmbuf_free_bulk() handles NULL entries internally, so per-element +// NULL guards are folded in as well. Loops whose body does more than the +// free (clearing the slot, bookkeeping, etc.) are not matched. +// +@@ +expression A, N; +identifier i; +@@ + +( +- for (i = 0; i < N; i++) +- rte_pktmbuf_free(A[i]); ++ rte_pktmbuf_free_bulk(A, N); +| +- for (i = 0; i < N; ++i) +- rte_pktmbuf_free(A[i]); ++ rte_pktmbuf_free_bulk(A, N); +| +- for (i = 0; i < N; i++) +- if (A[i] != NULL) +- rte_pktmbuf_free(A[i]); ++ rte_pktmbuf_free_bulk(A, N); +| +- for (i = 0; i < N; i++) +- if (A[i]) +- rte_pktmbuf_free(A[i]); ++ rte_pktmbuf_free_bulk(A, N); +) + +@@ +expression A, N; +identifier i; +type T; +@@ + +( +- for (T i = 0; i < N; i++) +- rte_pktmbuf_free(A[i]); ++ rte_pktmbuf_free_bulk(A, N); +| +- for (T i = 0; i < N; ++i) +- rte_pktmbuf_free(A[i]); ++ rte_pktmbuf_free_bulk(A, N); +| +- for (T i = 0; i < N; i++) +- if (A[i] != NULL) +- rte_pktmbuf_free(A[i]); ++ rte_pktmbuf_free_bulk(A, N); +| +- for (T i = 0; i < N; i++) +- if (A[i]) +- rte_pktmbuf_free(A[i]); ++ rte_pktmbuf_free_bulk(A, N); +)
Signature · 1 line
2.53.0
PATCH 2/20 eventdev: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- lib/eventdev/rte_event_eth_tx_adapter.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
lib/eventdev/rte_event_eth_tx_adapter.c +1 -3
@@ -914,12 +914,10 @@ static inline void txa_txq_buffer_drain(struct txa_service_queue_info *tqi) {struct rte_eth_dev_tx_buffer *b; -uint16_t i; b = tqi->tx_buf; -for (i =0 ; i < b->length; i++) -rte_pktmbuf_free (b->pkts[i]); +rte_pktmbuf_free_bulk (b->pkts, b->length); b->length =0 ; }
Signature · 1 line
2.53.0
PATCH 3/20 gso: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- lib/gso/gso_common.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
lib/gso/gso_common.c +1 -4
@@ -31,10 +31,7 @@ hdr_segment_init(struct rte_mbuf *hdr_segment, struct rte_mbuf *pkt,static inline void free_gso_segment (struct rte_mbuf **pkts,uint16_t nb_pkts) { -uint16_t i; - -for (i =0 ; i < nb_pkts; i++) -rte_pktmbuf_free (pkts[i]); +rte_pktmbuf_free_bulk (pkts, nb_pkts); }int
Signature · 1 line
2.53.0
PATCH 4/20 ip_frag: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- lib/ip_frag/rte_ipv6_fragmentation.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
lib/ip_frag/rte_ipv6_fragmentation.c +1 -3
@@ -38,9 +38,7 @@ __fill_ipv6hdr_frag(struct rte_ipv6_hdr *dst,static inline void __free_fragments (struct rte_mbuf *mb[],uint32_t num) { -uint32_t i; -for (i =0 ; i < num; i++) -rte_pktmbuf_free (mb[i]); +rte_pktmbuf_free_bulk (mb, num); }/**
Signature · 1 line
2.53.0
PATCH 5/20 pipeline: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- lib/pipeline/rte_pipeline.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
lib/pipeline/rte_pipeline.c +1 -3
@@ -1305,10 +1305,8 @@ rte_pipeline_action_handler_drop(struct rte_pipeline *p, uint64_t pkts_mask) {if ((pkts_mask & (pkts_mask +1 )) ==0 ) {uint64_t n_pkts =rte_popcount64 (pkts_mask); -uint32_t i; -for (i =0 ; i < n_pkts; i++) -rte_pktmbuf_free (p->pkts[i]); +rte_pktmbuf_free_bulk (p->pkts, n_pkts); }else {uint32_t i;
Signature · 1 line
2.53.0
PATCH 6/20 port: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- lib/port/rte_port_fd.c | 6 ++---- lib/port/rte_swx_port_fd.c | 8 ++------ lib/port/rte_swx_port_source_sink.c | 6 +----- 3 files changed, 5 insertions(+), 15 deletions(-)
lib/port/rte_port_fd.c +2 -4
@@ -212,8 +212,7 @@ send_burst(struct rte_port_fd_writer *p)RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD (p, p->tx_buf_count - i); -for (i =0 ; i < p->tx_buf_count; i++) -rte_pktmbuf_free (p->tx_buf[i]); +rte_pktmbuf_free_bulk (p->tx_buf, p->tx_buf_count); p->tx_buf_count =0 ; }
@@ -397,8 +396,7 @@ send_burst_nodrop(struct rte_port_fd_writer_nodrop *p)RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD (p, p->tx_buf_count - i); -for (i =0 ; i < p->tx_buf_count; i++) -rte_pktmbuf_free (p->tx_buf[i]); +rte_pktmbuf_free_bulk (p->tx_buf, p->tx_buf_count); p->tx_buf_count =0 ; }
lib/port/rte_swx_port_fd.c +2 -6
@@ -73,14 +73,11 @@ static void reader_free(void *port) {struct reader *p = port; -uint32_t i;if (!p)return ; -for (i =0 ; i < p->n_pkts; i++) -rte_pktmbuf_free (p->pkts[i]); - +rte_pktmbuf_free_bulk (p->pkts, p->n_pkts);free (p->pkts);free (p); }
@@ -218,8 +215,7 @@ __writer_flush(struct writer *p) (uint32_t )p->params.fd, p->n_pkts); -for (i =0 ; i < p->n_pkts; i++) -rte_pktmbuf_free (p->pkts[i]); +rte_pktmbuf_free_bulk (p->pkts, p->n_pkts); p->n_pkts =0 ; }
lib/port/rte_swx_port_source_sink.c +1 -5
@@ -52,16 +52,12 @@ static void source_free(void *port) {struct source *p = port; -uint32_t i;if (!p)return ; -for (i =0 ; i < p->n_pkts; i++) -rte_pktmbuf_free (p->pkts[i]); - +rte_pktmbuf_free_bulk (p->pkts, p->n_pkts);free (p->pkts); -free (p); }
Signature · 1 line
2.53.0
PATCH 7/20 net/af_xdp: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- drivers/net/af_xdp/rte_eth_af_xdp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/af_xdp/rte_eth_af_xdp.c +1 -2
@@ -263,8 +263,7 @@ reserve_fill_queue_zc(struct xsk_umem_info *umem, uint16_t reserve_size,uint16_t i;if (unlikely (!xsk_ring_prod__reserve (fq, reserve_size, &idx))) { -for (i =0 ; i < reserve_size; i++) -rte_pktmbuf_free (bufs[i]); +rte_pktmbuf_free_bulk (bufs, reserve_size);AF_XDP_LOG_LINE (DEBUG ,"Failed to reserve enough fq descs." );return -1 ; }
Signature · 1 line
2.53.0
PATCH 8/20 net/cnxk: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- drivers/net/cnxk/cnxk_ethdev.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/cnxk/cnxk_ethdev.c +2 -3
@@ -1913,7 +1913,7 @@ cnxk_nix_dev_stop(struct rte_eth_dev *eth_dev)const struct eth_dev_ops *dev_ops = eth_dev->dev_ops;struct rte_mbuf *rx_pkts[32 ];struct rte_eth_link link; -int count, i, j, rc; +int count, i, rc;void *rxq;/* In case of Inline IPSec, will need to avoid disabling the MCAM rules and NPC Rx
@@ -1951,8 +1951,7 @@ cnxk_nix_dev_stop(struct rte_eth_dev *eth_dev) rxq = eth_dev->data->rx_queues[i]; count = dev->rx_pkt_burst_no_offload (rxq, rx_pkts,32 );while (count) { -for (j =0 ; j < count; j++) -rte_pktmbuf_free (rx_pkts[j]); +rte_pktmbuf_free_bulk (rx_pkts, count); count = dev->rx_pkt_burst_no_offload (rxq, rx_pkts,32 ); } }
Signature · 1 line
2.53.0
PATCH 9/20 net/pfe: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- drivers/net/pfe/pfe_ethdev.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/pfe/pfe_ethdev.c +1 -3
@@ -281,9 +281,7 @@ pfe_eth_open(struct rte_eth_dev *dev) ret =hif_lib_receive_pkt (&client->rx_q[0 ], hif_shm->pool, rx_pkts,32 );while (ret) { -int i; -for (i =0 ; i < ret; i++) -rte_pktmbuf_free (rx_pkts[i]); +rte_pktmbuf_free_bulk (rx_pkts, ret); ret =hif_lib_receive_pkt (&client->rx_q[0 ], hif_shm->pool, rx_pkts,32 );
Signature · 1 line
2.53.0
PATCH 10/20 net/virtio: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- drivers/net/virtio/virtio_rxtx.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-)
drivers/net/virtio/virtio_rxtx.c +7 -13
@@ -723,7 +723,7 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)struct virtnet_rx *rxvq = &vq->rxq;struct rte_mbuf *m;uint16_t desc_idx; -int error, nbufs, i; +int error, nbufs;bool in_order =virtio_with_feature (hw,VIRTIO_F_IN_ORDER );PMD_INIT_FUNC_TRACE ();
@@ -764,8 +764,7 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx) pkts, free_cnt);if (unlikely (error)) { -for (i =0 ; i < free_cnt; i++) -rte_pktmbuf_free (pkts[i]); +rte_pktmbuf_free_bulk (pkts, free_cnt); }else { nbufs += free_cnt; }
@@ -1071,8 +1070,7 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) error =virtqueue_enqueue_recv_refill (vq, new_pkts, free_cnt);if (unlikely (error)) { -for (i =0 ; i < free_cnt; i++) -rte_pktmbuf_free (new_pkts[i]); +rte_pktmbuf_free_bulk (new_pkts, free_cnt); } nb_enqueued += free_cnt; }else {
@@ -1176,8 +1174,7 @@ virtio_recv_pkts_packed(void *rx_queue, struct rte_mbuf **rx_pkts, error =virtqueue_enqueue_recv_refill_packed (vq, new_pkts, free_cnt);if (unlikely (error)) { -for (i =0 ; i < free_cnt; i++) -rte_pktmbuf_free (new_pkts[i]); +rte_pktmbuf_free_bulk (new_pkts, free_cnt); } nb_enqueued += free_cnt; }else {
@@ -1358,8 +1355,7 @@ virtio_recv_pkts_inorder(void *rx_queue, error =virtqueue_enqueue_refill_inorder (vq, new_pkts, free_cnt);if (unlikely (error)) { -for (i =0 ; i < free_cnt; i++) -rte_pktmbuf_free (new_pkts[i]); +rte_pktmbuf_free_bulk (new_pkts, free_cnt); } nb_enqueued += free_cnt; }else {
@@ -1535,8 +1531,7 @@ virtio_recv_mergeable_pkts(void *rx_queue, error =virtqueue_enqueue_recv_refill (vq, new_pkts, free_cnt);if (unlikely (error)) { -for (i =0 ; i < free_cnt; i++) -rte_pktmbuf_free (new_pkts[i]); +rte_pktmbuf_free_bulk (new_pkts, free_cnt); } nb_enqueued += free_cnt; }else {
@@ -1707,8 +1702,7 @@ virtio_recv_mergeable_pkts_packed(void *rx_queue, error =virtqueue_enqueue_recv_refill_packed (vq, new_pkts, free_cnt);if (unlikely (error)) { -for (i =0 ; i < free_cnt; i++) -rte_pktmbuf_free (new_pkts[i]); +rte_pktmbuf_free_bulk (new_pkts, free_cnt); } nb_enqueued += free_cnt; }else {
Signature · 1 line
2.53.0
PATCH 11/20 net/zxdh: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- drivers/net/zxdh/zxdh_queue.c | 7 ++----- drivers/net/zxdh/zxdh_rxtx.c | 3 +-- 2 files changed, 3 insertions(+), 7 deletions(-)
drivers/net/zxdh/zxdh_queue.c +2 -5
@@ -445,11 +445,8 @@ int32_t zxdh_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_iif (likely (rte_pktmbuf_alloc_bulk (rxvq->mpool, new_pkts, free_cnt) ==0 )) { error =zxdh_enqueue_recv_refill_packed (vq, new_pkts, free_cnt); -if (unlikely (error)) { -int32_t i; -for (i =0 ; i < free_cnt; i++) -rte_pktmbuf_free (new_pkts[i]); - } +if (unlikely (error)) +rte_pktmbuf_free_bulk (new_pkts, free_cnt); }else {PMD_DRV_LOG (ERR ,"port %d rxq %d allocated bufs from %s failed" , hw->port_id, logic_qidx, rxvq->mpool->name);
drivers/net/zxdh/zxdh_rxtx.c +1 -2
@@ -970,8 +970,7 @@ zxdh_recv_pkts_packed(void *rx_queue, struct rte_mbuf **rx_pkts,if (!rte_pktmbuf_alloc_bulk (rxvq->mpool, new_pkts, free_cnt)) { error =zxdh_enqueue_recv_refill_packed (vq, new_pkts, free_cnt);if (unlikely (error)) { -for (i =0 ; i < free_cnt; i++) -rte_pktmbuf_free (new_pkts[i]); +rte_pktmbuf_free_bulk (new_pkts, free_cnt); }if (unlikely (zxdh_queue_kick_prepare_packed (vq)))
Signature · 1 line
2.53.0
PATCH 12/20 app/compress-perf: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- app/test-compress-perf/comp_perf_test_common.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
app/test-compress-perf/comp_perf_test_common.c +2 -4
@@ -84,12 +84,10 @@ comp_perf_free_memory(struct comp_test_data *test_data,uint32_t i;if (mem->decomp_bufs !=NULL ) -for (i =0 ; i < mem->total_bufs; i++) -rte_pktmbuf_free (mem->decomp_bufs[i]); +rte_pktmbuf_free_bulk (mem->decomp_bufs, mem->total_bufs);if (mem->comp_bufs !=NULL ) -for (i =0 ; i < mem->total_bufs; i++) -rte_pktmbuf_free (mem->comp_bufs[i]); +rte_pktmbuf_free_bulk (mem->comp_bufs, mem->total_bufs);rte_free (mem->decomp_bufs);rte_free (mem->comp_bufs);
Signature · 1 line
2.53.0
PATCH 13/20 mbuf: allow NULL array in rte_pktmbuf_free_bulk
In reply to Stephen HemmingerThis allows callers to avoid NULL checks and just call rte_pktmbuf_free_bulk, similar to rte_pktmbuf_free.
--- devtools/cocci/nullfree.cocci | 5 ++++- doc/guides/rel_notes/release_26_07.rst | 5 +++++ lib/mbuf/rte_mbuf.c | 3 +++ lib/mbuf/rte_mbuf.h | 1 + 4 files changed, 13 insertions(+), 1 deletion(-)
devtools/cocci/nullfree.cocci +4 -1
@@ -4,7 +4,7 @@ // free(NULL) as a no-op. // @@ -expression E; +expression E, N; @@ ( - if (E != NULL) cmdline_free(E);
@@ -79,6 +79,9 @@ expression E; - if (E != NULL) rte_pktmbuf_free(E); + rte_pktmbuf_free(E); | +- if (E != NULL) rte_pktmbuf_free_bulk(E, N); ++ rte_pktmbuf_free_bulk(E, N); +| - if (E != NULL) rte_rib_free(E); + rte_rib_free(E); |
doc/guides/rel_notes/release_26_07.rst +5 -0
@@ -63,6 +63,11 @@ New Features ``rte_eal_init`` and the application is responsible for probing each device, * ``--auto-probing`` enables the initial bus probing, which is the current default behavior. +* **mbuf: rte_pktmbuf_free_bulk now accepts NULL array pointer.** + + Calling ``rte_pktmbuf_free_bulk`` with a NULL ``mbufs`` argument is a no-op, + matching the behavior of ``rte_pktmbuf_free()`` and ``rte_free()``. + Removed Items -------------
lib/mbuf/rte_mbuf.c +3 -0
@@ -562,6 +562,9 @@ void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count)struct rte_mbuf *m, *m_next, *pending[RTE_PKTMBUF_FREE_PENDING_SZ ];unsigned int idx, nb_pending =0 ; +if (mbufs ==NULL ) +return ; +rte_mbuf_history_mark_bulk (mbufs, count,RTE_MBUF_HISTORY_OP_LIB_FREE );for (idx =0 ; idx < count; idx++) {
lib/mbuf/rte_mbuf.h +1 -0
@@ -1534,6 +1534,7 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m)* @param mbufs * Array of pointers to packet mbufs. * The array may contain NULL pointers. +* The array pointer is NULL function does nothing. * @param count * Array size. */
Signature · 1 line
2.53.0
RE: [PATCH 13/20] mbuf: allow NULL array in rte_pktmbuf_free_bulk
Quoted 7 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Friday, 8 May 2026 22.34This allows callers to avoid NULL checks and just call
rte_pktmbuf_free_bulk, similar torte_pktmbuf_free.Signed-off-by Stephen Hemminger <[email protected]>
I disagree with this patch.
The parameter is an array of (pointers to) mbufs.
We already accept that the array can contain NULL pointers (no mbuf present).
This is extremely forgiving, considering that other fast path functions don't allow NULL pointers in arrays; e.g. rte_eth_tx_burst(), rte_mempool_put_bulk().
But since it's a "free()" class of function, I don't object to it.
However, this patch changes the parameter type from "array" to "array or NULL (no array present)". And I don't think we should change the parameter type; it should remain "array" only.
If there are any scenarios where a non-present array (NULL) is passed to the function, the count should be zero too. And when the count is zero, the function does not dereference the array, so explicitly checking for NULL is superfluous.
We have a convention of not checking parameter validity in fast path functions. And I consider it invalid parameters passing NULL with a non-zero count.
You might argue that this is a "free()" class of function, which warrants checking for NULL; but since it already accepts NULL with zero count, it is already covered.
We could change the function declaration for clarity:
void rte_pktmbuf_free_bulk(
unsigned int count; struct rte_mbuf *mbufs[count], unsigned int count);
Or add a debug assertion at the start of the function:RTE_ASSERT(mbufs != NULL || count == 0);
Quoted 83 lines
--- devtools/cocci/nullfree.cocci | 5 ++++- doc/guides/rel_notes/release_26_07.rst | 5 +++++ lib/mbuf/rte_mbuf.c | 3 +++ lib/mbuf/rte_mbuf.h | 1 + 4 files changed, 13 insertions(+), 1 deletion(-)devtools/cocci/nullfree.cocci +4
-1@@ -4,7 +4,7 @@ // free(NULL) as a no-op. // @@ -expression E; +expression E, N; @@ ( - if (E != NULL) cmdline_free(E);@@ -79,6 +79,9 @@ expression E; - if (E != NULL) rte_pktmbuf_free(E); + rte_pktmbuf_free(E); | +- if (E != NULL) rte_pktmbuf_free_bulk(E, N); ++ rte_pktmbuf_free_bulk(E, N); +| - if (E != NULL) rte_rib_free(E); + rte_rib_free(E); |doc/guides/rel_notes/release_26_07.rst +0
-0@@ -63,6 +63,11 @@ New Features ``rte_eal_init`` and the application is responsible for probing each device, * ``--auto-probing`` enables the initial bus probing, which is thecurrent default behavior.
doc/guides/rel_notes/release_26_07.rst +3
-0+* **mbuf: rte_pktmbuf_free_bulk now accepts NULL array pointer.** + + Calling ``rte_pktmbuf_free_bulk`` with a NULL ``mbufs`` argument isa no-op,
doc/guides/rel_notes/release_26_07.rst +2
-0+ matching the behavior of ``rte_pktmbuf_free()`` and ``rte_free()``. + Removed Items -------------lib/mbuf/rte_mbuf.c +3
-0@@ -562,6 +562,9 @@ void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count)struct rte_mbuf *m, *m_next, *pending[RTE_PKTMBUF_FREE_PENDING_SZ ];unsigned int idx, nb_pending =0 ; +if (mbufs ==NULL ) +return ; + rte_mbuf_history_mark_bulk(mbufs, count,
RTE_MBUF_HISTORY_OP_LIB_FREE);lib/mbuf/rte_mbuf.c +0
-0for (idx =0 ; idx < count; idx++) {lib/mbuf/rte_mbuf.h +1
-0@@ -1534,6 +1534,7 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m) * @param mbufs * Array of pointers to packet mbufs. * The array may contain NULL pointers. + * The array pointer is NULL function does nothing. * @param count * Array size.*/
--
2.53.0
Re: [PATCH 13/20] mbuf: allow NULL array in rte_pktmbuf_free_bulk
Quoted 27 lines · On Sat, 9 May 2026 10:47:53 +0200 Morten Brørup <[email protected]>…
Quoted 7 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Friday, 8 May 2026 22.34This allows callers to avoid NULL checks and just call
rte_pktmbuf_free_bulk, similar torte_pktmbuf_free.Signed-off-by Stephen Hemminger <[email protected]>I disagree with this patch.
The parameter is an array of (pointers to) mbufs.
We already accept that the array can contain NULL pointers (no mbuf present).
This is extremely forgiving, considering that other fast path functions don't allow NULL pointers in arrays; e.g.rte_eth_tx_burst(),rte_mempool_put_bulk().
But since it's a "free()" class of function, I don't object to it.However, this patch changes the parameter type from "array" to "array or NULL (no array present)". And I don't think we should change the parameter type; it should remain "array" only.
If there are any scenarios where a non-present array (NULL) is passed to the function, the count should be zero too. And when the count is zero, the function does not dereference the array, so explicitly checking for NULL is superfluous.
We have a convention of not checking parameter validity in fast path functions. And I consider it invalid parameters passing NULL with a non-zero count.
You might argue that this is a "
free()" class of function, which warrants checking for NULL; but since it already accepts NULL with zero count, it is already covered.
Quoted 8 lines
We could change the function declaration for clarity:
void rte_pktmbuf_free_bulk(
unsigned int count; struct rte_mbuf *mbufs[count], unsigned int count);Or add a debug assertion at the start of the function:
RTE_ASSERT(mbufs != NULL || count == 0);
Ok, it was more motivated by common pattern in driver cleanup paths like:
app/test-compress-perf/comp_perf_test_common.c +2 -4
@@ -83,11 +83,9 @@ comp_perf_free_memory(struct comp_test_data *test_data, {uint32_t i; -if (mem->decomp_bufs !=NULL ) -rte_pktmbuf_free_bulk (mem->decomp_bufs, mem->total_bufs); +rte_pktmbuf_free_bulk (mem->decomp_bufs, mem->total_bufs); -if (mem->comp_bufs !=NULL ) -rte_pktmbuf_free_bulk (mem->comp_bufs, mem->total_bufs); +rte_pktmbuf_free_bulk (mem->comp_bufs, mem->total_bufs);
RE: [PATCH 13/20] mbuf: allow NULL array in rte_pktmbuf_free_bulk
Quoted 60 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Saturday, 9 May 2026 17.47Quoted 6 lines · On Sat, 9 May 2026 10:47:53 +0200 Morten Brørup <[email protected]>…
Quoted 6 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Friday, 8 May 2026 22.34This allows callers to avoid NULL checks and just call
rte_pktmbuf_free_bulk, similar torte_pktmbuf_free.Quoted 6 lines
Quoted 1 line
Signed-off-by Stephen Hemminger <[email protected]>I disagree with this patch.
The parameter is an array of (pointers to) mbufs.
We already accept that the array can contain NULL pointers (no mbufpresent).
Quoted 1 line
This is extremely forgiving, considering that other fast path
functions don't allow NULL pointers in arrays;
Quoted 4 lines
e.g.
rte_eth_tx_burst(),rte_mempool_put_bulk().
But since it's a "free()" class of function, I don't object to it.However, this patch changes the parameter type from "array" to "array
or NULL (no array present)".
Quoted 1 line
And I don't think we should change the parameter type; it should
remain "array" only.
Quoted 2 lines
If there are any scenarios where a non-present array (NULL) is passed
to the function, the count should be zero too.
Quoted 1 line
And when the count is zero, the function does not dereference the
array, so explicitly checking for NULL is superfluous.
Quoted 2 lines
We have a convention of not checking parameter validity in fast path
functions.
Quoted 1 line
And I consider it invalid parameters passing NULL with a non-zero
count.
Quoted 2 lines
You might argue that this is a "
free()" class of function, whichwarrants checking for NULL; but since it already accepts NULL with zero count, it is already covered.
Quoted 9 lines
We could change the function declaration for clarity:
void rte_pktmbuf_free_bulk(
unsigned int count; struct rte_mbuf *mbufs[count], unsigned int count);Or add a debug assertion at the start of the function:
RTE_ASSERT(mbufs != NULL || count == 0);Ok, it was more motivated by common pattern in driver cleanup paths like:
app/test-compress-perf/comp_perf_test_common.c +0
-0@@ -83,11 +83,9 @@ comp_perf_free_memory(struct comp_test_data *test_data, {
app/test-compress-perf/comp_perf_test_common.c comp_perf_free_memory(struct comp_test_data · line 90
Quoted 10 lines
app/test-compress-perf/comp_perf_test_common.c +2
-4uint32_t i; -if (mem->decomp_bufs !=NULL ) -rte_pktmbuf_free_bulk (mem->decomp_bufs, mem->total_bufs); +rte_pktmbuf_free_bulk (mem->decomp_bufs, mem->total_bufs); -if (mem->comp_bufs !=NULL ) -rte_pktmbuf_free_bulk (mem->comp_bufs, mem->total_bufs); +rte_pktmbuf_free_bulk (mem->comp_bufs, mem->total_bufs);
Skimming comp_perf_test_common.c, it looks like mem->total_bufs is initialized to the number of wanted buffers, and then mem->decomp_bufs is set up afterwards. In other words, total_bufs can be non-zero while comp_bufs is NULL.
IMO, removing the NULL comparison here would pass invalid parameters to rte_pktmbuf_free_bulk().
Train of thoughts...
On the other hand, it does provide a good example where considering rte_pktmbuf_free_bulk() a "free()" class function accepting a NULL pointer would be helpful. And the added performance cost of checking for a NULL pointer is per burst, not per packet.
I'm not as strongly opposed as I was initially.
However, looking at it in a broader scope gets me be back to being opposed:
This patch is for freeing mbufs.
If we consider freeing mempool objects, the cleanup function would call rte_mempool_put_bulk() to free the objects, which is the function for freeing previously allocated mempool objects. It just happens to not have "free" as part of its name.
The mempool single object "free()" function, rte_mempool_put(), doesn't accept a NULL pointer. Similarly, the mempool bulk free function, rte_mempool_put_bulk(), doesn't accept holes (NULL pointers) in the array. I certainly do not want to introduce holes into mempool object arrays.
Maybe it was a bad decision to allow holes in mbuf arrays being passed to rte_pktmbuf_free_bulk(). Such holes are not accepted in any other DPDK APIs.
At this point, I'm still not in favor of this patch.
It's defensive coding (with a performance cost, however small) in a fast path function.
Re: [PATCH 13/20] mbuf: allow NULL array in rte_pktmbuf_free_bulk
Quoted 85 lines · On Sun, 10 May 2026 14:31:57 +0200 Morten Brørup <[email protected]>…
Quoted 60 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Saturday, 9 May 2026 17.47Quoted 6 lines · On Sat, 9 May 2026 10:47:53 +0200 Morten Brørup <[email protected]>…
Quoted 6 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Friday, 8 May 2026 22.34This allows callers to avoid NULL checks and just call
rte_pktmbuf_free_bulk, similar torte_pktmbuf_free.Quoted 6 lines
Quoted 1 line
Signed-off-by Stephen Hemminger <[email protected]>I disagree with this patch.
The parameter is an array of (pointers to) mbufs.
We already accept that the array can contain NULL pointers (no mbufpresent).
Quoted 1 line
This is extremely forgiving, considering that other fast path
functions don't allow NULL pointers in arrays;
Quoted 4 lines
e.g.
rte_eth_tx_burst(),rte_mempool_put_bulk().
But since it's a "free()" class of function, I don't object to it.However, this patch changes the parameter type from "array" to "array
or NULL (no array present)".
Quoted 1 line
And I don't think we should change the parameter type; it should
remain "array" only.
Quoted 2 lines
If there are any scenarios where a non-present array (NULL) is passed
to the function, the count should be zero too.
Quoted 1 line
And when the count is zero, the function does not dereference the
array, so explicitly checking for NULL is superfluous.
Quoted 2 lines
We have a convention of not checking parameter validity in fast path
functions.
Quoted 1 line
And I consider it invalid parameters passing NULL with a non-zero
count.
Quoted 2 lines
You might argue that this is a "
free()" class of function, whichwarrants checking for NULL; but since it already accepts NULL with zero count, it is already covered.
Quoted 9 lines
We could change the function declaration for clarity:
void rte_pktmbuf_free_bulk(
unsigned int count; struct rte_mbuf *mbufs[count], unsigned int count);Or add a debug assertion at the start of the function:
RTE_ASSERT(mbufs != NULL || count == 0);Ok, it was more motivated by common pattern in driver cleanup paths like:
app/test-compress-perf/comp_perf_test_common.c +0
-0@@ -83,11 +83,9 @@ comp_perf_free_memory(struct comp_test_data *test_data, {app/test-compress-perf/comp_perf_test_common.c comp_perf_free_memory(struct comp_test_data · line 90
Quoted 10 lines
app/test-compress-perf/comp_perf_test_common.c +2
-4uint32_t i; -if (mem->decomp_bufs !=NULL ) -rte_pktmbuf_free_bulk (mem->decomp_bufs, mem->total_bufs); +rte_pktmbuf_free_bulk (mem->decomp_bufs, mem->total_bufs); -if (mem->comp_bufs !=NULL ) -rte_pktmbuf_free_bulk (mem->comp_bufs, mem->total_bufs); +rte_pktmbuf_free_bulk (mem->comp_bufs, mem->total_bufs);Skimming
comp_perf_test_common.c, it looks likemem->total_bufsis initialized to the number of wanted buffers, and thenmem->decomp_bufsis set up afterwards. In other words,total_bufscan be non-zero whilecomp_bufsis NULL.IMO, removing the NULL comparison here would pass invalid parameters to
rte_pktmbuf_free_bulk().Train of thoughts...
On the other hand, it does provide a good example where considering
rte_pktmbuf_free_bulk()a "free()" class function accepting a NULL pointer would be helpful. And the added performance cost of checking for a NULL pointer is per burst, not per packet.
I'm not as strongly opposed as I was initially.However, looking at it in a broader scope gets me be back to being opposed:
This patch is for freeing mbufs.
If we consider freeing mempool objects, the cleanup function would callrte_mempool_put_bulk()to free the objects, which is the function for freeing previously allocated mempool objects. It just happens to not have "free" as part of its name.
Quoted 9 lines
The mempool single object "
free()" function,rte_mempool_put(), doesn't accept a NULL pointer. Similarly, the mempool bulk free function,rte_mempool_put_bulk(), doesn't accept holes (NULL pointers) in the array. I certainly do not want to introduce holes into mempool object arrays.Maybe it was a bad decision to allow holes in mbuf arrays being passed to
rte_pktmbuf_free_bulk(). Such holes are not accepted in any other DPDK APIs.At this point, I'm still not in favor of this patch.
It's defensive coding (with a performance cost, however small) in a fast path function.
More thoughts.
- allowing NULL array is not worth it; not a big win, and only one place mattered
- allowing holes in array seems odd, and not that useful. Probably can't change now. Not sure why callers would need it.
- Probably should add RTE_ASSERT() into free bulk. Should allow rte_pktmbuf_free_bulk(NULL, 0) for consistency with some other API's that take array and count. But assert should trigger on rte_pktmbuf_free_bulk(NULL, 1)
PATCH 14/20 net/zxdh: remove unnecessary null check
In reply to Stephen HemmingerRemove unnecessary if check before calling free.
Generated by devtools/cocci/null_free.cocci
--- drivers/net/zxdh/zxdh_np.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/zxdh/zxdh_np.c +1 -2
@@ -12383,8 +12383,7 @@ zxdh_np_dtb_acl_data_clear(uint32_t dev_id, uint32_t queue_id, &element_id);free (data_buff);free (mask_buff); -if (eram_buff) -free (eram_buff); +free (eram_buff);free (p_entry_arr);ZXDH_COMM_CHECK_DEV_RC (dev_id, rc,"zxdh_np_dtb_acl_dma_insert" );
Signature · 1 line
2.53.0
PATCH 15/20 net/ice: remove unnecessary null check
In reply to Stephen HemmingerRemove unnecessary if check before calling free.
Generated by devtools/cocci/null_free.cocci
--- drivers/net/intel/ice/ice_dcf_sched.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/intel/ice/ice_dcf_sched.c +2 -4
@@ -877,10 +877,8 @@ static int ice_dcf_hierarchy_commit(struct rte_eth_dev *dev,return ret_val; fail_clear: -if (vf_bw !=NULL ) -free (vf_bw); -if (tc_bw !=NULL ) -free (tc_bw); +free (vf_bw); +free (tc_bw);/* clear all the traffic manager configuration */ if (clear_on_fail) {
Signature · 1 line
2.53.0
PATCH 16/20 net/bnxt: remove unnecessary null check
In reply to Stephen HemmingerRemove unnecessary if check before calling rte_free.
Generated by devtools/cocci/null_free.cocci
--- drivers/net/bnxt/tf_core/v3/tfo.c | 6 ++---- drivers/net/bnxt/tf_ulp/ulp_sc_mgr.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-)
drivers/net/bnxt/tf_core/v3/tfo.c +2 -4
@@ -183,13 +183,11 @@ void tfo_close(void **tfo) } } } -if (tim) -rte_free (tim); +rte_free (tim); tfco->ts_tim =NULL ; tfco->tfgo =NULL ; -if (*tfo) -rte_free (*tfo); +rte_free (*tfo); *tfo =NULL ; } }
drivers/net/bnxt/tf_ulp/ulp_sc_mgr.c +2 -4
@@ -169,11 +169,9 @@ ulp_sc_mgr_deinit(struct bnxt_ulp_context *ctxt)ulp_sc_mgr_thread_cancel (ctxt); -if (ulp_sc_info->stats_cache_tbl) -rte_free (ulp_sc_info->stats_cache_tbl); +rte_free (ulp_sc_info->stats_cache_tbl); -if (ulp_sc_info->read_data) -rte_free (ulp_sc_info->read_data); +rte_free (ulp_sc_info->read_data);rte_free (ulp_sc_info);
Signature · 1 line
2.53.0
PATCH 17/20 test: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- app/test/sample_packet_forward.c | 5 +---- app/test/test_distributor.c | 4 +--- app/test/test_dmadev.c | 6 ++---- app/test/test_ipfrag.c | 4 +--- app/test/test_link_bonding.c | 13 ++++--------- app/test/test_pmd_perf.c | 3 +-- app/test/test_pmd_tap.c | 3 +-- app/test/test_reorder.c | 12 ++++-------- app/test/test_table_ports.c | 12 ++++-------- app/test/test_table_tables.c | 21 +++++++-------------- 10 files changed, 26 insertions(+), 57 deletions(-)
app/test/sample_packet_forward.c +1 -4
@@ -115,10 +115,7 @@ test_get_mbuf_from_pool(struct rte_mempool **mp, struct rte_mbuf **pbuf,void test_put_mbuf_to_pool (struct rte_mempool *mp,struct rte_mbuf **pbuf) { -int itr =0 ; - -for (itr =0 ; itr <NUM_PACKETS ; itr++) -rte_pktmbuf_free (pbuf[itr]); +rte_pktmbuf_free_bulk (pbuf,NUM_PACKETS );rte_mempool_free (mp); }
app/test/test_distributor.c +1 -3
@@ -309,7 +309,6 @@ handle_work_with_free_mbufs(void *arg) alignas(RTE_CACHE_LINE_SIZE )struct rte_mbuf *buf[8 ];struct worker_params *wp = arg;struct rte_distributor *d = wp->dist; -unsigned int i;unsigned int num;unsigned int id =rte_atomic_fetch_add_explicit (&worker_idx,1 , rte_memory_order_relaxed);
@@ -317,8 +316,7 @@ handle_work_with_free_mbufs(void *arg)while (!quit) {rte_atomic_fetch_add_explicit (&worker_stats[id].handled_packets, num, rte_memory_order_relaxed); -for (i =0 ; i < num; i++) -rte_pktmbuf_free (buf[i]); +rte_pktmbuf_free_bulk (buf, num); num =rte_distributor_get_pkt (d, id, buf,NULL ,0 ); } rte_atomic_fetch_add_explicit(&worker_stats[id].handled_packets, num,
app/test/test_dmadev.c +2 -4
@@ -499,10 +499,8 @@ test_enqueue_sg_copies(int16_t dev_id, uint16_t vchan)ERR_RETURN ("Error:incorrect job id received when no job done, %u [expected %u]\n" , id,0 ); -for (i =0 ; i < n_src; i++) -rte_pktmbuf_free (src[i]); -for (i =0 ; i < n_dst; i++) -rte_pktmbuf_free (dst[i]); +rte_pktmbuf_free_bulk (src, n_src); +rte_pktmbuf_free_bulk (dst, n_dst);/* Verify that completion returns nothing more */ if (rte_dma_completed (dev_id,0 ,1 ,NULL ,NULL ) !=0 )
app/test/test_ipfrag.c +1 -3
@@ -240,9 +240,7 @@ v6_allocate_packet_of(struct rte_mbuf *b, int fill, size_t s, uint8_t ttl,static inline void test_free_fragments (struct rte_mbuf *mb[],uint32_t num) { -uint32_t i; -for (i =0 ; i < num; i++) -rte_pktmbuf_free (mb[i]); +rte_pktmbuf_free_bulk (mb, num); } static inline void
app/test/test_link_bonding.c +4 -9
@@ -1476,10 +1476,7 @@ verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)static void free_mbufs (struct rte_mbuf **mbufs,int nb_mbufs) { -int i; - -for (i =0 ; i < nb_mbufs; i++) -rte_pktmbuf_free (mbufs[i]); +rte_pktmbuf_free_bulk (mbufs, nb_mbufs); }#define TEST_RR_MEMBER_TX_FAIL_MEMBER_COUNT (2)
@@ -4193,7 +4190,7 @@ testsuite_teardown(void)static void free_virtualpmd_tx_queue (void ) { -int i, member_port, to_free_cnt; +int member_port, to_free_cnt;struct rte_mbuf *pkts_to_free[MAX_PKT_BURST ];/* Free tx queue of virtual pmd */
@@ -4202,8 +4199,7 @@ free_virtualpmd_tx_queue(void) to_free_cnt =virtual_ethdev_get_mbufs_from_tx_queue ( test_params->member_port_ids[member_port], pkts_to_free,MAX_PKT_BURST ); -for (i =0 ; i < to_free_cnt; i++) -rte_pktmbuf_free (pkts_to_free[i]); +rte_pktmbuf_free_bulk (pkts_to_free, to_free_cnt); } }
@@ -4381,8 +4377,7 @@ test_tlb_rx_burst(void) }/* free mbufs */ -for (i =0 ; i < burst_size; i++) -rte_pktmbuf_free (rx_pkt_burst[i]); +rte_pktmbuf_free_bulk (rx_pkt_burst, burst_size);/* reset bonding device stats */ rte_eth_stats_reset (test_params->bonding_port_id);
app/test/test_pmd_perf.c +1 -2
@@ -602,8 +602,7 @@ poll_burst(void *args) total, MAX_IDLE - timeout);/* clean up */ total = pkt_per_port * conf->nb_ports - total; -for (i =0 ; i < total; i++) -rte_pktmbuf_free (pkts_burst[i]); +rte_pktmbuf_free_bulk (pkts_burst, total);rte_free (pkts_burst);
app/test/test_pmd_tap.c +1 -2
@@ -192,8 +192,7 @@ test_tap_send_receive(void)printf ("Received %u packets on port %d\n" , nb_rx, tap_port0);/* Free received packets */ -for (i =0 ; i < nb_rx; i++) -rte_pktmbuf_free (rx_mbufs[i]); +rte_pktmbuf_free_bulk (rx_mbufs, nb_rx);return TEST_SUCCESS ; }
app/test/test_reorder.c +4 -8
@@ -208,8 +208,7 @@ test_reorder_insert(void) ret =0 ; exit:rte_reorder_free (b); -for (i =0 ; i <INSERT_NUM_BUFS ; i++) -rte_pktmbuf_free (bufs[i]); +rte_pktmbuf_free_bulk (bufs,INSERT_NUM_BUFS );return ret; }
@@ -382,8 +381,7 @@ test_reorder_drain_up_to_seqn(void) ret =-1 ; goto exit; } -for (i =0 ; i <2 ; i++) -rte_pktmbuf_free (robufs[i]); +rte_pktmbuf_free_bulk (robufs,2 );memset (robufs,0 ,sizeof (robufs));/* Insert more packets
@@ -406,8 +404,7 @@ test_reorder_drain_up_to_seqn(void) ret =-1 ; goto exit; } -for (i =0 ; i <2 ; i++) -rte_pktmbuf_free (robufs[i]); +rte_pktmbuf_free_bulk (robufs,2 );memset (robufs,0 ,sizeof (robufs)); ret =0 ;
@@ -483,8 +480,7 @@ test_reorder_set_seqn(void) ret =0 ; exit:rte_reorder_free (b); -for (i =0 ; i <SET_SEQN_NUM_BUFS ; i++) -rte_pktmbuf_free (bufs[i]); +rte_pktmbuf_free_bulk (bufs,SET_SEQN_NUM_BUFS );return ret; }
app/test/test_table_ports.c +4 -8
@@ -73,8 +73,7 @@ test_port_ring_reader(void)if (received_pkts < expected_pkts)return -6 ; -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (res_mbuf[i]); +rte_pktmbuf_free_bulk (res_mbuf,RTE_PORT_IN_BURST_SIZE_MAX );return 0 ; }
@@ -156,8 +155,7 @@ test_port_ring_writer(void)if (received_pkts < expected_pkts)return -8 ; -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (res_mbuf[i]); +rte_pktmbuf_free_bulk (res_mbuf,RTE_PORT_IN_BURST_SIZE_MAX );/* TX Bulk */ for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++)
@@ -171,8 +169,7 @@ test_port_ring_writer(void)if (received_pkts < expected_pkts)return -8 ; -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (res_mbuf[i]); +rte_pktmbuf_free_bulk (res_mbuf,RTE_PORT_IN_BURST_SIZE_MAX );for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) mbuf[i] =rte_pktmbuf_alloc (pool);
@@ -186,8 +183,7 @@ test_port_ring_writer(void)if (received_pkts < expected_pkts)return -9 ; -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (res_mbuf[i]); +rte_pktmbuf_free_bulk (res_mbuf,RTE_PORT_IN_BURST_SIZE_MAX );return 0 ; }
app/test/test_table_tables.c +7 -14
@@ -162,8 +162,7 @@ test_table_stub(void)return -2 ;/* Free resources */ -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (mbufs[i]); +rte_pktmbuf_free_bulk (mbufs,RTE_PORT_IN_BURST_SIZE_MAX );return 0 ; }
@@ -276,8 +275,7 @@ test_table_array(void)return -13 ;/* Free resources */ -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (mbufs[i]); +rte_pktmbuf_free_bulk (mbufs,RTE_PORT_IN_BURST_SIZE_MAX ); status = rte_table_array_ops.f_free (table);
@@ -442,8 +440,7 @@ test_table_lpm(void)return -23 ;/* Free resources */ -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (mbufs[i]); +rte_pktmbuf_free_bulk (mbufs,RTE_PORT_IN_BURST_SIZE_MAX ); status = rte_table_lpm_ops.f_free (table);
@@ -620,8 +617,7 @@ test_table_lpm_ipv6(void)return -24 ;/* Free resources */ -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (mbufs[i]); +rte_pktmbuf_free_bulk (mbufs,RTE_PORT_IN_BURST_SIZE_MAX ); status = rte_table_lpm_ipv6_ops.f_free (table);
@@ -723,8 +719,7 @@ test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size)return -13 ;/* Free resources */ -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (mbufs[i]); +rte_pktmbuf_free_bulk (mbufs,RTE_PORT_IN_BURST_SIZE_MAX ); status = ops->f_free (table);
@@ -833,8 +828,7 @@ test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size)return -13 ;/* Free resources */ -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (mbufs[i]); +rte_pktmbuf_free_bulk (mbufs,RTE_PORT_IN_BURST_SIZE_MAX ); status = ops->f_free (table);
@@ -1047,8 +1041,7 @@ test_table_hash_cuckoo(void)return -20 ;/* Free resources */ -for (i =0 ; i <RTE_PORT_IN_BURST_SIZE_MAX ; i++) -rte_pktmbuf_free (mbufs[i]); +rte_pktmbuf_free_bulk (mbufs,RTE_PORT_IN_BURST_SIZE_MAX ); status = rte_table_hash_cuckoo_ops.f_free (table);
Signature · 1 line
2.53.0
PATCH 18/20 app/test-dma-perf: remove unnecessary null check
In reply to Stephen HemmingerRemove unnecessary if check before calling rte_pktmbuf_free_bulk.
Generated by devtools/cocci/null_free.cocci
--- app/test-dma-perf/benchmark.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
app/test-dma-perf/benchmark.c +2 -4
@@ -690,10 +690,8 @@ teardown_memory_env(uint32_t nr_buf, struct rte_mbuf **srcs, struct rte_mbuf **d struct rte_dma_op **dma_ops) {/* free mbufs used in the test */ -if (srcs !=NULL ) -rte_pktmbuf_free_bulk (srcs, nr_buf); -if (dsts !=NULL ) -rte_pktmbuf_free_bulk (dsts, nr_buf); +rte_pktmbuf_free_bulk (srcs, nr_buf); +rte_pktmbuf_free_bulk (dsts, nr_buf);/* free the points for the mbufs */ rte_free (srcs);
Signature · 1 line
2.53.0
fengchengwen
NAKRe: [PATCH 18/20] app/test-dma-perf: remove unnecessary null check
NACK
The srcs / dsts may be NULL if setup_memory_env() failed.
Quoted 26 lines · Stephen Hemminger
Remove unnecessary if check before calling
rte_pktmbuf_free_bulk.Generated by
devtools/cocci/null_free.cocciSigned-off-by Stephen Hemminger <[email protected]>--- app/test-dma-perf/benchmark.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)app/test-dma-perf/benchmark.c +2
-4@@ -690,10 +690,8 @@ teardown_memory_env(uint32_t nr_buf, struct rte_mbuf **srcs, struct rte_mbuf **d struct rte_dma_op **dma_ops) {/* free mbufs used in the test */ -if (srcs !=NULL ) -rte_pktmbuf_free_bulk (srcs, nr_buf); -if (dsts !=NULL ) -rte_pktmbuf_free_bulk (dsts, nr_buf); +rte_pktmbuf_free_bulk (srcs, nr_buf); +rte_pktmbuf_free_bulk (dsts, nr_buf);/* free the points for the mbufs */ rte_free (srcs);
PATCH 19/20 app/test-compress-perf: remove unnecessary null check
In reply to Stephen HemmingerRemove unnecessary if check before calling rte_free and rte_pktmbuf_free_bulk.
Generated by devtools/cocci/null_free.cocci
--- app/test-compress-perf/comp_perf_test_common.c | 6 ++---- app/test-compress-perf/main.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-)
app/test-compress-perf/comp_perf_test_common.c +2 -4
@@ -83,11 +83,9 @@ comp_perf_free_memory(struct comp_test_data *test_data, {uint32_t i; -if (mem->decomp_bufs !=NULL ) -rte_pktmbuf_free_bulk (mem->decomp_bufs, mem->total_bufs); +rte_pktmbuf_free_bulk (mem->decomp_bufs, mem->total_bufs); -if (mem->comp_bufs !=NULL ) -rte_pktmbuf_free_bulk (mem->comp_bufs, mem->total_bufs); +rte_pktmbuf_free_bulk (mem->comp_bufs, mem->total_bufs);rte_free (mem->decomp_bufs);rte_free (mem->comp_bufs);
app/test-compress-perf/main.c +2 -4
@@ -392,15 +392,13 @@ comp_perf_dump_dictionary_data(struct comp_test_data *td)if (fread (data, data_to_read,1 , f) !=1 ) {RTE_LOG (ERR ,USER1 ,"Input file could not be read\n" ); -if (td->dictionary_data) -rte_free (td->dictionary_data); +rte_free (td->dictionary_data); goto end; }if (fseek (f,0 ,SEEK_SET ) !=0 ) {RTE_LOG (ERR ,USER1 ,"Size of input could not be calculated\n" ); -if (td->dictionary_data) -rte_free (td->dictionary_data); +rte_free (td->dictionary_data); goto end; } remaining_data -= data_to_read;
Signature · 1 line
2.53.0
PATCH 20/20 examples: use rte_pktmbuf_free_bulk
In reply to Stephen HemmingerReplace open-coded loop with rte_pktmbuf_free_bulk().
Generated by devtools/cocci/free_bulk.cocci.
--- examples/bbdev_app/main.c | 4 +--- examples/l2fwd-crypto/main.c | 4 ++-- .../client_server_mp/mp_client/client.c | 7 +++---- .../multi_process/client_server_mp/mp_server/main.c | 5 ++--- examples/ntb/ntb_fwd.c | 12 +++++------- examples/packet_ordering/main.c | 5 +---- examples/server_node_efd/efd_node/node.c | 7 +++---- examples/server_node_efd/efd_server/main.c | 5 ++--- examples/vhost/main.c | 3 +-- 9 files changed, 20 insertions(+), 32 deletions(-)
examples/bbdev_app/main.c +1 -3
@@ -291,9 +291,7 @@ print_mac(unsigned int portid, struct rte_ether_addr *bbdev_ports_eth_address)static inline void pktmbuf_free_bulk (struct rte_mbuf **mbufs,unsigned int nb_to_free) { -unsigned int i; -for (i =0 ; i < nb_to_free; ++i) -rte_pktmbuf_free (mbufs[i]); +rte_pktmbuf_free_bulk (mbufs, nb_to_free); } static inline void
examples/l2fwd-crypto/main.c +2 -2
@@ -931,8 +931,8 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops_burst, nb_rx) != nb_rx) { -for (j =0 ; j < nb_rx; j++) -rte_pktmbuf_free (pkts_burst[j]); +rte_pktmbuf_free_bulk (pkts_burst, + nb_rx); nb_rx =0 ; }
examples/multi_process/client_server_mp/mp_client/client.c +3 -4
@@ -117,15 +117,14 @@ parse_app_args(int argc, char *argv[])*/ static void flush_tx_error_callback (struct rte_mbuf **unsent,uint16_t count, -void *userdata) { -int i; +void *userdata) +{uint16_t port_id = (uintptr_t )userdata; tx_stats->tx_drop[port_id] += count;/* free the mbufs which failed from transmit */ -for (i =0 ; i < count; i++) -rte_pktmbuf_free (unsent[i]); +rte_pktmbuf_free_bulk (unsent, count); }
examples/multi_process/client_server_mp/mp_server/main.c +2 -3
@@ -195,7 +195,6 @@ clear_stats(void)static void flush_rx_queue (uint16_t client) { -uint16_t j;struct client *cl;if (cl_rx_buf[client].count ==0 )
@@ -204,8 +203,8 @@ flush_rx_queue(uint16_t client) cl = &clients[client];if (rte_ring_enqueue_bulk (cl->rx_q, (void **)cl_rx_buf[client].buffer, cl_rx_buf[client].count,NULL ) ==0 ){ -for (j =0 ; j < cl_rx_buf[client].count; j++) -rte_pktmbuf_free (cl_rx_buf[client].buffer[j]); +rte_pktmbuf_free_bulk (cl_rx_buf[client].buffer, + cl_rx_buf[client].count); cl->stats.rx_drop += cl_rx_buf[client].count; }else
examples/ntb/ntb_fwd.c +5 -7
@@ -253,8 +253,7 @@ cmd_send_parsed(void *parsed_result, (void *)queue_id);if (ret <0 ) {printf ("Enqueue failed with err %d\n" , ret); -for (j =0 ; j < nb_pkt; j++) -rte_pktmbuf_free (mbuf_send[j]); +rte_pktmbuf_free_bulk (mbuf_send, nb_pkt); goto clean; } nb_tx = ret;
@@ -387,8 +386,8 @@ start_iofwd_per_lcore(void *param)if (ret <0 ) {printf ("Enqueue failed with err %d\n" , ret); -for (j =0 ; j < nb_rx; j++) -rte_pktmbuf_free (pkts_burst[j]); +rte_pktmbuf_free_bulk (pkts_burst, + nb_rx); goto clean; } nb_tx = ret;
@@ -476,7 +475,7 @@ start_txonly_per_lcore(void *param)struct ntb_fwd_lcore_conf *conf = param;struct ntb_fwd_stream fs;uint16_t nb_pkt, nb_tx; -int i, j, ret; +int i, ret;for (i =0 ; i <NTB_MAX_PKT_BURST ; i++) ntb_buf[i] = (struct rte_rawdev_buf *)
@@ -517,8 +516,7 @@ start_txonly_per_lcore(void *param) nb_pkt, (void *)(size_t)fs.qp_id);if (ret <0 ) {printf ("Enqueue failed with err %d\n" , ret); -for (j =0 ; j < nb_pkt; j++) -rte_pktmbuf_free (pkts_burst[j]); +rte_pktmbuf_free_bulk (pkts_burst, nb_pkt); goto clean; } nb_tx = ret;
examples/packet_ordering/main.c +1 -4
@@ -128,10 +128,7 @@ get_previous_lcore_id(unsigned int id)static inline void pktmbuf_free_bulk (struct rte_mbuf *mbuf_table[],unsigned n) { -unsigned int i; - -for (i =0 ; i < n; i++) -rte_pktmbuf_free (mbuf_table[i]); +rte_pktmbuf_free_bulk (mbuf_table, n); }/* display usage */
examples/server_node_efd/efd_node/node.c +3 -4
@@ -121,15 +121,14 @@ parse_app_args(int argc, char *argv[])*/ static void flush_tx_error_callback (struct rte_mbuf **unsent,uint16_t count, -void *userdata) { -int i; +void *userdata) +{uint16_t port_id = (uintptr_t )userdata; tx_stats->tx_drop[port_id] += count;/* free the mbufs which failed from transmit */ -for (i =0 ; i < count; i++) -rte_pktmbuf_free (unsent[i]); +rte_pktmbuf_free_bulk (unsent, count); }
examples/server_node_efd/efd_server/main.c +2 -3
@@ -218,7 +218,6 @@ clear_stats(void)static void flush_rx_queue (uint16_t node) { -uint16_t j;struct node *cl;if (cl_rx_buf[node].count ==0 )
@@ -227,8 +226,8 @@ flush_rx_queue(uint16_t node) cl = &nodes[node];if (rte_ring_enqueue_bulk (cl->rx_q, (void **)cl_rx_buf[node].buffer, cl_rx_buf[node].count,NULL ) != cl_rx_buf[node].count){ -for (j =0 ; j < cl_rx_buf[node].count; j++) -rte_pktmbuf_free (cl_rx_buf[node].buffer[j]); +rte_pktmbuf_free_bulk (cl_rx_buf[node].buffer, + cl_rx_buf[node].count); cl->stats.rx_drop += cl_rx_buf[node].count; }else cl->stats.rx += cl_rx_buf[node].count;
examples/vhost/main.c +1 -2
@@ -1006,8 +1006,7 @@ unlink_vmdq(struct vhost_dev *vdev) (uint16_t)vdev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);while (rx_count) { -for (i =0 ; i < rx_count; i++) -rte_pktmbuf_free (pkts_burst[i]); +rte_pktmbuf_free_bulk (pkts_burst, rx_count); rx_count =rte_eth_rx_burst (ports[0 ], (uint16_t )vdev->vmdq_rx_q, pkts_burst,MAX_PKT_BURST );
Signature · 1 line
2.53.0