LCOV - code coverage report
Current view: top level - drivers/net/mlx5 - mlx5_stats.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 218 0.0 %
Date: 2025-03-01 20:23:48 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 126 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 = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
      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 = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
     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                 :            : {
     213                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     214                 :            :         struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
     215                 :            :         struct rte_eth_stats tmp;
     216                 :            :         unsigned int i;
     217                 :            :         unsigned int idx;
     218                 :            :         uint64_t wrap_n;
     219                 :            :         int ret;
     220                 :            : 
     221                 :            :         memset(&tmp, 0, sizeof(tmp));
     222                 :            :         /* Add software counters. */
     223         [ #  # ]:          0 :         for (i = 0; (i != priv->rxqs_n); ++i) {
     224                 :          0 :                 struct mlx5_rxq_data *rxq = mlx5_rxq_data_get(dev, i);
     225                 :            : 
     226         [ #  # ]:          0 :                 if (rxq == NULL)
     227                 :          0 :                         continue;
     228                 :          0 :                 idx = rxq->idx;
     229         [ #  # ]:          0 :                 if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
     230                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     231                 :          0 :                         tmp.q_ipackets[idx] += rxq->stats.ipackets -
     232                 :          0 :                                 rxq->stats_reset.ipackets;
     233                 :          0 :                         tmp.q_ibytes[idx] += rxq->stats.ibytes -
     234                 :          0 :                                 rxq->stats_reset.ibytes;
     235                 :            : #endif
     236                 :          0 :                         tmp.q_errors[idx] += (rxq->stats.idropped +
     237                 :          0 :                                               rxq->stats.rx_nombuf) -
     238                 :          0 :                                               (rxq->stats_reset.idropped +
     239                 :          0 :                                               rxq->stats_reset.rx_nombuf);
     240                 :            :                 }
     241                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     242                 :          0 :                 tmp.ipackets += rxq->stats.ipackets - rxq->stats_reset.ipackets;
     243                 :          0 :                 tmp.ibytes += rxq->stats.ibytes - rxq->stats_reset.ibytes;
     244                 :            : #endif
     245                 :          0 :                 tmp.ierrors += rxq->stats.idropped - rxq->stats_reset.idropped;
     246                 :          0 :                 tmp.rx_nombuf += rxq->stats.rx_nombuf -
     247                 :          0 :                                         rxq->stats_reset.rx_nombuf;
     248                 :            :         }
     249         [ #  # ]:          0 :         for (i = 0; (i != priv->txqs_n); ++i) {
     250                 :          0 :                 struct mlx5_txq_data *txq = (*priv->txqs)[i];
     251                 :            : 
     252         [ #  # ]:          0 :                 if (txq == NULL)
     253                 :          0 :                         continue;
     254                 :          0 :                 idx = txq->idx;
     255         [ #  # ]:          0 :                 if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
     256                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     257                 :          0 :                         tmp.q_opackets[idx] += txq->stats.opackets -
     258                 :          0 :                                                 txq->stats_reset.opackets;
     259                 :          0 :                         tmp.q_obytes[idx] += txq->stats.obytes -
     260                 :          0 :                                                 txq->stats_reset.obytes;
     261                 :            : #endif
     262                 :            :                 }
     263                 :            : #ifdef MLX5_PMD_SOFT_COUNTERS
     264                 :          0 :                 tmp.opackets += txq->stats.opackets - txq->stats_reset.opackets;
     265                 :          0 :                 tmp.obytes += txq->stats.obytes - txq->stats_reset.obytes;
     266                 :            : #endif
     267                 :          0 :                 tmp.oerrors += txq->stats.oerrors - txq->stats_reset.oerrors;
     268                 :            :         }
     269                 :          0 :         ret = mlx5_os_read_dev_stat(priv, "out_of_buffer", &tmp.imissed);
     270         [ #  # ]:          0 :         if (ret == 0) {
     271                 :          0 :                 tmp.imissed = (tmp.imissed - stats_ctrl->imissed_base) &
     272                 :            :                                  (uint64_t)UINT32_MAX;
     273                 :          0 :                 wrap_n = stats_ctrl->imissed >> 32;
     274         [ #  # ]:          0 :                 if (tmp.imissed < (stats_ctrl->imissed & (uint64_t)UINT32_MAX))
     275                 :          0 :                         wrap_n++;
     276                 :          0 :                 tmp.imissed |= (wrap_n) << 32;
     277                 :          0 :                 stats_ctrl->imissed = tmp.imissed;
     278                 :            :         } else {
     279                 :          0 :                 tmp.imissed = stats_ctrl->imissed;
     280                 :            :         }
     281                 :            : #ifndef MLX5_PMD_SOFT_COUNTERS
     282                 :            :         /* FIXME: retrieve and add hardware counters. */
     283                 :            : #endif
     284                 :          0 :         *stats = tmp;
     285                 :          0 :         return 0;
     286                 :            : }
     287                 :            : 
     288                 :            : /**
     289                 :            :  * DPDK callback to clear device statistics.
     290                 :            :  *
     291                 :            :  * @param dev
     292                 :            :  *   Pointer to Ethernet device structure.
     293                 :            :  *
     294                 :            :  * @return
     295                 :            :  *   always 0 on success and stats is reset
     296                 :            :  */
     297                 :            : int
     298                 :          0 : mlx5_stats_reset(struct rte_eth_dev *dev)
     299                 :            : {
     300                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     301                 :            :         struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
     302                 :            :         unsigned int i;
     303                 :            : 
     304         [ #  # ]:          0 :         for (i = 0; (i != priv->rxqs_n); ++i) {
     305                 :          0 :                 struct mlx5_rxq_data *rxq_data = mlx5_rxq_data_get(dev, i);
     306                 :            : 
     307         [ #  # ]:          0 :                 if (rxq_data == NULL)
     308                 :          0 :                         continue;
     309                 :          0 :                 rxq_data->stats_reset = rxq_data->stats;
     310                 :            :         }
     311         [ #  # ]:          0 :         for (i = 0; (i != priv->txqs_n); ++i) {
     312                 :          0 :                 struct mlx5_txq_data *txq_data = (*priv->txqs)[i];
     313                 :            : 
     314         [ #  # ]:          0 :                 if (txq_data == NULL)
     315                 :          0 :                         continue;
     316                 :          0 :                 txq_data->stats_reset = txq_data->stats;
     317                 :            :         }
     318                 :          0 :         mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
     319                 :          0 :         stats_ctrl->imissed = 0;
     320                 :            : #ifndef MLX5_PMD_SOFT_COUNTERS
     321                 :            :         /* FIXME: reset hardware counters. */
     322                 :            : #endif
     323                 :            : 
     324                 :          0 :         return 0;
     325                 :            : }
     326                 :            : 
     327                 :            : /**
     328                 :            :  * DPDK callback to clear device extended statistics.
     329                 :            :  *
     330                 :            :  * @param dev
     331                 :            :  *   Pointer to Ethernet device structure.
     332                 :            :  *
     333                 :            :  * @return
     334                 :            :  *   0 on success and stats is reset, negative errno value otherwise and
     335                 :            :  *   rte_errno is set.
     336                 :            :  */
     337                 :            : int
     338                 :          0 : mlx5_xstats_reset(struct rte_eth_dev *dev)
     339                 :            : {
     340                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     341                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     342                 :            :         unsigned int i;
     343                 :            :         uint64_t *counters;
     344                 :            :         int ret;
     345                 :          0 :         uint16_t stats_n = 0;
     346                 :          0 :         uint16_t stats_n_2nd = 0;
     347   [ #  #  #  # ]:          0 :         bool bond_master = (priv->master && priv->pf_bond >= 0);
     348                 :            : 
     349                 :          0 :         ret = mlx5_os_get_stats_n(dev, bond_master, &stats_n, &stats_n_2nd);
     350         [ #  # ]:          0 :         if (ret < 0) {
     351                 :          0 :                 DRV_LOG(ERR, "port %u cannot get stats: %s", dev->data->port_id,
     352                 :            :                         strerror(-ret));
     353                 :          0 :                 return ret;
     354                 :            :         }
     355   [ #  #  #  # ]:          0 :         if (xstats_ctrl->stats_n != stats_n ||
     356         [ #  # ]:          0 :             (bond_master && xstats_ctrl->stats_n_2nd != stats_n_2nd))
     357                 :          0 :                 mlx5_os_stats_init(dev);
     358                 :            :         /* Considering to use stack directly. */
     359                 :          0 :         counters = mlx5_malloc(MLX5_MEM_SYS, sizeof(*counters) * xstats_ctrl->mlx5_stats_n,
     360                 :            :                                0, SOCKET_ID_ANY);
     361         [ #  # ]:          0 :         if (!counters) {
     362                 :          0 :                 DRV_LOG(WARNING, "port %u unable to allocate memory for xstats counters",
     363                 :            :                      dev->data->port_id);
     364                 :          0 :                 rte_errno = ENOMEM;
     365                 :          0 :                 return -rte_errno;
     366                 :            :         }
     367                 :          0 :         ret = mlx5_os_read_dev_counters(dev, bond_master, counters);
     368         [ #  # ]:          0 :         if (ret) {
     369                 :          0 :                 DRV_LOG(ERR, "port %u cannot read device counters: %s",
     370                 :            :                         dev->data->port_id, strerror(rte_errno));
     371                 :          0 :                 mlx5_free(counters);
     372                 :          0 :                 return ret;
     373                 :            :         }
     374         [ #  # ]:          0 :         for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) {
     375                 :          0 :                 xstats_ctrl->base[i] = counters[i];
     376                 :          0 :                 xstats_ctrl->hw_stats[i] = 0;
     377                 :            :         }
     378                 :          0 :         mlx5_reset_xstats_rq(dev);
     379                 :          0 :         mlx5_txpp_xstats_reset(dev);
     380                 :          0 :         mlx5_free(counters);
     381                 :          0 :         return 0;
     382                 :            : }
     383                 :            : 
     384                 :            : void
     385                 :          0 : mlx5_reset_xstats_by_name(struct mlx5_priv *priv, const char *ctr_name)
     386                 :            : {
     387                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     388                 :          0 :         unsigned int mlx5_xstats_n = xstats_ctrl->mlx5_stats_n;
     389                 :            :         unsigned int i;
     390                 :            : 
     391         [ #  # ]:          0 :         for (i = 0; i != mlx5_xstats_n; ++i) {
     392         [ #  # ]:          0 :                 if (strcmp(xstats_ctrl->info[i].ctr_name, ctr_name) == 0) {
     393                 :          0 :                         xstats_ctrl->base[i] = 0;
     394                 :          0 :                         xstats_ctrl->hw_stats[i] = 0;
     395                 :          0 :                         xstats_ctrl->xstats[i] = 0;
     396                 :          0 :                         return;
     397                 :            :                 }
     398                 :            :         }
     399                 :            : }
     400                 :            : 
     401                 :            : /**
     402                 :            :  * Clear device extended statistics for each Rx queue.
     403                 :            :  *
     404                 :            :  * @param dev
     405                 :            :  *   Pointer to Ethernet device structure.
     406                 :            :  */
     407                 :            : void
     408                 :          0 : mlx5_reset_xstats_rq(struct rte_eth_dev *dev)
     409                 :            : {
     410                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     411                 :            :         struct mlx5_rxq_priv *rxq;
     412                 :            :         struct mlx5_rxq_data *rxq_data;
     413                 :            :         unsigned int i;
     414                 :            : 
     415         [ #  # ]:          0 :         for (i = 0; (i != priv->rxqs_n); ++i) {
     416                 :          0 :                 rxq = mlx5_rxq_get(dev, i);
     417                 :          0 :                 rxq_data = mlx5_rxq_data_get(dev, i);
     418                 :            : 
     419   [ #  #  #  # ]:          0 :                 if (rxq == NULL || rxq_data == NULL || rxq->q_counter == NULL)
     420                 :          0 :                         continue;
     421         [ #  # ]:          0 :                 if (rxq->ctrl->is_hairpin)
     422                 :          0 :                         mlx5_read_queue_counter(rxq->q_counter,
     423                 :            :                                 "hairpin_out_of_buffer", &rxq_data->stats_reset.oobs.count);
     424                 :            :                 else
     425                 :          0 :                         mlx5_read_queue_counter(rxq->q_counter,
     426                 :            :                                 "out_of_buffer", &rxq_data->stats_reset.oobs.count);
     427                 :            :         }
     428                 :          0 : }
     429                 :            : 
     430                 :            : /**
     431                 :            :  * DPDK callback to retrieve names of extended device statistics
     432                 :            :  *
     433                 :            :  * @param dev
     434                 :            :  *   Pointer to Ethernet device structure.
     435                 :            :  * @param[out] xstats_names
     436                 :            :  *   Buffer to insert names into.
     437                 :            :  * @param n
     438                 :            :  *   Number of names.
     439                 :            :  *
     440                 :            :  * @return
     441                 :            :  *   Number of xstats names.
     442                 :            :  */
     443                 :            : int
     444                 :          0 : mlx5_xstats_get_names(struct rte_eth_dev *dev,
     445                 :            :                       struct rte_eth_xstat_name *xstats_names, unsigned int n)
     446                 :            : {
     447                 :            :         unsigned int i;
     448                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     449                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     450                 :          0 :         unsigned int mlx5_xstats_n = xstats_ctrl->mlx5_stats_n;
     451                 :          0 :         unsigned int n_used = mlx5_rq_xstats_get_names(dev, xstats_names);
     452                 :            : 
     453         [ #  # ]:          0 :         if (n >= mlx5_xstats_n && xstats_names) {
     454         [ #  # ]:          0 :                 for (i = 0; i != mlx5_xstats_n; ++i) {
     455                 :          0 :                         rte_strscpy(xstats_names[i + n_used].name,
     456                 :          0 :                                 xstats_ctrl->info[i].dpdk_name,
     457                 :            :                                 RTE_ETH_XSTATS_NAME_SIZE);
     458                 :          0 :                         xstats_names[i + n_used].name[RTE_ETH_XSTATS_NAME_SIZE - 1] = 0;
     459                 :            :                 }
     460                 :            :         }
     461                 :          0 :         mlx5_xstats_n = mlx5_txpp_xstats_get_names(dev, xstats_names,
     462                 :            :                                                    n, mlx5_xstats_n + n_used);
     463                 :          0 :         return mlx5_xstats_n;
     464                 :            : }
     465                 :            : 
     466                 :            : static struct mlx5_stat_counter_ctrl*
     467                 :          0 : mlx5_rxq_get_counter_by_id(struct rte_eth_dev *dev, uint64_t id, uint64_t *rq_id)
     468                 :            : {
     469                 :          0 :         uint16_t n_stats_rq = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
     470                 :            : 
     471         [ #  # ]:          0 :         for (int i = 0; (i != n_stats_rq); i++) {
     472                 :          0 :                 struct mlx5_rxq_data *rxq_data = mlx5_rxq_data_get(dev, i);
     473   [ #  #  #  # ]:          0 :                 if (rxq_data == NULL || rxq_data->stats.oobs.id == -1)
     474                 :          0 :                         continue;
     475                 :            : 
     476         [ #  # ]:          0 :                 if ((uint64_t)rxq_data->stats.oobs.id == id) {
     477                 :          0 :                         *rq_id = rxq_data->idx;
     478                 :          0 :                         return &rxq_data->stats.oobs.ctrl;
     479                 :            :                 }
     480                 :            :         }
     481                 :            : 
     482                 :            :         return NULL;
     483                 :            : }
     484                 :            : 
     485                 :            : /**
     486                 :            :  * Callback to enable an xstat counter of the given id.
     487                 :            :  *
     488                 :            :  * @param dev
     489                 :            :  *   Pointer to Ethernet device structure.
     490                 :            :  * @param id
     491                 :            :  *   The ID of the counter to enable
     492                 :            :  *
     493                 :            :  * @return
     494                 :            :  *   1 xstat is enabled, 0 if xstat is disabled,
     495                 :            :  *   -ENOTSUP if enabling/disabling is not implemented and -EINVAL if xstat id is invalid.
     496                 :            :  */
     497                 :            : int
     498                 :          0 : mlx5_xstats_enable(struct rte_eth_dev *dev, uint64_t id)
     499                 :            : {
     500                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     501                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     502                 :            :         struct mlx5_stat_counter_ctrl *counter_ctrl = NULL;
     503                 :          0 :         uint16_t n_stats_rq = mlx5_rq_xstats_get(dev, NULL);
     504                 :            : 
     505         [ #  # ]:          0 :         if (id < n_stats_rq)
     506                 :          0 :                 counter_ctrl = mlx5_rxq_get_counter_by_id(dev, id, &id);
     507                 :            :         else
     508                 :          0 :                 counter_ctrl = &xstats_ctrl->info[id - n_stats_rq].ctrl;
     509                 :            : 
     510         [ #  # ]:          0 :         if (counter_ctrl == NULL)
     511                 :            :                 return -EINVAL;
     512                 :            : 
     513         [ #  # ]:          0 :         if (counter_ctrl->enable == NULL)
     514                 :            :                 return -ENOTSUP;
     515                 :            : 
     516                 :          0 :         counter_ctrl->enabled = counter_ctrl->enable(dev, id) == 0 ? 1 : 0;
     517                 :          0 :         return counter_ctrl->enabled;
     518                 :            : }
     519                 :            : 
     520                 :            : /**
     521                 :            :  * Callback to disable an xstat counter of the given id.
     522                 :            :  *
     523                 :            :  * @param dev
     524                 :            :  *   Pointer to Ethernet device structure.
     525                 :            :  * @param id
     526                 :            :  *   The ID of the counter to enable
     527                 :            :  *
     528                 :            :  * @return
     529                 :            :  *   1 if xstat is disabled, 0 xstat is enabled,
     530                 :            :  *   -ENOTSUP if enabling/disabling is not implemented and -EINVAL if xstat id is invalid.
     531                 :            :  */
     532                 :            : int
     533                 :          0 : mlx5_xstats_disable(struct rte_eth_dev *dev, uint64_t id)
     534                 :            : {
     535                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     536                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     537                 :            :         struct mlx5_stat_counter_ctrl *counter_ctrl = NULL;
     538                 :            : 
     539                 :          0 :         uint16_t n_stats_rq = mlx5_rq_xstats_get(dev, NULL);
     540         [ #  # ]:          0 :         if (id < n_stats_rq)
     541                 :          0 :                 counter_ctrl = mlx5_rxq_get_counter_by_id(dev, id, &id);
     542                 :            :         else
     543                 :          0 :                 counter_ctrl = &xstats_ctrl->info[id - n_stats_rq].ctrl;
     544                 :            : 
     545         [ #  # ]:          0 :         if (counter_ctrl == NULL)
     546                 :            :                 return -EINVAL;
     547                 :            : 
     548         [ #  # ]:          0 :         if (counter_ctrl->disable == NULL)
     549                 :            :                 return -ENOTSUP;
     550                 :            : 
     551                 :          0 :         counter_ctrl->enabled = counter_ctrl->disable(dev, id) == 0 ? 0 : 1;
     552                 :          0 :         return counter_ctrl->enabled;
     553                 :            : }
     554                 :            : 
     555                 :            : /**
     556                 :            :  * Query the state of the xstat counter.
     557                 :            :  *
     558                 :            :  * @param dev
     559                 :            :  *   Pointer to Ethernet device structure.
     560                 :            :  * @param id
     561                 :            :  *   The ID of the counter to enable
     562                 :            :  *
     563                 :            :  * @return
     564                 :            :  *   1 if xstat is disabled, 0 xstat is enabled,
     565                 :            :  *   -ENOTSUP if enabling/disabling is not implemented and -EINVAL if xstat id is invalid.
     566                 :            :  */
     567                 :            : int
     568                 :          0 : mlx5_xstats_query_state(struct rte_eth_dev *dev, uint64_t id)
     569                 :            : {
     570                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     571                 :            :         struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
     572                 :            :         struct mlx5_stat_counter_ctrl *counter_ctrl = NULL;
     573                 :            : 
     574                 :          0 :         uint16_t n_stats_rq = mlx5_rq_xstats_get(dev, NULL);
     575         [ #  # ]:          0 :         if (id < n_stats_rq)
     576                 :          0 :                 counter_ctrl = mlx5_rxq_get_counter_by_id(dev, id, &id);
     577                 :            :         else
     578                 :          0 :                 counter_ctrl = &xstats_ctrl->info[id - n_stats_rq].ctrl;
     579                 :            : 
     580         [ #  # ]:          0 :         if (counter_ctrl == NULL)
     581                 :            :                 return -EINVAL;
     582                 :            : 
     583         [ #  # ]:          0 :         if (counter_ctrl->disable == NULL)
     584                 :            :                 return -ENOTSUP;
     585                 :            : 
     586                 :          0 :         return counter_ctrl->enabled;
     587                 :            : }

Generated by: LCOV version 1.14