[v3,2/3] net/mlx5: configure Tx queue with send on time offload
Checks
Commit Message
The wait on time configuration flag is copied to the Tx queue
structure due to performance considerations. Timestamp
mask is preparted and stored in queue structure as well.
Signed-off-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
drivers/net/mlx5/linux/mlx5_verbs.c | 4 ++++
drivers/net/mlx5/mlx5.h | 3 +++
drivers/net/mlx5/mlx5_devx.c | 2 ++
drivers/net/mlx5/mlx5_tx.h | 3 +++
drivers/net/mlx5/mlx5_txq.c | 18 ++++++++++++++++--
5 files changed, 28 insertions(+), 2 deletions(-)
@@ -1035,6 +1035,10 @@ mlx5_txq_ibv_obj_new(struct rte_eth_dev *dev, uint16_t idx)
txq_data->wqe_pi = 0;
txq_data->wqe_comp = 0;
txq_data->wqe_thres = txq_data->wqe_s / MLX5_TX_COMP_THRESH_INLINE_DIV;
+ txq_data->wait_on_time = !!(!priv->sh->config.tx_pp &&
+ priv->sh->cdev->config.hca_attr.wait_on_time &&
+ txq_data->offloads &
+ RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP);
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
/*
* If using DevX need to query and store TIS transport domain value.
@@ -337,6 +337,9 @@ struct mlx5_lb_ctx {
#define MLX5_CNT_ARRAY_IDX(pool, cnt) \
((int)(((uint8_t *)(cnt) - (uint8_t *)((pool) + 1)) / \
MLX5_CNT_LEN(pool)))
+#define MLX5_TS_MASK_SECS 8ull
+/* timestamp wrapping in seconds, must be power of 2. */
+
/*
* The pool index and offset of counter in the pool array makes up the
* counter index. In case the counter is from pool 0 and offset 0, it
@@ -1328,6 +1328,8 @@ mlx5_txq_devx_obj_new(struct rte_eth_dev *dev, uint16_t idx)
txq_data->qp_num_8s = txq_obj->sq_obj.sq->id << 8;
txq_data->db_heu = sh->cdev->config.dbnc == MLX5_SQ_DB_HEURISTIC;
txq_data->db_nc = sh->tx_uar.dbnc;
+ txq_data->wait_on_time = !!(!sh->config.tx_pp &&
+ sh->cdev->config.hca_attr.wait_on_time);
/* Change Send Queue state to Ready-to-Send. */
ret = mlx5_txq_devx_modify(txq_obj, MLX5_TXQ_MOD_RST2RDY, 0);
if (ret) {
@@ -138,6 +138,8 @@ struct mlx5_txq_data {
uint16_t vlan_en:1; /* VLAN insertion in WQE is supported. */
uint16_t db_nc:1; /* Doorbell mapped to non-cached region. */
uint16_t db_heu:1; /* Doorbell heuristic write barrier. */
+ uint16_t rt_timestamp:1; /* Realtime timestamp format. */
+ uint16_t wait_on_time:1; /* WQE with timestamp is supported. */
uint16_t fast_free:1; /* mbuf fast free on Tx is enabled. */
uint16_t inlen_send; /* Ordinary send data inline size. */
uint16_t inlen_empw; /* eMPW max packet size to inline. */
@@ -157,6 +159,7 @@ struct mlx5_txq_data {
volatile uint32_t *cq_db; /* Completion queue doorbell. */
uint16_t port_id; /* Port ID of device. */
uint16_t idx; /* Queue index. */
+ uint64_t rt_timemask; /* Scheduling timestamp mask. */
uint64_t ts_mask; /* Timestamp flag dynamic mask. */
int32_t ts_offset; /* Timestamp field dynamic offset. */
struct mlx5_dev_ctx_shared *sh; /* Shared context. */
@@ -109,7 +109,8 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
RTE_ETH_TX_OFFLOAD_TCP_CKSUM);
if (dev_cap->tso)
offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
- if (priv->sh->config.tx_pp)
+ if (priv->sh->config.tx_pp ||
+ priv->sh->cdev->config.hca_attr.wait_on_time)
offloads |= RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP;
if (dev_cap->swp) {
if (dev_cap->swp & MLX5_SW_PARSING_CSUM_CAP)
@@ -1288,12 +1289,21 @@ mlx5_txq_dynf_timestamp_set(struct rte_eth_dev *dev)
int off, nbit;
unsigned int i;
uint64_t mask = 0;
+ uint64_t ts_mask;
+ if (sh->dev_cap.rt_timestamp ||
+ !sh->cdev->config.hca_attr.dev_freq_khz)
+ ts_mask = MLX5_TS_MASK_SECS << 32;
+ else
+ ts_mask = rte_align64pow2(MLX5_TS_MASK_SECS * 1000ull *
+ sh->cdev->config.hca_attr.dev_freq_khz);
+ ts_mask = rte_cpu_to_be_64(ts_mask - 1ull);
nbit = rte_mbuf_dynflag_lookup
(RTE_MBUF_DYNFLAG_TX_TIMESTAMP_NAME, NULL);
off = rte_mbuf_dynfield_lookup
(RTE_MBUF_DYNFIELD_TIMESTAMP_NAME, NULL);
- if (nbit >= 0 && off >= 0 && sh->txpp.refcnt)
+ if (nbit >= 0 && off >= 0 &&
+ (sh->txpp.refcnt || priv->sh->cdev->config.hca_attr.wait_on_time))
mask = 1ULL << nbit;
for (i = 0; i != priv->txqs_n; ++i) {
data = (*priv->txqs)[i];
@@ -1302,5 +1312,9 @@ mlx5_txq_dynf_timestamp_set(struct rte_eth_dev *dev)
data->sh = sh;
data->ts_mask = mask;
data->ts_offset = off;
+ data->rt_timestamp = sh->dev_cap.rt_timestamp;
+ data->rt_timemask = (data->offloads &
+ RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP) ?
+ ts_mask : 0;
}
}