From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E4CE5A04BB; Tue, 6 Oct 2020 15:16:32 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 96BFB1B671; Tue, 6 Oct 2020 15:16:31 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 8C3871B28E for ; Tue, 6 Oct 2020 15:16:29 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from dekelp@nvidia.com) with SMTP; 6 Oct 2020 16:16:26 +0300 Received: from mtl-vdi-280.wap.labs.mlnx. (mtl-vdi-280.wap.labs.mlnx [10.228.134.250]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 096DGQJB010266; Tue, 6 Oct 2020 16:16:26 +0300 From: Dekel Peled To: viacheslavo@nvidia.com, shahafs@nvidia.com, matan@nvidia.com Cc: dev@dpdk.org Date: Tue, 6 Oct 2020 16:15:57 +0300 Message-Id: X-Mailer: git-send-email 1.7.1 Subject: [dpdk-dev] [PATCH] net/mlx5: support query of AGE action X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Recent patch [1] adds to ethdev the API for query of age action. This patch implements in MLX5 PMD the query of age action using this API. [1] https://mails.dpdk.org/archives/dev/2020-October/184319.html Signed-off-by: Dekel Peled --- drivers/net/mlx5/mlx5.h | 7 +++++ drivers/net/mlx5/mlx5_flow.c | 3 ++- drivers/net/mlx5/mlx5_flow_dv.c | 59 +++++++++++++++++++++++++++++++++++------ 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index bd91e16..98f2e5d 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -339,6 +339,7 @@ struct mlx5_age_param { uint16_t port_id; /**< Port id of the counter. */ uint32_t timeout:15; /**< Age timeout in unit of 0.1sec. */ uint32_t expire:16; /**< Expire time(0.1sec) in the future. */ + uint32_t last_hit_time; /**< Last hit time in seconds. */ void *context; /**< Flow counter age context. */ }; @@ -461,6 +462,12 @@ struct mlx5_flow_default_miss_resource { ((age_info)->flags & (1 << (BIT))) #define GET_PORT_AGE_INFO(priv) \ (&((priv)->sh->port[(priv)->dev_port - 1].age_info)) +/* Current time in seconds. */ +#define MLX5_CURR_TIME_SEC (rte_rdtsc() / rte_get_tsc_hz()) +#define MLX5_AGE_UNITS_PER_SEC 10 /* Aging is calculated in 0.1 sec units. */ +/* Current time in defined units. */ +#define MLX5_AGE_CURR_TIME \ + (rte_rdtsc() / (rte_get_tsc_hz() / MLX5_AGE_UNITS_PER_SEC)) /* Aging information for per port. */ struct mlx5_age_info { diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index ffa7646..0043fe4 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -6039,7 +6039,7 @@ struct mlx5_meter_domains_infos * struct mlx5_age_param *age_param; struct mlx5_counter_stats_raw *cur = pool->raw_hw; struct mlx5_counter_stats_raw *prev = pool->raw; - uint16_t curr = rte_rdtsc() / (rte_get_tsc_hz() / 10); + uint16_t curr = MLX5_AGE_CURR_TIME; uint32_t i; for (i = 0; i < MLX5_COUNTERS_PER_POOL; ++i) { @@ -6049,6 +6049,7 @@ struct mlx5_meter_domains_infos * continue; if (cur->data[i].hits != prev->data[i].hits) { age_param->expire = curr + age_param->timeout; + age_param->last_hit_time = MLX5_CURR_TIME_SEC; continue; } if ((uint16_t)(curr - age_param->expire) >= (UINT16_MAX / 2)) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 79fdf34..28389c6 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -8015,21 +8015,17 @@ struct field_modify_info modify_tcp[] = { if (!counter || age == NULL) return counter; age_param = flow_dv_counter_idx_get_age(dev, counter); - /* - * The counter age accuracy may have a bit delay. Have 3/4 - * second bias on the timeount in order to let it age in time. - */ age_param->context = age->context ? age->context : (void *)(uintptr_t)(dev_flow->flow_idx); /* * The counter age accuracy may have a bit delay. Have 3/4 - * second bias on the timeount in order to let it age in time. + * second bias on the timeout in order to let it age in time. */ age_param->timeout = age->timeout * 10 - MLX5_AGING_TIME_DELAY; - /* Set expire time in unit of 0.1 sec. */ age_param->port_id = dev->data->port_id; - age_param->expire = age_param->timeout + - rte_rdtsc() / (rte_get_tsc_hz() / 10); + /* Set expire time in unit of 0.1 sec. */ + age_param->expire = age_param->timeout + MLX5_AGE_CURR_TIME; + age_param->last_hit_time = MLX5_CURR_TIME_SEC; rte_atomic16_set(&age_param->state, AGE_CANDIDATE); return counter; } @@ -9529,6 +9525,50 @@ struct field_modify_info modify_tcp[] = { } /** + * Query a flow rule AGE action for aging information. + * + * @param[in] dev + * Pointer to Ethernet device. + * @param[in] flow + * Pointer to the sub flow. + * @param[out] data + * data retrieved by the query. + * @param[out] error + * Perform verbose error reporting if not NULL. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +flow_dv_query_age(struct rte_eth_dev *dev, struct rte_flow *flow, + void *data, struct rte_flow_error *error) +{ + struct rte_flow_query_age *resp = data; + + if (flow->counter) { + struct mlx5_age_param *age_param = + flow_dv_counter_idx_get_age(dev, flow->counter); + + if (!age_param || !age_param->timeout) + return rte_flow_error_set + (error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "cannot read age data"); + resp->aged = rte_atomic16_read(&age_param->state) == + AGE_TMOUT ? 1 : 0; + resp->last_hit_time_valid = !resp->aged; + if (resp->last_hit_time_valid) + resp->sec_since_last_hit = + MLX5_CURR_TIME_SEC - age_param->last_hit_time; + return 0; + } + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "age data not available"); +} + +/** * Query a flow. * * @see rte_flow_query() @@ -9550,6 +9590,9 @@ struct field_modify_info modify_tcp[] = { case RTE_FLOW_ACTION_TYPE_COUNT: ret = flow_dv_query_count(dev, flow, data, error); break; + case RTE_FLOW_ACTION_TYPE_AGE: + ret = flow_dv_query_age(dev, flow, data, error); + break; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, -- 1.8.3.1