LCOV - code coverage report
Current view: top level - drivers/net/mlx5 - mlx5_stats.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 214 0.0 %
Date: 2026-10-01 18:19:24 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 130 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                 :            : static const struct mlx5_xstats_name_off mlx5_rxq_stats_strings[] = {
      25                 :            :         {"out_of_buffer", offsetof(struct mlx5_rq_stats, q_oobs)},
      26                 :            : };
      27                 :            : 
      28                 :            : #define NB_RXQ_STATS RTE_DIM(mlx5_rxq_stats_strings)
      29                 :            : 
      30                 :            : /**
      31                 :            :  * Retrieve extended device statistics
      32                 :            :  * for Rx queues. It appends the specific statistics
      33                 :            :  * before the parts filled by preceding modules (eth stats, etc.)
      34                 :            :  *
      35                 :            :  * @param dev
      36                 :            :  *   Pointer to Ethernet device.
      37                 :            :  * @param[out] stats
      38                 :            :  *   Pointer to an array to store the retrieved statistics.
      39                 :            :  * @return
      40                 :            :  *   Number of extended stats is filled,
      41                 :            :  *   negative on error and rte_errno is set.
      42                 :            :  */
      43                 :            : static int
      44                 :          0 : mlx5_rq_xstats_get(struct rte_eth_dev *dev,
      45                 :            :                                         struct rte_eth_xstat *stats)
      46                 :            : {
      47                 :          0 :         uint16_t n_stats_rq = dev->data->nb_rx_queues;
      48                 :            :         int cnt_used_entries = 0;
      49                 :            : 
      50         [ #  # ]:          0 :         for (unsigned int idx = 0; idx < n_stats_rq; idx++) {
      51                 :          0 :                 struct mlx5_rxq_data *rxq_data = mlx5_rxq_data_get(dev, idx);
      52                 :          0 :                 struct mlx5_rxq_priv *rxq_priv = mlx5_rxq_get(dev, idx);
      53                 :            : 
      54         [ #  # ]:          0 :                 if (rxq_data == NULL)
      55                 :          0 :                         continue;
      56                 :            : 
      57                 :            :                 struct mlx5_rxq_stat *rxq_stat = &rxq_data->stats.oobs;
      58                 :            :                 if (rxq_stat == NULL)
      59                 :            :                         continue;
      60                 :            : 
      61                 :            :                 /* Handle initial stats setup - Flag uninitialized stat */
      62                 :          0 :                 rxq_stat->id = -1;
      63                 :            : 
      64                 :            :                 /* Handle hairpin statistics */
      65   [ #  #  #  # ]:          0 :                 if (rxq_priv && rxq_priv->ctrl->is_hairpin) {
      66         [ #  # ]:          0 :                         if (stats) {
      67                 :          0 :                                 mlx5_read_queue_counter(rxq_priv->q_counter, "hairpin_out_of_buffer",
      68                 :            :                                         &rxq_stat->count);
      69                 :            : 
      70                 :          0 :                                 stats[cnt_used_entries].id = cnt_used_entries;
      71                 :          0 :                                 stats[cnt_used_entries].value = rxq_stat->count -
      72                 :          0 :                                         rxq_data->stats_reset.oobs.count;
      73                 :            :                         }
      74                 :          0 :                         rxq_stat->ctrl.enable = mlx5_enable_per_queue_hairpin_counter;
      75                 :          0 :                         rxq_stat->ctrl.disable = mlx5_disable_per_queue_hairpin_counter;
      76                 :          0 :                         rxq_stat->id = cnt_used_entries;
      77                 :          0 :                         cnt_used_entries++;
      78                 :            :                 }
      79                 :            :         }
      80                 :          0 :         return cnt_used_entries;
      81                 :            : }
      82                 :            : 
      83                 :            : /**
      84                 :            :  * Retrieve names of extended device statistics
      85                 :            :  * for Rx queues. It appends the specific stats names
      86                 :            :  * before the parts filled by preceding modules (eth stats, etc.)
      87                 :            :  *
      88                 :            :  * @param dev
      89                 :            :  *   Pointer to Ethernet device structure.
      90                 :            :  * @param[out] xstats_names
      91                 :            :  *   Buffer to insert names into.
      92                 :            :  *
      93                 :            :  * @return
      94                 :            :  *   Number of xstats names.
      95                 :            :  */
      96                 :            : static int
      97                 :          0 : mlx5_rq_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
      98                 :            :                                struct rte_eth_xstat_name *xstats_names)
      99                 :            : {
     100                 :            :         struct mlx5_rxq_priv *rxq;
     101                 :            :         unsigned int i;
     102                 :            :         int cnt_used_entries = 0;
     103                 :            : 
     104                 :          0 :         uint16_t n_stats_rq = dev->data->nb_rx_queues;
     105                 :            : 
     106         [ #  # ]:          0 :         for (i = 0; (i != n_stats_rq); ++i) {
     107                 :          0 :                 rxq = mlx5_rxq_get(dev, i);
     108                 :            : 
     109         [ #  # ]:          0 :                 if (rxq == NULL)
     110                 :          0 :                         continue;
     111                 :            : 
     112         [ #  # ]:          0 :                 if (rxq->ctrl->is_hairpin) {
     113         [ #  # ]:          0 :                         if (xstats_names)
     114                 :          0 :                                 snprintf(xstats_names[cnt_used_entries].name,
     115                 :            :                                         sizeof(xstats_names[0].name),
     116                 :            :                                         "hairpin_%s_rxq%u",
     117                 :            :                                         mlx5_rxq_stats_strings[0].name, i);
     118                 :          0 :                         cnt_used_entries++;
     119                 :            :                 }
     120                 :            :         }
     121                 :          0 :         return cnt_used_entries;
     122                 :            : }
     123                 :            : 
     124                 :            : /**
     125                 :            :  * DPDK callback to get extended device statistics.
     126                 :            :  *
     127                 :            :  * @param dev
     128                 :            :  *   Pointer to Ethernet device.
     129                 :            :  * @param[out] stats
     130                 :            :  *   Pointer to rte extended stats table.
     131                 :            :  * @param n
     132                 :            :  *   The size of the stats table.
     133                 :            :  *
     134                 :            :  * @return
     135                 :            :  *   Number of extended stats on success and stats is filled,
     136                 :            :  *   negative on error and rte_errno is set.
     137                 :            :  */
     138                 :            : int
     139                 :          0 : mlx5_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
     140                 :            :                 unsigned int n)
     141                 :            : {
     142                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     143                 :            :         uint64_t counters[MLX5_MAX_XSTATS];
     144                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     145                 :            :         unsigned int i;
     146                 :          0 :         uint16_t stats_n = 0;
     147                 :          0 :         uint16_t stats_n_2nd = 0;
     148                 :          0 :         uint16_t mlx5_stats_n = xstats_ctrl->mlx5_stats_n;
     149   [ #  #  #  # ]:          0 :         bool bond_master = (priv->master && priv->pf_bond >= 0);
     150                 :          0 :         int n_used = mlx5_rq_xstats_get(dev, stats);
     151                 :            : 
     152   [ #  #  #  # ]:          0 :         if (n >= mlx5_stats_n && stats) {
     153                 :            :                 int ret;
     154                 :            : 
     155                 :          0 :                 ret = mlx5_os_get_stats_n(dev, bond_master, &stats_n, &stats_n_2nd);
     156         [ #  # ]:          0 :                 if (ret < 0)
     157                 :            :                         return ret;
     158                 :            :                 /*
     159                 :            :                  * The number of statistics fetched via "ETH_SS_STATS" may vary because
     160                 :            :                  * of the port configuration each time. This is also true between 2
     161                 :            :                  * ports. There might be a case that the numbers are the same even if
     162                 :            :                  * configurations are different.
     163                 :            :                  * It is not recommended to change the configuration without using
     164                 :            :                  * RTE API. The port(traffic) restart may trigger another initialization
     165                 :            :                  * to make sure the map are correct.
     166                 :            :                  */
     167   [ #  #  #  # ]:          0 :                 if (xstats_ctrl->stats_n != stats_n ||
     168         [ #  # ]:          0 :                     (bond_master && xstats_ctrl->stats_n_2nd != stats_n_2nd))
     169                 :          0 :                         mlx5_os_stats_init(dev);
     170                 :          0 :                 ret = mlx5_os_read_dev_counters(dev, bond_master, counters);
     171         [ #  # ]:          0 :                 if (ret < 0)
     172                 :            :                         return ret;
     173         [ #  # ]:          0 :                 for (i = 0; i != mlx5_stats_n; i++) {
     174                 :          0 :                         stats[i + n_used].id = i + n_used;
     175         [ #  # ]:          0 :                         if (xstats_ctrl->info[i].dev) {
     176                 :            :                                 uint64_t wrap_n;
     177                 :          0 :                                 uint64_t hw_stat = xstats_ctrl->hw_stats[i];
     178                 :            : 
     179                 :          0 :                                 stats[i + n_used].value = (counters[i] -
     180                 :          0 :                                                   xstats_ctrl->base[i]) &
     181                 :            :                                                   (uint64_t)UINT32_MAX;
     182                 :          0 :                                 wrap_n = hw_stat >> 32;
     183                 :          0 :                                 if (stats[i + n_used].value <
     184         [ #  # ]:          0 :                                             (hw_stat & (uint64_t)UINT32_MAX))
     185                 :          0 :                                         wrap_n++;
     186                 :          0 :                                 stats[i + n_used].value |= (wrap_n) << 32;
     187                 :          0 :                                 xstats_ctrl->hw_stats[i] = stats[i + n_used].value;
     188                 :            :                         } else {
     189                 :          0 :                                 stats[i + n_used].value =
     190                 :          0 :                                         (counters[i] - xstats_ctrl->base[i]);
     191                 :            :                         }
     192                 :            :                 }
     193                 :            :         }
     194                 :          0 :         mlx5_stats_n = mlx5_txpp_xstats_get(dev, stats, n, mlx5_stats_n + n_used);
     195                 :          0 :         return mlx5_stats_n;
     196                 :            : }
     197                 :            : 
     198                 :            : /**
     199                 :            :  * DPDK callback to get device statistics.
     200                 :            :  *
     201                 :            :  * @param dev
     202                 :            :  *   Pointer to Ethernet device structure.
     203                 :            :  * @param[out] stats
     204                 :            :  *   Stats structure output buffer.
     205                 :            :  *
     206                 :            :  * @return
     207                 :            :  *   0 on success and stats is filled, negative errno value otherwise and
     208                 :            :  *   rte_errno is set.
     209                 :            :  */
     210                 :            : int
     211                 :          0 : mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
     212                 :            :                struct eth_queue_stats *qstats)
     213                 :            : {
     214                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     215                 :            :         struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
     216                 :            :         struct rte_eth_stats tmp;
     217                 :            :         unsigned int i;
     218                 :            :         unsigned int idx;
     219                 :            :         uint64_t wrap_n;
     220                 :            :         int ret;
     221                 :            : 
     222                 :            :         memset(&tmp, 0, sizeof(tmp));
     223                 :            :         /* Add software counters. */
     224         [ #  # ]:          0 :         for (i = 0; (i != priv->rxqs_n); ++i) {
     225                 :          0 :                 struct mlx5_rxq_data *rxq = mlx5_rxq_data_get(dev, i);
     226                 :            : 
     227         [ #  # ]:          0 :                 if (rxq == NULL)
     228                 :          0 :                         continue;
     229                 :          0 :                 idx = rxq->idx;
     230   [ #  #  #  # ]:          0 :                 if (qstats != NULL && idx < dev->data->nb_rx_queues) {
     231                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     232                 :          0 :                         qstats[idx].q_ipackets += rxq->stats.ipackets -
     233                 :          0 :                                 rxq->stats_reset.ipackets;
     234                 :          0 :                         qstats[idx].q_ibytes += rxq->stats.ibytes -
     235                 :          0 :                                 rxq->stats_reset.ibytes;
     236                 :            : #endif
     237                 :            :                 }
     238                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     239                 :          0 :                 tmp.ipackets += rxq->stats.ipackets - rxq->stats_reset.ipackets;
     240                 :          0 :                 tmp.ibytes += rxq->stats.ibytes - rxq->stats_reset.ibytes;
     241                 :            : #endif
     242                 :          0 :                 tmp.ierrors += rxq->stats.idropped - rxq->stats_reset.idropped;
     243                 :          0 :                 tmp.rx_nombuf += rxq->stats.rx_nombuf -
     244                 :          0 :                                         rxq->stats_reset.rx_nombuf;
     245                 :            :         }
     246         [ #  # ]:          0 :         for (i = 0; (i != priv->txqs_n); ++i) {
     247                 :          0 :                 struct mlx5_txq_data *txq = (*priv->txqs)[i];
     248                 :            : 
     249         [ #  # ]:          0 :                 if (txq == NULL)
     250                 :          0 :                         continue;
     251                 :          0 :                 idx = txq->idx;
     252   [ #  #  #  # ]:          0 :                 if (qstats != NULL && idx < dev->data->nb_tx_queues) {
     253                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     254                 :          0 :                         qstats[idx].q_opackets += txq->stats.opackets -
     255                 :          0 :                                                 txq->stats_reset.opackets;
     256                 :          0 :                         qstats[idx].q_obytes += txq->stats.obytes -
     257                 :          0 :                                                 txq->stats_reset.obytes;
     258                 :            : #endif
     259                 :            :                 }
     260                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     261                 :          0 :                 tmp.opackets += txq->stats.opackets - txq->stats_reset.opackets;
     262                 :          0 :                 tmp.obytes += txq->stats.obytes - txq->stats_reset.obytes;
     263                 :            : #endif
     264                 :          0 :                 tmp.oerrors += txq->stats.oerrors - txq->stats_reset.oerrors;
     265                 :            :         }
     266                 :          0 :         ret = mlx5_os_read_dev_stat(priv, "out_of_buffer", &tmp.imissed);
     267         [ #  # ]:          0 :         if (ret == 0) {
     268                 :          0 :                 tmp.imissed = (tmp.imissed - stats_ctrl->imissed_base) &
     269                 :            :                                  (uint64_t)UINT32_MAX;
     270                 :          0 :                 wrap_n = stats_ctrl->imissed >> 32;
     271         [ #  # ]:          0 :                 if (tmp.imissed < (stats_ctrl->imissed & (uint64_t)UINT32_MAX))
     272                 :          0 :                         wrap_n++;
     273                 :          0 :                 tmp.imissed |= (wrap_n) << 32;
     274                 :          0 :                 stats_ctrl->imissed = tmp.imissed;
     275                 :            :         } else {
     276                 :          0 :                 tmp.imissed = stats_ctrl->imissed;
     277                 :            :         }
     278                 :            : #ifndef MLX5_PMD_SOFT_COUNTERS
     279                 :            :         /* FIXME: retrieve and add hardware counters. */
     280                 :            : #endif
     281                 :          0 :         *stats = tmp;
     282                 :          0 :         return 0;
     283                 :            : }
     284                 :            : 
     285                 :            : /**
     286                 :            :  * DPDK callback to clear device statistics.
     287                 :            :  *
     288                 :            :  * @param dev
     289                 :            :  *   Pointer to Ethernet device structure.
     290                 :            :  *
     291                 :            :  * @return
     292                 :            :  *   always 0 on success and stats is reset
     293                 :            :  */
     294                 :            : int
     295                 :          0 : mlx5_stats_reset(struct rte_eth_dev *dev)
     296                 :            : {
     297                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     298                 :            :         struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
     299                 :            :         unsigned int i;
     300                 :            : 
     301         [ #  # ]:          0 :         for (i = 0; (i != priv->rxqs_n); ++i) {
     302                 :          0 :                 struct mlx5_rxq_data *rxq_data = mlx5_rxq_data_get(dev, i);
     303                 :            : 
     304         [ #  # ]:          0 :                 if (rxq_data == NULL)
     305                 :          0 :                         continue;
     306                 :          0 :                 rxq_data->stats_reset = rxq_data->stats;
     307                 :            :         }
     308         [ #  # ]:          0 :         for (i = 0; (i != priv->txqs_n); ++i) {
     309                 :          0 :                 struct mlx5_txq_data *txq_data = (*priv->txqs)[i];
     310                 :            : 
     311         [ #  # ]:          0 :                 if (txq_data == NULL)
     312                 :          0 :                         continue;
     313                 :          0 :                 txq_data->stats_reset = txq_data->stats;
     314                 :            :         }
     315                 :          0 :         mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
     316                 :          0 :         stats_ctrl->imissed = 0;
     317                 :            : #ifndef MLX5_PMD_SOFT_COUNTERS
     318                 :            :         /* FIXME: reset hardware counters. */
     319                 :            : #endif
     320                 :            : 
     321                 :          0 :         return 0;
     322                 :            : }
     323                 :            : 
     324                 :            : /**
     325                 :            :  * DPDK callback to clear device extended statistics.
     326                 :            :  *
     327                 :            :  * @param dev
     328                 :            :  *   Pointer to Ethernet device structure.
     329                 :            :  *
     330                 :            :  * @return
     331                 :            :  *   0 on success and stats is reset, negative errno value otherwise and
     332                 :            :  *   rte_errno is set.
     333                 :            :  */
     334                 :            : int
     335                 :          0 : mlx5_xstats_reset(struct rte_eth_dev *dev)
     336                 :            : {
     337                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     338                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     339                 :            :         unsigned int i;
     340                 :            :         uint64_t *counters;
     341                 :            :         int ret;
     342                 :          0 :         uint16_t stats_n = 0;
     343                 :          0 :         uint16_t stats_n_2nd = 0;
     344   [ #  #  #  # ]:          0 :         bool bond_master = (priv->master && priv->pf_bond >= 0);
     345                 :            : 
     346                 :          0 :         ret = mlx5_os_get_stats_n(dev, bond_master, &stats_n, &stats_n_2nd);
     347         [ #  # ]:          0 :         if (ret < 0) {
     348                 :          0 :                 DRV_LOG(ERR, "port %u cannot get stats: %s", dev->data->port_id,
     349                 :            :                         strerror(-ret));
     350                 :          0 :                 return ret;
     351                 :            :         }
     352   [ #  #  #  # ]:          0 :         if (xstats_ctrl->stats_n != stats_n ||
     353         [ #  # ]:          0 :             (bond_master && xstats_ctrl->stats_n_2nd != stats_n_2nd))
     354                 :          0 :                 mlx5_os_stats_init(dev);
     355                 :            :         /* Considering to use stack directly. */
     356                 :          0 :         counters = mlx5_malloc(MLX5_MEM_SYS, sizeof(*counters) * xstats_ctrl->mlx5_stats_n,
     357                 :            :                                0, SOCKET_ID_ANY);
     358         [ #  # ]:          0 :         if (!counters) {
     359                 :          0 :                 DRV_LOG(WARNING, "port %u unable to allocate memory for xstats counters",
     360                 :            :                      dev->data->port_id);
     361                 :          0 :                 rte_errno = ENOMEM;
     362                 :          0 :                 return -rte_errno;
     363                 :            :         }
     364                 :          0 :         ret = mlx5_os_read_dev_counters(dev, bond_master, counters);
     365         [ #  # ]:          0 :         if (ret) {
     366                 :          0 :                 DRV_LOG(ERR, "port %u cannot read device counters: %s",
     367                 :            :                         dev->data->port_id, strerror(rte_errno));
     368                 :          0 :                 mlx5_free(counters);
     369                 :          0 :                 return ret;
     370                 :            :         }
     371         [ #  # ]:          0 :         for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) {
     372                 :          0 :                 xstats_ctrl->base[i] = counters[i];
     373                 :          0 :                 xstats_ctrl->hw_stats[i] = 0;
     374                 :            :         }
     375                 :          0 :         mlx5_reset_xstats_rq(dev);
     376                 :          0 :         mlx5_txpp_xstats_reset(dev);
     377                 :          0 :         mlx5_free(counters);
     378                 :          0 :         return 0;
     379                 :            : }
     380                 :            : 
     381                 :            : void
     382                 :          0 : mlx5_reset_xstats_by_name(struct mlx5_priv *priv, const char *ctr_name)
     383                 :            : {
     384                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     385                 :          0 :         unsigned int mlx5_xstats_n = xstats_ctrl->mlx5_stats_n;
     386                 :            :         unsigned int i;
     387                 :            : 
     388         [ #  # ]:          0 :         for (i = 0; i != mlx5_xstats_n; ++i) {
     389         [ #  # ]:          0 :                 if (strcmp(xstats_ctrl->info[i].ctr_name, ctr_name) == 0) {
     390                 :          0 :                         xstats_ctrl->base[i] = 0;
     391                 :          0 :                         xstats_ctrl->hw_stats[i] = 0;
     392                 :          0 :                         xstats_ctrl->xstats[i] = 0;
     393                 :          0 :                         return;
     394                 :            :                 }
     395                 :            :         }
     396                 :            : }
     397                 :            : 
     398                 :            : /**
     399                 :            :  * Clear device extended statistics for each Rx queue.
     400                 :            :  *
     401                 :            :  * @param dev
     402                 :            :  *   Pointer to Ethernet device structure.
     403                 :            :  */
     404                 :            : void
     405                 :          0 : mlx5_reset_xstats_rq(struct rte_eth_dev *dev)
     406                 :            : {
     407                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     408                 :            :         struct mlx5_rxq_priv *rxq;
     409                 :            :         struct mlx5_rxq_data *rxq_data;
     410                 :            :         unsigned int i;
     411                 :            : 
     412         [ #  # ]:          0 :         for (i = 0; (i != priv->rxqs_n); ++i) {
     413                 :          0 :                 rxq = mlx5_rxq_get(dev, i);
     414                 :          0 :                 rxq_data = mlx5_rxq_data_get(dev, i);
     415                 :            : 
     416   [ #  #  #  # ]:          0 :                 if (rxq == NULL || rxq_data == NULL || rxq->q_counter == NULL)
     417                 :          0 :                         continue;
     418         [ #  # ]:          0 :                 if (rxq->ctrl->is_hairpin)
     419                 :          0 :                         mlx5_read_queue_counter(rxq->q_counter,
     420                 :            :                                 "hairpin_out_of_buffer", &rxq_data->stats_reset.oobs.count);
     421                 :            :                 else
     422                 :          0 :                         mlx5_read_queue_counter(rxq->q_counter,
     423                 :            :                                 "out_of_buffer", &rxq_data->stats_reset.oobs.count);
     424                 :            :         }
     425                 :          0 : }
     426                 :            : 
     427                 :            : /**
     428                 :            :  * DPDK callback to retrieve names of extended device statistics
     429                 :            :  *
     430                 :            :  * @param dev
     431                 :            :  *   Pointer to Ethernet device structure.
     432                 :            :  * @param[out] xstats_names
     433                 :            :  *   Buffer to insert names into.
     434                 :            :  * @param n
     435                 :            :  *   Number of names.
     436                 :            :  *
     437                 :            :  * @return
     438                 :            :  *   Number of xstats names.
     439                 :            :  */
     440                 :            : int
     441                 :          0 : mlx5_xstats_get_names(struct rte_eth_dev *dev,
     442                 :            :                       struct rte_eth_xstat_name *xstats_names, unsigned int n)
     443                 :            : {
     444                 :            :         unsigned int i;
     445                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     446                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     447                 :          0 :         unsigned int mlx5_xstats_n = xstats_ctrl->mlx5_stats_n;
     448                 :          0 :         unsigned int n_used = mlx5_rq_xstats_get_names(dev, xstats_names);
     449                 :            : 
     450         [ #  # ]:          0 :         if (n >= mlx5_xstats_n && xstats_names) {
     451         [ #  # ]:          0 :                 for (i = 0; i != mlx5_xstats_n; ++i) {
     452                 :          0 :                         rte_strscpy(xstats_names[i + n_used].name,
     453                 :          0 :                                 xstats_ctrl->info[i].dpdk_name,
     454                 :            :                                 RTE_ETH_XSTATS_NAME_SIZE);
     455                 :          0 :                         xstats_names[i + n_used].name[RTE_ETH_XSTATS_NAME_SIZE - 1] = 0;
     456                 :            :                 }
     457                 :            :         }
     458                 :          0 :         mlx5_xstats_n = mlx5_txpp_xstats_get_names(dev, xstats_names,
     459                 :            :                                                    n, mlx5_xstats_n + n_used);
     460                 :          0 :         return mlx5_xstats_n;
     461                 :            : }
     462                 :            : 
     463                 :            : static struct mlx5_stat_counter_ctrl*
     464                 :          0 : mlx5_rxq_get_counter_by_id(struct rte_eth_dev *dev, uint64_t id, uint64_t *rq_id)
     465                 :            : {
     466                 :          0 :         uint16_t n_stats_rq = dev->data->nb_rx_queues;
     467                 :            : 
     468         [ #  # ]:          0 :         for (int i = 0; (i != n_stats_rq); i++) {
     469                 :          0 :                 struct mlx5_rxq_data *rxq_data = mlx5_rxq_data_get(dev, i);
     470   [ #  #  #  # ]:          0 :                 if (rxq_data == NULL || rxq_data->stats.oobs.id == -1)
     471                 :          0 :                         continue;
     472                 :            : 
     473         [ #  # ]:          0 :                 if ((uint64_t)rxq_data->stats.oobs.id == id) {
     474                 :          0 :                         *rq_id = rxq_data->idx;
     475                 :          0 :                         return &rxq_data->stats.oobs.ctrl;
     476                 :            :                 }
     477                 :            :         }
     478                 :            : 
     479                 :            :         return NULL;
     480                 :            : }
     481                 :            : 
     482                 :            : /**
     483                 :            :  * Callback to enable an xstat counter of the given id.
     484                 :            :  *
     485                 :            :  * @param dev
     486                 :            :  *   Pointer to Ethernet device structure.
     487                 :            :  * @param id
     488                 :            :  *   The ID of the counter to enable
     489                 :            :  *
     490                 :            :  * @return
     491                 :            :  *   1 xstat is enabled, 0 if xstat is disabled,
     492                 :            :  *   -ENOTSUP if enabling/disabling is not implemented and -EINVAL if xstat id is invalid.
     493                 :            :  */
     494                 :            : int
     495                 :          0 : mlx5_xstats_enable(struct rte_eth_dev *dev, uint64_t id)
     496                 :            : {
     497                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     498                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     499                 :            :         struct mlx5_stat_counter_ctrl *counter_ctrl = NULL;
     500                 :          0 :         uint16_t n_stats_rq = mlx5_rq_xstats_get(dev, NULL);
     501                 :            : 
     502         [ #  # ]:          0 :         if (id < n_stats_rq)
     503                 :          0 :                 counter_ctrl = mlx5_rxq_get_counter_by_id(dev, id, &id);
     504                 :            :         else
     505                 :          0 :                 counter_ctrl = &xstats_ctrl->info[id - n_stats_rq].ctrl;
     506                 :            : 
     507         [ #  # ]:          0 :         if (counter_ctrl == NULL)
     508                 :            :                 return -EINVAL;
     509                 :            : 
     510         [ #  # ]:          0 :         if (counter_ctrl->enable == NULL)
     511                 :            :                 return -ENOTSUP;
     512                 :            : 
     513                 :          0 :         counter_ctrl->enabled = counter_ctrl->enable(dev, id) == 0 ? 1 : 0;
     514                 :          0 :         return counter_ctrl->enabled;
     515                 :            : }
     516                 :            : 
     517                 :            : /**
     518                 :            :  * Callback to disable an xstat counter of the given id.
     519                 :            :  *
     520                 :            :  * @param dev
     521                 :            :  *   Pointer to Ethernet device structure.
     522                 :            :  * @param id
     523                 :            :  *   The ID of the counter to enable
     524                 :            :  *
     525                 :            :  * @return
     526                 :            :  *   1 if xstat is disabled, 0 xstat is enabled,
     527                 :            :  *   -ENOTSUP if enabling/disabling is not implemented and -EINVAL if xstat id is invalid.
     528                 :            :  */
     529                 :            : int
     530                 :          0 : mlx5_xstats_disable(struct rte_eth_dev *dev, uint64_t id)
     531                 :            : {
     532                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     533                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     534                 :            :         struct mlx5_stat_counter_ctrl *counter_ctrl = NULL;
     535                 :            : 
     536                 :          0 :         uint16_t n_stats_rq = mlx5_rq_xstats_get(dev, NULL);
     537         [ #  # ]:          0 :         if (id < n_stats_rq)
     538                 :          0 :                 counter_ctrl = mlx5_rxq_get_counter_by_id(dev, id, &id);
     539                 :            :         else
     540                 :          0 :                 counter_ctrl = &xstats_ctrl->info[id - n_stats_rq].ctrl;
     541                 :            : 
     542         [ #  # ]:          0 :         if (counter_ctrl == NULL)
     543                 :            :                 return -EINVAL;
     544                 :            : 
     545         [ #  # ]:          0 :         if (counter_ctrl->disable == NULL)
     546                 :            :                 return -ENOTSUP;
     547                 :            : 
     548                 :          0 :         counter_ctrl->enabled = counter_ctrl->disable(dev, id) == 0 ? 0 : 1;
     549                 :          0 :         return counter_ctrl->enabled;
     550                 :            : }
     551                 :            : 
     552                 :            : /**
     553                 :            :  * Query the state of the xstat counter.
     554                 :            :  *
     555                 :            :  * @param dev
     556                 :            :  *   Pointer to Ethernet device structure.
     557                 :            :  * @param id
     558                 :            :  *   The ID of the counter to enable
     559                 :            :  *
     560                 :            :  * @return
     561                 :            :  *   1 if xstat is disabled, 0 xstat is enabled,
     562                 :            :  *   -ENOTSUP if enabling/disabling is not implemented and -EINVAL if xstat id is invalid.
     563                 :            :  */
     564                 :            : int
     565                 :          0 : mlx5_xstats_query_state(struct rte_eth_dev *dev, uint64_t id)
     566                 :            : {
     567                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     568                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     569                 :            :         struct mlx5_stat_counter_ctrl *counter_ctrl = NULL;
     570                 :            : 
     571                 :          0 :         uint16_t n_stats_rq = mlx5_rq_xstats_get(dev, NULL);
     572         [ #  # ]:          0 :         if (id < n_stats_rq)
     573                 :          0 :                 counter_ctrl = mlx5_rxq_get_counter_by_id(dev, id, &id);
     574                 :            :         else
     575                 :          0 :                 counter_ctrl = &xstats_ctrl->info[id - n_stats_rq].ctrl;
     576                 :            : 
     577         [ #  # ]:          0 :         if (counter_ctrl == NULL)
     578                 :            :                 return -EINVAL;
     579                 :            : 
     580         [ #  # ]:          0 :         if (counter_ctrl->disable == NULL)
     581                 :            :                 return -ENOTSUP;
     582                 :            : 
     583                 :          0 :         return counter_ctrl->enabled;
     584                 :            : }

Generated by: LCOV version 1.14