From 085ff447f01c52c3595ea3196511b97bf54866f0 Mon Sep 17 00:00:00 2001 From: Viacheslav Ovsiienko Date: Thu, 16 Jul 2020 08:23:14 +0000 Subject: [PATCH] net/mlx5: convert timestamp to completion index The application provides timestamps in Tx mbuf as clocks, the hardware performs scheduling on Clock Queue completion index match. This patch introduces the timestamp-to-completion-index inline routine. Signed-off-by: Viacheslav Ovsiienko Acked-by: Matan Azrad --- drivers/net/mlx5/mlx5.h | 2 ++ drivers/net/mlx5/mlx5_rxtx.h | 55 ++++++++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_txpp.c | 5 ++++ 3 files changed, 62 insertions(+) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index bb2c096b4f..3304f0d246 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -585,6 +585,8 @@ struct mlx5_dev_txpp { rte_atomic32_t err_miss_int; /* Missed service interrupt. */ rte_atomic32_t err_rearm_queue; /* Rearm Queue errors. */ rte_atomic32_t err_clock_queue; /* Clock Queue errors. */ + rte_atomic32_t err_ts_past; /* Timestamp in the past. */ + rte_atomic32_t err_ts_future; /* Timestamp in the distant future. */ }; /* diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h index 974a84741e..d082cd70cf 100644 --- a/drivers/net/mlx5/mlx5_rxtx.h +++ b/drivers/net/mlx5/mlx5_rxtx.h @@ -719,4 +719,59 @@ mlx5_txpp_convert_rx_ts(struct mlx5_dev_ctx_shared *sh, uint64_t ts) return (ts & UINT32_MAX) + (ts >> 32) * NS_PER_S; } +/** + * Convert timestamp from mbuf format to linear counter + * of Clock Queue completions (24 bits) + * + * @param sh + * Pointer to the device shared context to fetch Tx + * packet pacing timestamp and parameters. + * @param ts + * Timestamp from mbuf to convert. + * @return + * positive or zero value - completion ID to wait + * negative value - conversion error + */ +static __rte_always_inline int32_t +mlx5_txpp_convert_tx_ts(struct mlx5_dev_ctx_shared *sh, uint64_t mts) +{ + uint64_t ts, ci; + uint32_t tick; + + do { + /* + * Read atomically two uint64_t fields and compare lsb bits. + * It there is no match - the timestamp was updated in + * the service thread, data should be re-read. + */ + rte_compiler_barrier(); + ci = rte_atomic64_read(&sh->txpp.ts.ci_ts); + ts = rte_atomic64_read(&sh->txpp.ts.ts); + rte_compiler_barrier(); + if (!((ts ^ ci) << (64 - MLX5_CQ_INDEX_WIDTH))) + break; + } while (true); + /* Perform the skew correction, positive value to send earlier. */ + mts -= sh->txpp.skew; + mts -= ts; + if (unlikely(mts >= UINT64_MAX / 2)) { + /* We have negative integer, mts is in the past. */ + rte_atomic32_inc(&sh->txpp.err_ts_past); + return -1; + } + tick = sh->txpp.tick; + MLX5_ASSERT(tick); + /* Convert delta to completions, round up. */ + mts = (mts + tick - 1) / tick; + if (unlikely(mts >= (1 << MLX5_CQ_INDEX_WIDTH) / 2 - 1)) { + /* We have mts is too distant future. */ + rte_atomic32_inc(&sh->txpp.err_ts_future); + return -1; + } + mts <<= 64 - MLX5_CQ_INDEX_WIDTH; + ci += mts; + ci >>= 64 - MLX5_CQ_INDEX_WIDTH; + return ci; +} + #endif /* RTE_PMD_MLX5_RXTX_H_ */ diff --git a/drivers/net/mlx5/mlx5_txpp.c b/drivers/net/mlx5/mlx5_txpp.c index 8f7284b935..95b91278a2 100644 --- a/drivers/net/mlx5/mlx5_txpp.c +++ b/drivers/net/mlx5/mlx5_txpp.c @@ -860,6 +860,11 @@ mlx5_txpp_start_service(struct mlx5_dev_ctx_shared *sh) int flags; int ret; + rte_atomic32_set(&sh->txpp.err_miss_int, 0); + rte_atomic32_set(&sh->txpp.err_rearm_queue, 0); + rte_atomic32_set(&sh->txpp.err_clock_queue, 0); + rte_atomic32_set(&sh->txpp.err_ts_past, 0); + rte_atomic32_set(&sh->txpp.err_ts_future, 0); /* Attach interrupt handler to process Rearm Queue completions. */ flags = fcntl(sh->txpp.echan->fd, F_GETFL); ret = fcntl(sh->txpp.echan->fd, F_SETFL, flags | O_NONBLOCK); -- 2.20.1