From: Viacheslav Ovsiienko Date: Thu, 24 Feb 2022 10:55:00 +0000 (+0200) Subject: net/mlx5: configure Tx queue with send on time offload X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=2f5122dfc41f4493a33d8ccd65ba89dd26624b6b;p=dpdk.git net/mlx5: configure Tx queue with send on time offload The wait on time configuration flag is copied to the Tx queue structure due to performance considerations. Timestamp mask is prepared and stored in queue structure as well. Signed-off-by: Viacheslav Ovsiienko --- diff --git a/drivers/net/mlx5/linux/mlx5_verbs.c b/drivers/net/mlx5/linux/mlx5_verbs.c index dfbc5a1e08..b6ba21c216 100644 --- a/drivers/net/mlx5/linux/mlx5_verbs.c +++ b/drivers/net/mlx5/linux/mlx5_verbs.c @@ -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. diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index e7eaacc76f..0f465d0e9e 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -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 diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c index f18b18b1a2..a9b8c2a1b7 100644 --- a/drivers/net/mlx5/mlx5_devx.c +++ b/drivers/net/mlx5/mlx5_devx.c @@ -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) { diff --git a/drivers/net/mlx5/mlx5_tx.h b/drivers/net/mlx5/mlx5_tx.h index c4b8271f6f..b50deb8b67 100644 --- a/drivers/net/mlx5/mlx5_tx.h +++ b/drivers/net/mlx5/mlx5_tx.h @@ -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. */ diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c index edbaa50692..f128c3d1a5 100644 --- a/drivers/net/mlx5/mlx5_txq.c +++ b/drivers/net/mlx5/mlx5_txq.c @@ -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; } }