From: Jun Yang <jun.yang at nxp.com>
When Tx confirmation is enabled, transmitted mbufs are only released
back to their pool once the corresponding Tx-confirm frames are
dequeued. On a port that stops transmitting, these confirmations are
never drained and the mbufs stay held. Applications had no way to
force this cleanup.
Add rte_pmd_dpaa2_clean_tx_conf() so an application can drain the
Tx-confirm queue associated with a given port and Tx queue on demand.
To support this, dpaa2_dev_tx_conf() is changed to take the
tx-confirm queue directly instead of the Tx queue, and its callers are
updated to pass tx_conf_queue explicitly.
Signed-off-by: Jun Yang <jun.yang at nxp.com>
---
drivers/net/dpaa2/dpaa2_ethdev.c | 22 ++++++++++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 2 +-
drivers/net/dpaa2/dpaa2_ptp.c | 2 +-
drivers/net/dpaa2/dpaa2_rxtx.c | 22 ++++++++++------------
drivers/net/dpaa2/rte_pmd_dpaa2.h | 4 ++++
5 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index d8a183453b..fe43779b10 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -1240,6 +1240,28 @@ dpaa2_dev_dcb_info(struct rte_eth_dev *dev,
return 0;
}
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_dpaa2_clean_tx_conf, 26.11)
+uint16_t
+rte_pmd_dpaa2_clean_tx_conf(uint32_t eth_id, uint16_t txq_id)
+{
+ struct rte_eth_dev *dev;
+ struct dpaa2_queue *txq;
+
+ if (unlikely(!rte_pmd_dpaa2_dev_is_dpaa2(eth_id))) {
+ DPAA2_PMD_WARN("eth%d is NOT dpaa2 device", eth_id);
+ return 0;
+ }
+
+ dev = &rte_eth_devices[eth_id];
+ txq = dev->data->tx_queues[txq_id];
+
+ if (txq->tx_conf_queue)
+ return dpaa2_dev_tx_conf(txq->tx_conf_queue, true);
+
+ DPAA2_PMD_WARN("TX confirm not enabled on %s", dev->data->name);
+ return 0;
+}
+
RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_dpaa2_dev_configure_default_action, 26.11)
int
rte_pmd_dpaa2_dev_configure_default_action(uint16_t port_id,
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h
index d1ddea7c64..2f3f5bae2a 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.h
+++ b/drivers/net/dpaa2/dpaa2_ethdev.h
@@ -981,7 +981,7 @@ uint16_t dpaa2_dev_tx_multi_txq_ordered(struct dpaa2_queue **dpaa2_q,
void dpaa2_dev_free_eqresp_buf(uint16_t eqresp_ci, struct dpaa2_queue *dpaa2_q);
void dpaa2_flow_clean(struct rte_eth_dev *dev, uint8_t tc_id,
enum dpaa2_flow_dist_type type);
-uint16_t dpaa2_dev_tx_conf(void *txq, int drain);
+uint16_t dpaa2_dev_tx_conf(struct dpaa2_queue *tx_conf_q, int drain);
void
dpaa2_dev_tx_ptp_one_step_runtime(struct rte_eth_dev *dev,
diff --git a/drivers/net/dpaa2/dpaa2_ptp.c b/drivers/net/dpaa2/dpaa2_ptp.c
index 00f6d04c92..90de203f93 100644
--- a/drivers/net/dpaa2/dpaa2_ptp.c
+++ b/drivers/net/dpaa2/dpaa2_ptp.c
@@ -218,7 +218,7 @@ int dpaa2_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
rte_memory_order_relaxed);
while (txq && rte_atomic_load_explicit(&txq->ts_to_cnfd,
rte_memory_order_relaxed) > 0) {
- dpaa2_dev_tx_conf(txq, false);
+ dpaa2_dev_tx_conf(txq->tx_conf_queue, false);
txq = rte_atomic_load_explicit(&priv->next_txq_to_cnf,
rte_memory_order_relaxed);
}
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index efaa862623..4f712ec9f7 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -1417,14 +1417,14 @@ dpaa2_dev_is_mbuf_from_spec_pool(struct rte_mempool *mp,
}
static __rte_always_inline void __rte_hot
-dpaa2_dev_tx_cnf_fd_to_mbuf(struct dpaa2_queue *dpaa2_q,
+dpaa2_dev_tx_cnf_fd_to_mbuf(struct dpaa2_queue *tx_conf_q,
const struct qbman_fd *fd, const struct qbman_fd **fds,
struct rte_mbuf **mbuf)
{
void *v_addr;
struct dpaa2_annot_hdr *annotation;
- struct dpaa2_queue *dpaa2_txq = dpaa2_q->tx_queue;
- struct dpaa2_dev_priv *priv = dpaa2_q->eth_data->dev_private;
+ struct dpaa2_queue *dpaa2_txq = tx_conf_q->tx_queue;
+ struct dpaa2_dev_priv *priv = tx_conf_q->eth_data->dev_private;
RTE_SET_USED(fds);
@@ -1436,17 +1436,15 @@ dpaa2_dev_tx_cnf_fd_to_mbuf(struct dpaa2_queue *dpaa2_q,
annotation->word2, rte_memory_order_relaxed);
rte_atomic_store_explicit(&priv->next_txq_to_cnf,
dpaa2_txq, rte_memory_order_relaxed);
- rte_atomic_fetch_sub_explicit(&dpaa2_q->ts_to_cnfd, 1,
+ rte_atomic_fetch_sub_explicit(&tx_conf_q->ts_to_cnfd, 1,
rte_memory_order_relaxed);
dpaa2_timestamp_debug(priv, __func__, priv->tx_timestamp);
}
}
-uint16_t dpaa2_dev_tx_conf(void *txq, int drain)
+uint16_t dpaa2_dev_tx_conf(struct dpaa2_queue *tx_conf_q, int drain)
{
/* Function receive frames for a given device and VQ*/
- struct dpaa2_queue *dpaa2_txq = txq;
- struct dpaa2_queue *dpaa2_q = dpaa2_txq->tx_conf_queue;
uint16_t num_rx, total = 0, idx;
int bulk_free;
struct rte_mbuf *mbufs[dpaa2_dqrr_size];
@@ -1455,7 +1453,7 @@ uint16_t dpaa2_dev_tx_conf(void *txq, int drain)
dpaa2_dev_prefetch_next_psr_dummy : dpaa2_dev_prefetch_next_psr;
dq_again:
- num_rx = dpaa2_dev_prefetch_rx_common(dpaa2_q, NULL, mbufs, dpaa2_dqrr_size,
+ num_rx = dpaa2_dev_prefetch_rx_common(tx_conf_q, NULL, mbufs, dpaa2_dqrr_size,
dpaa2_dev_tx_cnf_fd_to_mbuf, dq_prefetch);
bulk_free = true;
mp = NULL;
@@ -1548,7 +1546,7 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
hw_mp = priv->bp_list->mp;
if (dpaa2_q->tx_conf_queue)
- dpaa2_dev_tx_conf(dpaa2_q, false);
+ dpaa2_dev_tx_conf(dpaa2_q->tx_conf_queue, false);
/*Prepare enqueue descriptor*/
qbman_eq_desc_clear(&eqdesc);
@@ -1874,10 +1872,10 @@ dpaa2_dev_tx_multi_txq_ordered(struct dpaa2_queue **dpaa2_q,
}
}
for (i = 0; i < loop; i++) {
- if (unlikely(dpaa2_q[i]->tx_conf_queue)) {
- dpaa2_dev_tx_conf(dpaa2_q[i], false);
+ cnf_q = dpaa2_q[i]->tx_conf_queue;
+ if (unlikely(cnf_q)) {
+ dpaa2_dev_tx_conf(cnf_q, false);
if (tstamp[i]) {
- cnf_q = dpaa2_q[i]->tx_conf_queue;
rte_atomic_fetch_add_explicit(&cnf_q->ts_to_cnfd,
1, rte_memory_order_relaxed);
}
diff --git a/drivers/net/dpaa2/rte_pmd_dpaa2.h b/drivers/net/dpaa2/rte_pmd_dpaa2.h
index 5a61a952bf..0e447cb58d 100644
--- a/drivers/net/dpaa2/rte_pmd_dpaa2.h
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2.h
@@ -203,6 +203,10 @@ int
rte_pmd_dpaa2_dev_configure_default_action(uint16_t port_id,
struct rte_pmd_dpaa2_default_action_conf *def_act_conf);
+__rte_experimental
+uint16_t
+rte_pmd_dpaa2_clean_tx_conf(uint32_t eth_id, uint16_t txq_id);
+
#define RTE_DPAA2_EVENT_PORT_CFG_ATOMIC RTE_BIT32(31)
/** RTE_DPAA2_MIX_GROUP_FLOW has same behavio as RTE_DPAA2_FLAT_GROUP_FLOW*/
--
2.43.0