From: Slava Ovsiienko <viacheslavo@mellanox.com>
To: "Jiawei(Jonny) Wang" <jiaweiw@mellanox.com>,
Matan Azrad <matan@mellanox.com>,
"Jiawei(Jonny) Wang" <jiaweiw@mellanox.com>
Cc: Raslan Darawsheh <rasland@mellanox.com>,
"dev@dpdk.org" <dev@dpdk.org>,
"stable@dpdk.org" <stable@dpdk.org>
Subject: Re: [dpdk-dev] [PATCH] net/mlx5: fix imissed counter overflow issue
Date: Mon, 30 Mar 2020 05:53:40 +0000 [thread overview]
Message-ID: <AM4PR05MB3265155B76A91C9ADC612CA4D2CB0@AM4PR05MB3265.eurprd05.prod.outlook.com> (raw)
In-Reply-To: <20200330030210.21595-1-jiaweiw@mellanox.com>
> -----Original Message-----
> From: Jiawei Wang <jiaweiw@mellanox.com>
> Sent: Monday, March 30, 2020 6:02
> To: Slava Ovsiienko <viacheslavo@mellanox.com>; Matan Azrad
> <matan@mellanox.com>; Jiawei(Jonny) Wang <jiaweiw@mellanox.com>
> Cc: Raslan Darawsheh <rasland@mellanox.com>; dev@dpdk.org;
> stable@dpdk.org
> Subject: [PATCH] net/mlx5: fix imissed counter overflow issue
>
> The Hw counters is defined as 32bit unsigned value and read from the sysfs.
> Firstly read the base value while application start, then fetch the new value
> while do query and minus the base value.
> If the new value is less than base value, will result in the a negative value and
> convert to the big value as unsigned 64bit.
>
> PMD add xstats field to store the last successfully read counter, use it if failed
> to read hw counter from sysfs.
> PMD also record the last output value to handle the wrap around case, if
> overflow happened, increase the wrap count by 1 and save into the higher
> 32bit, and update the new value into lower 32bit, finally return the 64bit
> counter value.
>
> Fixes: ce9494d76c4 ("net/mlx5: report imissed statistics")
> Cc: stable@dpdk.org
>
> Signed-off-by: Jiawei Wang <jiaweiw@mellanox.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
> drivers/net/mlx5/mlx5.h | 3 ++
> drivers/net/mlx5/mlx5_stats.c | 57 ++++++++++++++++++++++++++++++-----
> 2 files changed, 52 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> d7c519bae0..c01fae8c8e 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -112,12 +112,15 @@ struct mlx5_xstats_ctrl {
> /* Index in the device counters table. */
> uint16_t dev_table_idx[MLX5_MAX_XSTATS];
> uint64_t base[MLX5_MAX_XSTATS];
> + uint64_t xstats[MLX5_MAX_XSTATS];
> + uint64_t hw_stats[MLX5_MAX_XSTATS];
> struct mlx5_counter_ctrl info[MLX5_MAX_XSTATS]; };
>
> struct mlx5_stats_ctrl {
> /* Base for imissed counter. */
> uint64_t imissed_base;
> + uint64_t imissed;
> };
>
> /* Flow list . */
> diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c
> index 7603502967..5bc6fa6aa1 100644
> --- a/drivers/net/mlx5/mlx5_stats.c
> +++ b/drivers/net/mlx5/mlx5_stats.c
> @@ -139,7 +139,7 @@ static const struct mlx5_counter_ctrl
> mlx5_counters_init[] = {
>
> static const unsigned int xstats_n = RTE_DIM(mlx5_counters_init);
>
> -static inline void
> +static inline int
> mlx5_read_ib_stat(struct mlx5_priv *priv, const char *ctr_name, uint64_t
> *stat) {
> FILE *file;
> @@ -155,10 +155,11 @@ mlx5_read_ib_stat(struct mlx5_priv *priv, const
> char *ctr_name, uint64_t *stat)
>
> fclose(file);
> if (n == 1)
> - return;
> + return 0;
> }
> }
> *stat = 0;
> + return 1;
> }
>
> /**
> @@ -197,8 +198,14 @@ mlx5_read_dev_counters(struct rte_eth_dev *dev,
> uint64_t *stats)
> }
> for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) {
> if (xstats_ctrl->info[i].ib) {
> - mlx5_read_ib_stat(priv, xstats_ctrl->info[i].ctr_name,
> - &stats[i]);
> + ret = mlx5_read_ib_stat(priv,
> + xstats_ctrl->info[i].ctr_name,
> + &stats[i]);
> + /* return last xstats counter if fail to read. */
> + if (ret == 0)
> + xstats_ctrl->xstats[i] = stats[i];
> + else
> + stats[i] = xstats_ctrl->xstats[i];
> } else {
> stats[i] = (uint64_t)
> et_stats->data[xstats_ctrl->dev_table_idx[i]];
> @@ -304,6 +311,7 @@ mlx5_stats_init(struct rte_eth_dev *dev)
> unsigned int idx = xstats_ctrl->mlx5_stats_n++;
>
> xstats_ctrl->info[idx] = mlx5_counters_init[i];
> + xstats_ctrl->hw_stats[idx] = 0;
> }
> }
> MLX5_ASSERT(xstats_ctrl->mlx5_stats_n <= MLX5_MAX_XSTATS); @@
> -314,6 +322,7 @@ mlx5_stats_init(struct rte_eth_dev *dev)
> DRV_LOG(ERR, "port %u cannot read device counters: %s",
> dev->data->port_id, strerror(rte_errno));
> mlx5_read_ib_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
> + stats_ctrl->imissed = 0;
> free:
> rte_free(strings);
> }
> @@ -356,7 +365,23 @@ mlx5_xstats_get(struct rte_eth_dev *dev, struct
> rte_eth_xstat *stats,
> return ret;
> for (i = 0; i != mlx5_stats_n; ++i) {
> stats[i].id = i;
> - stats[i].value = (counters[i] - xstats_ctrl->base[i]);
> + if (xstats_ctrl->info[i].ib) {
> + uint64_t wrap_n;
> + uint64_t hw_stat = xstats_ctrl->hw_stats[i];
> +
> + stats[i].value = (counters[i] -
> + xstats_ctrl->base[i]) &
> + (uint64_t)UINT32_MAX;
> + wrap_n = hw_stat >> 32;
> + if (stats[i].value <
> + (hw_stat &
> (uint64_t)UINT32_MAX))
> + wrap_n++;
> + stats[i].value |= (wrap_n) << 32;
> + xstats_ctrl->hw_stats[i] = stats[i].value;
> + } else {
> + stats[i].value =
> + (counters[i] - xstats_ctrl->base[i]);
> + }
> }
> }
> return mlx5_stats_n;
> @@ -378,9 +403,12 @@ int
> mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) {
> struct mlx5_priv *priv = dev->data->dev_private;
> + struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
> struct rte_eth_stats tmp;
> unsigned int i;
> unsigned int idx;
> + uint64_t wrap_n;
> + int ret;
>
> memset(&tmp, 0, sizeof(tmp));
> /* Add software counters. */
> @@ -423,8 +451,18 @@ mlx5_stats_get(struct rte_eth_dev *dev, struct
> rte_eth_stats *stats) #endif
> tmp.oerrors += txq->stats.oerrors;
> }
> - mlx5_read_ib_stat(priv, "out_of_buffer", &tmp.imissed);
> - tmp.imissed -= priv->stats_ctrl.imissed_base;
> + ret = mlx5_read_ib_stat(priv, "out_of_buffer", &tmp.imissed);
> + if (ret == 0) {
> + tmp.imissed = (tmp.imissed - stats_ctrl->imissed_base) &
> + (uint64_t)UINT32_MAX;
> + wrap_n = stats_ctrl->imissed >> 32;
> + if (tmp.imissed < (stats_ctrl->imissed &
> (uint64_t)UINT32_MAX))
> + wrap_n++;
> + tmp.imissed |= (wrap_n) << 32;
> + stats_ctrl->imissed = tmp.imissed;
> + } else {
> + tmp.imissed = stats_ctrl->imissed;
> + }
> #ifndef MLX5_PMD_SOFT_COUNTERS
> /* FIXME: retrieve and add hardware counters. */ #endif @@ -461,6
> +499,7 @@ mlx5_stats_reset(struct rte_eth_dev *dev)
> sizeof(struct mlx5_txq_stats));
> }
> mlx5_read_ib_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
> + stats_ctrl->imissed = 0;
> #ifndef MLX5_PMD_SOFT_COUNTERS
> /* FIXME: reset hardware counters. */
> #endif
> @@ -503,8 +542,10 @@ mlx5_xstats_reset(struct rte_eth_dev *dev)
> dev->data->port_id, strerror(rte_errno));
> return ret;
> }
> - for (i = 0; i != n; ++i)
> + for (i = 0; i != n; ++i) {
> xstats_ctrl->base[i] = counters[i];
> + xstats_ctrl->hw_stats[i] = 0;
> + }
>
> return 0;
> }
> --
> 2.21.0
next prev parent reply other threads:[~2020-03-30 5:53 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-30 3:02 Jiawei Wang
2020-03-30 5:53 ` Slava Ovsiienko [this message]
2020-03-31 14:33 ` Raslan Darawsheh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=AM4PR05MB3265155B76A91C9ADC612CA4D2CB0@AM4PR05MB3265.eurprd05.prod.outlook.com \
--to=viacheslavo@mellanox.com \
--cc=dev@dpdk.org \
--cc=jiaweiw@mellanox.com \
--cc=matan@mellanox.com \
--cc=rasland@mellanox.com \
--cc=stable@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).