From 014e609ca6710bb88c326aefd9ed8632dd4eaf7a Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Mon, 11 Sep 2023 16:20:07 +0300 Subject: [PATCH] linux-gen: dpdk: implement don't free option Implemented packet output don't free option for DPDK packet IO. Option is available only when not using zero copy mode. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo --- platform/linux-generic/odp_packet_io.c | 1 - platform/linux-generic/pktio/dpdk.c | 30 +++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 349df6d337..406916de25 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -1600,7 +1600,6 @@ int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa) capa->tx_compl.queue_type_sched = 1; capa->tx_compl.queue_type_plain = 1; capa->tx_compl.max_compl_id = UINT32_MAX - 1; - capa->free_ctrl.dont_free = 0; capa->config.pktout.bit.aging_ena = 1; capa->max_tx_aging_tmo_ns = MAX_TX_AGING_TMO_NS; diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c index 89aa91af76..3fa7960078 100644 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@ -1821,6 +1821,7 @@ static int dpdk_init_capability(pktio_entry_t *pktio_entry, capa->tx_compl.mode_all = 1; capa->tx_compl.mode_event = 1; capa->tx_compl.mode_poll = 1; + capa->free_ctrl.dont_free = 1; } /* Copy for fast path access */ @@ -2258,13 +2259,36 @@ static int dpdk_send(pktio_entry_t *pktio_entry, int index, } } } else { + int i; + int first = tx_pkts; + if (odp_unlikely(tx_pkts < mbufs)) { - for (uint16_t i = tx_pkts; i < mbufs; i++) + for (i = tx_pkts; i < mbufs; i++) rte_pktmbuf_free(tx_mbufs[i]); } - if (odp_likely(tx_pkts)) - odp_packet_free_multi(pkt_table, tx_pkts); + if (odp_unlikely(tx_pkts == 0)) + return 0; + + /* Find the first packet with (possible) don't free flag */ + for (i = 0; i < tx_pkts; i++) { + if (odp_packet_free_ctrl(pkt_table[i]) == ODP_PACKET_FREE_CTRL_DONT_FREE) { + first = i; + break; + } + } + + /* Free first N packets that don't have the flag */ + if (odp_likely(first > 0)) + odp_packet_free_multi(pkt_table, first); + + /* Free rest of the packets (according to the flag) */ + for (i = first; i < tx_pkts; i++) { + if (odp_packet_free_ctrl(pkt_table[i]) == ODP_PACKET_FREE_CTRL_DONT_FREE) + continue; + + odp_packet_free(pkt_table[i]); + } } return tx_pkts;