Add support to the ixgbe driver for the API rte_eth_tx_done_cleanup
 to force free consumed buffers on Tx ring.

Signed-off-by: Di ChenxuX <chenxux...@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c   | 39 ++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_rxtx.h   |  2 ++
 3 files changed, 43 insertions(+)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 7eb3d0567..255af2290 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -591,6 +591,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
        .udp_tunnel_port_add  = ixgbe_dev_udp_tunnel_port_add,
        .udp_tunnel_port_del  = ixgbe_dev_udp_tunnel_port_del,
        .tm_ops_get           = ixgbe_tm_ops_get,
+       .tx_done_cleanup      = ixgbe_tx_done_cleanup,
 };
 
 /*
@@ -639,6 +640,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
        .reta_query           = ixgbe_dev_rss_reta_query,
        .rss_hash_update      = ixgbe_dev_rss_hash_update,
        .rss_hash_conf_get    = ixgbe_dev_rss_hash_conf_get,
+       .tx_done_cleanup      = ixgbe_tx_done_cleanup,
 };
 
 /* store statistics names and its offset in stats structure */
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index edcfa60ce..7bdb244b0 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2306,6 +2306,45 @@ ixgbe_tx_queue_release_mbufs(struct ixgbe_tx_queue *txq)
        }
 }
 
+int ixgbe_tx_done_cleanup(void *txq, uint32_t free_cnt)
+{
+       struct ixgbe_tx_queue *q = (struct ixgbe_tx_queue *)txq;
+       struct ixgbe_tx_entry *sw_ring;
+       uint16_t tx_id;    /* Current segment being processed. */
+       uint16_t tx_cleaned;
+
+       int count = 0;
+
+       if (q == NULL)
+               return -ENODEV;
+
+       sw_ring = q->sw_ring;
+       tx_cleaned = q->last_desc_cleaned;
+       tx_id = sw_ring[q->last_desc_cleaned].next_id;
+       if (!(q->tx_ring[tx_id].wb.status &
+                       IXGBE_TXD_STAT_DD))
+               return 0;
+
+       do {
+               if (sw_ring[tx_id].mbuf == NULL)
+                       break;
+
+               rte_pktmbuf_free_seg(sw_ring[tx_id].mbuf);
+               sw_ring[tx_id].mbuf = NULL;
+               sw_ring[tx_id].last_id = tx_id;
+
+               /* Move to next segemnt. */
+               tx_cleaned = tx_id;
+               tx_id = sw_ring[tx_id].next_id;
+               count++;
+       } while (count != (int)free_cnt);
+
+       q->nb_tx_free += (uint16_t)count;
+       q->last_desc_cleaned = tx_cleaned;
+
+       return count;
+}
+
 static void __attribute__((cold))
 ixgbe_tx_free_swring(struct ixgbe_tx_queue *txq)
 {
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h b/drivers/net/ixgbe/ixgbe_rxtx.h
index 505d344b9..2c3770af6 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.h
+++ b/drivers/net/ixgbe/ixgbe_rxtx.h
@@ -285,6 +285,8 @@ int ixgbe_rx_vec_dev_conf_condition_check(struct 
rte_eth_dev *dev);
 int ixgbe_rxq_vec_setup(struct ixgbe_rx_queue *rxq);
 void ixgbe_rx_queue_release_mbufs_vec(struct ixgbe_rx_queue *rxq);
 
+int ixgbe_tx_done_cleanup(void *txq, uint32_t free_cnt);
+
 extern const uint32_t ptype_table[IXGBE_PACKET_TYPE_MAX];
 extern const uint32_t ptype_table_tn[IXGBE_PACKET_TYPE_TN_MAX];
 
-- 
2.17.1

Reply via email to