LCOV - code coverage report
Current view: top level - drivers/net/mlx5 - mlx5_stats.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 126 0.0 %
Date: 2025-02-01 18:54:23 Functions: 0 5 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 70 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2015 6WIND S.A.
       3                 :            :  * Copyright 2015 Mellanox Technologies, Ltd
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <inttypes.h>
       7                 :            : #include <stdint.h>
       8                 :            : #include <stdio.h>
       9                 :            : #include <unistd.h>
      10                 :            : 
      11                 :            : #include <ethdev_driver.h>
      12                 :            : #include <rte_common.h>
      13                 :            : #include <rte_malloc.h>
      14                 :            : 
      15                 :            : #include <mlx5_common.h>
      16                 :            : 
      17                 :            : #include "mlx5_defs.h"
      18                 :            : #include "mlx5.h"
      19                 :            : #include "mlx5_rx.h"
      20                 :            : #include "mlx5_tx.h"
      21                 :            : #include "mlx5_malloc.h"
      22                 :            : 
      23                 :            : /**
      24                 :            :  * DPDK callback to get extended device statistics.
      25                 :            :  *
      26                 :            :  * @param dev
      27                 :            :  *   Pointer to Ethernet device.
      28                 :            :  * @param[out] stats
      29                 :            :  *   Pointer to rte extended stats table.
      30                 :            :  * @param n
      31                 :            :  *   The size of the stats table.
      32                 :            :  *
      33                 :            :  * @return
      34                 :            :  *   Number of extended stats on success and stats is filled,
      35                 :            :  *   negative on error and rte_errno is set.
      36                 :            :  */
      37                 :            : int
      38                 :          0 : mlx5_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
      39                 :            :                 unsigned int n)
      40                 :            : {
      41                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
      42                 :            :         uint64_t counters[MLX5_MAX_XSTATS];
      43                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
      44                 :            :         unsigned int i;
      45                 :          0 :         uint16_t stats_n = 0;
      46                 :          0 :         uint16_t stats_n_2nd = 0;
      47                 :          0 :         uint16_t mlx5_stats_n = xstats_ctrl->mlx5_stats_n;
      48   [ #  #  #  # ]:          0 :         bool bond_master = (priv->master && priv->pf_bond >= 0);
      49                 :            : 
      50   [ #  #  #  # ]:          0 :         if (n >= mlx5_stats_n && stats) {
      51                 :            :                 int ret;
      52                 :            : 
      53                 :          0 :                 ret = mlx5_os_get_stats_n(dev, bond_master, &stats_n, &stats_n_2nd);
      54         [ #  # ]:          0 :                 if (ret < 0)
      55                 :            :                         return ret;
      56                 :            :                 /*
      57                 :            :                  * The number of statistics fetched via "ETH_SS_STATS" may vary because
      58                 :            :                  * of the port configuration each time. This is also true between 2
      59                 :            :                  * ports. There might be a case that the numbers are the same even if
      60                 :            :                  * configurations are different.
      61                 :            :                  * It is not recommended to change the configuration without using
      62                 :            :                  * RTE API. The port(traffic) restart may trigger another initialization
      63                 :            :                  * to make sure the map are correct.
      64                 :            :                  */
      65   [ #  #  #  # ]:          0 :                 if (xstats_ctrl->stats_n != stats_n ||
      66         [ #  # ]:          0 :                     (bond_master && xstats_ctrl->stats_n_2nd != stats_n_2nd))
      67                 :          0 :                         mlx5_os_stats_init(dev);
      68                 :          0 :                 ret = mlx5_os_read_dev_counters(dev, bond_master, counters);
      69         [ #  # ]:          0 :                 if (ret < 0)
      70                 :            :                         return ret;
      71         [ #  # ]:          0 :                 for (i = 0; i != mlx5_stats_n; i++) {
      72                 :          0 :                         stats[i].id = i;
      73         [ #  # ]:          0 :                         if (xstats_ctrl->info[i].dev) {
      74                 :            :                                 uint64_t wrap_n;
      75                 :          0 :                                 uint64_t hw_stat = xstats_ctrl->hw_stats[i];
      76                 :            : 
      77                 :          0 :                                 stats[i].value = (counters[i] -
      78                 :          0 :                                                   xstats_ctrl->base[i]) &
      79                 :            :                                                   (uint64_t)UINT32_MAX;
      80                 :          0 :                                 wrap_n = hw_stat >> 32;
      81                 :          0 :                                 if (stats[i].value <
      82         [ #  # ]:          0 :                                             (hw_stat & (uint64_t)UINT32_MAX))
      83                 :          0 :                                         wrap_n++;
      84                 :          0 :                                 stats[i].value |= (wrap_n) << 32;
      85                 :          0 :                                 xstats_ctrl->hw_stats[i] = stats[i].value;
      86                 :            :                         } else {
      87                 :          0 :                                 stats[i].value =
      88                 :          0 :                                         (counters[i] - xstats_ctrl->base[i]);
      89                 :            :                         }
      90                 :            :                 }
      91                 :            :         }
      92                 :          0 :         mlx5_stats_n = mlx5_txpp_xstats_get(dev, stats, n, mlx5_stats_n);
      93                 :          0 :         return mlx5_stats_n;
      94                 :            : }
      95                 :            : 
      96                 :            : /**
      97                 :            :  * DPDK callback to get device statistics.
      98                 :            :  *
      99                 :            :  * @param dev
     100                 :            :  *   Pointer to Ethernet device structure.
     101                 :            :  * @param[out] stats
     102                 :            :  *   Stats structure output buffer.
     103                 :            :  *
     104                 :            :  * @return
     105                 :            :  *   0 on success and stats is filled, negative errno value otherwise and
     106                 :            :  *   rte_errno is set.
     107                 :            :  */
     108                 :            : int
     109                 :          0 : mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
     110                 :            : {
     111                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     112                 :            :         struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
     113                 :            :         struct rte_eth_stats tmp;
     114                 :            :         unsigned int i;
     115                 :            :         unsigned int idx;
     116                 :            :         uint64_t wrap_n;
     117                 :            :         int ret;
     118                 :            : 
     119                 :            :         memset(&tmp, 0, sizeof(tmp));
     120                 :            :         /* Add software counters. */
     121         [ #  # ]:          0 :         for (i = 0; (i != priv->rxqs_n); ++i) {
     122                 :          0 :                 struct mlx5_rxq_data *rxq = mlx5_rxq_data_get(dev, i);
     123                 :            : 
     124         [ #  # ]:          0 :                 if (rxq == NULL)
     125                 :          0 :                         continue;
     126                 :          0 :                 idx = rxq->idx;
     127         [ #  # ]:          0 :                 if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
     128                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     129                 :          0 :                         tmp.q_ipackets[idx] += rxq->stats.ipackets -
     130                 :          0 :                                 rxq->stats_reset.ipackets;
     131                 :          0 :                         tmp.q_ibytes[idx] += rxq->stats.ibytes -
     132                 :          0 :                                 rxq->stats_reset.ibytes;
     133                 :            : #endif
     134                 :          0 :                         tmp.q_errors[idx] += (rxq->stats.idropped +
     135                 :          0 :                                               rxq->stats.rx_nombuf) -
     136                 :          0 :                                               (rxq->stats_reset.idropped +
     137                 :          0 :                                               rxq->stats_reset.rx_nombuf);
     138                 :            :                 }
     139                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     140                 :          0 :                 tmp.ipackets += rxq->stats.ipackets - rxq->stats_reset.ipackets;
     141                 :          0 :                 tmp.ibytes += rxq->stats.ibytes - rxq->stats_reset.ibytes;
     142                 :            : #endif
     143                 :          0 :                 tmp.ierrors += rxq->stats.idropped - rxq->stats_reset.idropped;
     144                 :          0 :                 tmp.rx_nombuf += rxq->stats.rx_nombuf -
     145                 :          0 :                                         rxq->stats_reset.rx_nombuf;
     146                 :            :         }
     147         [ #  # ]:          0 :         for (i = 0; (i != priv->txqs_n); ++i) {
     148                 :          0 :                 struct mlx5_txq_data *txq = (*priv->txqs)[i];
     149                 :            : 
     150         [ #  # ]:          0 :                 if (txq == NULL)
     151                 :          0 :                         continue;
     152                 :          0 :                 idx = txq->idx;
     153         [ #  # ]:          0 :                 if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
     154                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     155                 :          0 :                         tmp.q_opackets[idx] += txq->stats.opackets -
     156                 :          0 :                                                 txq->stats_reset.opackets;
     157                 :          0 :                         tmp.q_obytes[idx] += txq->stats.obytes -
     158                 :          0 :                                                 txq->stats_reset.obytes;
     159                 :            : #endif
     160                 :            :                 }
     161                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     162                 :          0 :                 tmp.opackets += txq->stats.opackets - txq->stats_reset.opackets;
     163                 :          0 :                 tmp.obytes += txq->stats.obytes - txq->stats_reset.obytes;
     164                 :            : #endif
     165                 :          0 :                 tmp.oerrors += txq->stats.oerrors - txq->stats_reset.oerrors;
     166                 :            :         }
     167                 :          0 :         ret = mlx5_os_read_dev_stat(priv, "out_of_buffer", &tmp.imissed);
     168         [ #  # ]:          0 :         if (ret == 0) {
     169                 :          0 :                 tmp.imissed = (tmp.imissed - stats_ctrl->imissed_base) &
     170                 :            :                                  (uint64_t)UINT32_MAX;
     171                 :          0 :                 wrap_n = stats_ctrl->imissed >> 32;
     172         [ #  # ]:          0 :                 if (tmp.imissed < (stats_ctrl->imissed & (uint64_t)UINT32_MAX))
     173                 :          0 :                         wrap_n++;
     174                 :          0 :                 tmp.imissed |= (wrap_n) << 32;
     175                 :          0 :                 stats_ctrl->imissed = tmp.imissed;
     176                 :            :         } else {
     177                 :          0 :                 tmp.imissed = stats_ctrl->imissed;
     178                 :            :         }
     179                 :            : #ifndef MLX5_PMD_SOFT_COUNTERS
     180                 :            :         /* FIXME: retrieve and add hardware counters. */
     181                 :            : #endif
     182                 :          0 :         *stats = tmp;
     183                 :          0 :         return 0;
     184                 :            : }
     185                 :            : 
     186                 :            : /**
     187                 :            :  * DPDK callback to clear device statistics.
     188                 :            :  *
     189                 :            :  * @param dev
     190                 :            :  *   Pointer to Ethernet device structure.
     191                 :            :  *
     192                 :            :  * @return
     193                 :            :  *   always 0 on success and stats is reset
     194                 :            :  */
     195                 :            : int
     196                 :          0 : mlx5_stats_reset(struct rte_eth_dev *dev)
     197                 :            : {
     198                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     199                 :            :         struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
     200                 :            :         unsigned int i;
     201                 :            : 
     202         [ #  # ]:          0 :         for (i = 0; (i != priv->rxqs_n); ++i) {
     203                 :          0 :                 struct mlx5_rxq_data *rxq_data = mlx5_rxq_data_get(dev, i);
     204                 :            : 
     205         [ #  # ]:          0 :                 if (rxq_data == NULL)
     206                 :          0 :                         continue;
     207                 :          0 :                 rxq_data->stats_reset = rxq_data->stats;
     208                 :            :         }
     209         [ #  # ]:          0 :         for (i = 0; (i != priv->txqs_n); ++i) {
     210                 :          0 :                 struct mlx5_txq_data *txq_data = (*priv->txqs)[i];
     211                 :            : 
     212         [ #  # ]:          0 :                 if (txq_data == NULL)
     213                 :          0 :                         continue;
     214                 :          0 :                 txq_data->stats_reset = txq_data->stats;
     215                 :            :         }
     216                 :          0 :         mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
     217                 :          0 :         stats_ctrl->imissed = 0;
     218                 :            : #ifndef MLX5_PMD_SOFT_COUNTERS
     219                 :            :         /* FIXME: reset hardware counters. */
     220                 :            : #endif
     221                 :            : 
     222                 :          0 :         return 0;
     223                 :            : }
     224                 :            : 
     225                 :            : /**
     226                 :            :  * DPDK callback to clear device extended statistics.
     227                 :            :  *
     228                 :            :  * @param dev
     229                 :            :  *   Pointer to Ethernet device structure.
     230                 :            :  *
     231                 :            :  * @return
     232                 :            :  *   0 on success and stats is reset, negative errno value otherwise and
     233                 :            :  *   rte_errno is set.
     234                 :            :  */
     235                 :            : int
     236                 :          0 : mlx5_xstats_reset(struct rte_eth_dev *dev)
     237                 :            : {
     238                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     239                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     240                 :            :         unsigned int i;
     241                 :            :         uint64_t *counters;
     242                 :            :         int ret;
     243                 :          0 :         uint16_t stats_n = 0;
     244                 :          0 :         uint16_t stats_n_2nd = 0;
     245   [ #  #  #  # ]:          0 :         bool bond_master = (priv->master && priv->pf_bond >= 0);
     246                 :            : 
     247                 :          0 :         ret = mlx5_os_get_stats_n(dev, bond_master, &stats_n, &stats_n_2nd);
     248         [ #  # ]:          0 :         if (ret < 0) {
     249                 :          0 :                 DRV_LOG(ERR, "port %u cannot get stats: %s", dev->data->port_id,
     250                 :            :                         strerror(-ret));
     251                 :          0 :                 return ret;
     252                 :            :         }
     253   [ #  #  #  # ]:          0 :         if (xstats_ctrl->stats_n != stats_n ||
     254         [ #  # ]:          0 :             (bond_master && xstats_ctrl->stats_n_2nd != stats_n_2nd))
     255                 :          0 :                 mlx5_os_stats_init(dev);
     256                 :            :         /* Considering to use stack directly. */
     257                 :          0 :         counters = mlx5_malloc(MLX5_MEM_SYS, sizeof(*counters) * xstats_ctrl->mlx5_stats_n,
     258                 :            :                                0, SOCKET_ID_ANY);
     259         [ #  # ]:          0 :         if (!counters) {
     260                 :          0 :                 DRV_LOG(WARNING, "port %u unable to allocate memory for xstats counters",
     261                 :            :                      dev->data->port_id);
     262                 :          0 :                 rte_errno = ENOMEM;
     263                 :          0 :                 return -rte_errno;
     264                 :            :         }
     265                 :          0 :         ret = mlx5_os_read_dev_counters(dev, bond_master, counters);
     266         [ #  # ]:          0 :         if (ret) {
     267                 :          0 :                 DRV_LOG(ERR, "port %u cannot read device counters: %s",
     268                 :            :                         dev->data->port_id, strerror(rte_errno));
     269                 :          0 :                 mlx5_free(counters);
     270                 :          0 :                 return ret;
     271                 :            :         }
     272         [ #  # ]:          0 :         for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) {
     273                 :          0 :                 xstats_ctrl->base[i] = counters[i];
     274                 :          0 :                 xstats_ctrl->hw_stats[i] = 0;
     275                 :            :         }
     276                 :          0 :         mlx5_txpp_xstats_reset(dev);
     277                 :          0 :         mlx5_free(counters);
     278                 :          0 :         return 0;
     279                 :            : }
     280                 :            : 
     281                 :            : /**
     282                 :            :  * DPDK callback to retrieve names of extended device statistics
     283                 :            :  *
     284                 :            :  * @param dev
     285                 :            :  *   Pointer to Ethernet device structure.
     286                 :            :  * @param[out] xstats_names
     287                 :            :  *   Buffer to insert names into.
     288                 :            :  * @param n
     289                 :            :  *   Number of names.
     290                 :            :  *
     291                 :            :  * @return
     292                 :            :  *   Number of xstats names.
     293                 :            :  */
     294                 :            : int
     295                 :          0 : mlx5_xstats_get_names(struct rte_eth_dev *dev,
     296                 :            :                       struct rte_eth_xstat_name *xstats_names, unsigned int n)
     297                 :            : {
     298                 :            :         unsigned int i;
     299                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     300                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     301                 :          0 :         unsigned int mlx5_xstats_n = xstats_ctrl->mlx5_stats_n;
     302                 :            : 
     303         [ #  # ]:          0 :         if (n >= mlx5_xstats_n && xstats_names) {
     304         [ #  # ]:          0 :                 for (i = 0; i != mlx5_xstats_n; ++i) {
     305                 :          0 :                         strlcpy(xstats_names[i].name,
     306                 :            :                                 xstats_ctrl->info[i].dpdk_name,
     307                 :            :                                 RTE_ETH_XSTATS_NAME_SIZE);
     308                 :            :                 }
     309                 :            :         }
     310                 :          0 :         mlx5_xstats_n = mlx5_txpp_xstats_get_names(dev, xstats_names,
     311                 :            :                                                    n, mlx5_xstats_n);
     312                 :          0 :         return mlx5_xstats_n;
     313                 :            : }

Generated by: LCOV version 1.14