net/hns3: implement Tx mbuf free on demand
authorChengwen Feng <fengchengwen@huawei.com>
Thu, 4 Mar 2021 07:44:43 +0000 (15:44 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 4 Mar 2021 14:07:13 +0000 (15:07 +0100)
This patch add support tx_done_cleanup ops, which could support for
the API rte_eth_tx_done_cleanup to free consumed mbufs on Tx ring.

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Signed-off-by: Lijun Ou <oulijun@huawei.com>
doc/guides/nics/features/hns3.ini
doc/guides/nics/features/hns3_vf.ini
doc/guides/rel_notes/release_21_05.rst
drivers/net/hns3/hns3_ethdev.c
drivers/net/hns3/hns3_ethdev_vf.c
drivers/net/hns3/hns3_rxtx.c
drivers/net/hns3/hns3_rxtx.h

index a1f5f9e..3aeea8e 100644 (file)
@@ -10,6 +10,7 @@ Queue start/stop     = Y
 Runtime Rx queue setup = Y
 Runtime Tx queue setup = Y
 Burst mode info      = Y
+Free Tx mbuf on demand = Y
 MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
index 99a0bf0..c796cd5 100644 (file)
@@ -10,6 +10,7 @@ Queue start/stop     = Y
 Runtime Rx queue setup = Y
 Runtime Tx queue setup = Y
 Burst mode info      = Y
+Free Tx mbuf on demand = Y
 MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
index b82ea82..15e016e 100644 (file)
@@ -58,6 +58,7 @@ New Features
 * **Updated Hisilicon hns3 driver.**
 
   * Added support for module EEPROM dumping.
+  * Added support for freeing Tx mbuf on demand.
 
 * **Updated Wangxun txgbe driver.**
 
index e02a7ec..91d720a 100644 (file)
@@ -6388,6 +6388,7 @@ static const struct eth_dev_ops hns3_eth_dev_ops = {
        .fec_get                = hns3_fec_get,
        .fec_set                = hns3_fec_set,
        .tm_ops_get             = hns3_tm_ops_get,
+       .tx_done_cleanup        = hns3_tx_done_cleanup,
 };
 
 static const struct hns3_reset_ops hns3_reset_ops = {
index 3f9f328..1b8c029 100644 (file)
@@ -2763,6 +2763,7 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = {
        .vlan_offload_set   = hns3vf_vlan_offload_set,
        .get_reg            = hns3_get_regs,
        .dev_supported_ptypes_get = hns3_dev_supported_ptypes_get,
+       .tx_done_cleanup    = hns3_tx_done_cleanup,
 };
 
 static const struct hns3_reset_ops hns3vf_reset_ops = {
index 222cf8a..5e79177 100644 (file)
@@ -3913,6 +3913,65 @@ hns3_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
        return 0;
 }
 
+static int
+hns3_tx_done_cleanup_full(struct hns3_tx_queue *txq, uint32_t free_cnt)
+{
+       uint16_t next_to_clean = txq->next_to_clean;
+       uint16_t next_to_use   = txq->next_to_use;
+       uint16_t tx_bd_ready   = txq->tx_bd_ready;
+       struct hns3_entry *tx_pkt = &txq->sw_ring[next_to_clean];
+       struct hns3_desc *desc = &txq->tx_ring[next_to_clean];
+       uint32_t idx;
+
+       if (free_cnt == 0 || free_cnt > txq->nb_tx_desc)
+               free_cnt = txq->nb_tx_desc;
+
+       for (idx = 0; idx < free_cnt; idx++) {
+               if (next_to_clean == next_to_use)
+                       break;
+
+               if (desc->tx.tp_fe_sc_vld_ra_ri &
+                   rte_cpu_to_le_16(BIT(HNS3_TXD_VLD_B)))
+                       break;
+
+               if (tx_pkt->mbuf != NULL) {
+                       rte_pktmbuf_free_seg(tx_pkt->mbuf);
+                       tx_pkt->mbuf = NULL;
+               }
+
+               next_to_clean++;
+               tx_bd_ready++;
+               tx_pkt++;
+               desc++;
+               if (next_to_clean == txq->nb_tx_desc) {
+                       tx_pkt = txq->sw_ring;
+                       desc = txq->tx_ring;
+                       next_to_clean = 0;
+               }
+       }
+
+       if (idx > 0) {
+               txq->next_to_clean = next_to_clean;
+               txq->tx_bd_ready = tx_bd_ready;
+       }
+
+       return (int)idx;
+}
+
+int
+hns3_tx_done_cleanup(void *txq, uint32_t free_cnt)
+{
+       struct hns3_tx_queue *q = (struct hns3_tx_queue *)txq;
+       struct rte_eth_dev *dev = &rte_eth_devices[q->port_id];
+
+       if (dev->tx_pkt_burst == hns3_xmit_pkts)
+               return hns3_tx_done_cleanup_full(q, free_cnt);
+       else if (dev->tx_pkt_burst == hns3_dummy_rxtx_burst)
+               return 0;
+       else
+               return -ENOTSUP;
+}
+
 uint32_t
 hns3_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
 {
index 8f5ae5c..7118bd4 100644 (file)
@@ -706,5 +706,6 @@ int hns3_start_all_txqs(struct rte_eth_dev *dev);
 int hns3_start_all_rxqs(struct rte_eth_dev *dev);
 void hns3_stop_all_txqs(struct rte_eth_dev *dev);
 void hns3_restore_tqp_enable_state(struct hns3_hw *hw);
+int hns3_tx_done_cleanup(void *txq, uint32_t free_cnt);
 
 #endif /* _HNS3_RXTX_H_ */