LCOV - code coverage report
Current view: top level - drivers/event/dsw - dsw_xstats.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 88 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 23 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 38 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018-2019 Ericsson AB
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "dsw_evdev.h"
       6                 :            : 
       7                 :            : #include <stdbool.h>
       8                 :            : #include <string.h>
       9                 :            : 
      10                 :            : #include <rte_debug.h>
      11                 :            : 
      12                 :            : /* The high bits in the xstats id is used to store an additional
      13                 :            :  * parameter (beyond the queue or port id already in the xstats
      14                 :            :  * interface).
      15                 :            :  */
      16                 :            : #define DSW_XSTATS_ID_PARAM_BITS (8)
      17                 :            : #define DSW_XSTATS_ID_STAT_BITS                                 \
      18                 :            :         (sizeof(uint64_t)*CHAR_BIT - DSW_XSTATS_ID_PARAM_BITS)
      19                 :            : #define DSW_XSTATS_ID_STAT_MASK ((UINT64_C(1) << DSW_XSTATS_ID_STAT_BITS) - 1)
      20                 :            : 
      21                 :            : #define DSW_XSTATS_ID_GET_PARAM(id)             \
      22                 :            :         ((id)>>DSW_XSTATS_ID_STAT_BITS)
      23                 :            : 
      24                 :            : #define DSW_XSTATS_ID_GET_STAT(id)              \
      25                 :            :         ((id) & DSW_XSTATS_ID_STAT_MASK)
      26                 :            : 
      27                 :            : #define DSW_XSTATS_ID_CREATE(id, param_value)                   \
      28                 :            :         ((((uint64_t)param_value) << DSW_XSTATS_ID_STAT_BITS) | id)
      29                 :            : 
      30                 :            : typedef
      31                 :            : uint64_t (*dsw_xstats_dev_get_value_fn)(struct dsw_evdev *dsw);
      32                 :            : 
      33                 :            : struct dsw_xstat_dev {
      34                 :            :         const char *name;
      35                 :            :         dsw_xstats_dev_get_value_fn get_value_fn;
      36                 :            : };
      37                 :            : 
      38                 :            : typedef
      39                 :            : uint64_t (*dsw_xstats_port_get_value_fn)(struct dsw_evdev *dsw,
      40                 :            :                                          uint8_t port_id, uint8_t queue_id);
      41                 :            : 
      42                 :            : struct dsw_xstats_port {
      43                 :            :         const char *name_fmt;
      44                 :            :         dsw_xstats_port_get_value_fn get_value_fn;
      45                 :            :         bool per_queue;
      46                 :            : };
      47                 :            : 
      48                 :            : static uint64_t
      49                 :          0 : dsw_xstats_dev_credits_on_loan(struct dsw_evdev *dsw)
      50                 :            : {
      51                 :          0 :         return rte_atomic_load_explicit(&dsw->credits_on_loan, rte_memory_order_relaxed);
      52                 :            : }
      53                 :            : 
      54                 :            : static struct dsw_xstat_dev dsw_dev_xstats[] = {
      55                 :            :         { "dev_credits_on_loan", dsw_xstats_dev_credits_on_loan }
      56                 :            : };
      57                 :            : 
      58                 :            : #define DSW_GEN_PORT_ACCESS_FN(_variable)                               \
      59                 :            :         static uint64_t                                                 \
      60                 :            :         dsw_xstats_port_get_ ## _variable(struct dsw_evdev *dsw,        \
      61                 :            :                                           uint8_t port_id,              \
      62                 :            :                                           uint8_t queue_id __rte_unused) \
      63                 :            :         {                                                               \
      64                 :            :                 return dsw->ports[port_id]._variable;                        \
      65                 :            :         }
      66                 :            : 
      67                 :          0 : DSW_GEN_PORT_ACCESS_FN(new_enqueued)
      68                 :          0 : DSW_GEN_PORT_ACCESS_FN(forward_enqueued)
      69                 :          0 : DSW_GEN_PORT_ACCESS_FN(release_enqueued)
      70                 :            : 
      71                 :            : static uint64_t
      72                 :          0 : dsw_xstats_port_get_queue_enqueued(struct dsw_evdev *dsw, uint8_t port_id,
      73                 :            :                                    uint8_t queue_id)
      74                 :            : {
      75                 :          0 :         return dsw->ports[port_id].queue_enqueued[queue_id];
      76                 :            : }
      77                 :            : 
      78                 :          0 : DSW_GEN_PORT_ACCESS_FN(dequeued)
      79                 :            : 
      80                 :            : static uint64_t
      81                 :          0 : dsw_xstats_port_get_queue_dequeued(struct dsw_evdev *dsw, uint8_t port_id,
      82                 :            :                                    uint8_t queue_id)
      83                 :            : {
      84                 :          0 :         return dsw->ports[port_id].queue_dequeued[queue_id];
      85                 :            : }
      86                 :            : 
      87                 :          0 : DSW_GEN_PORT_ACCESS_FN(emigrations)
      88                 :          0 : DSW_GEN_PORT_ACCESS_FN(immigrations)
      89                 :            : 
      90                 :            : static uint64_t
      91                 :          0 : dsw_xstats_port_get_migration_latency(struct dsw_evdev *dsw, uint8_t port_id,
      92                 :            :                                       uint8_t queue_id __rte_unused)
      93                 :            : {
      94                 :          0 :         uint64_t total_latency = dsw->ports[port_id].emigration_latency;
      95                 :          0 :         uint64_t num_emigrations = dsw->ports[port_id].emigrations;
      96                 :            : 
      97         [ #  # ]:          0 :         return num_emigrations > 0 ? total_latency / num_emigrations : 0;
      98                 :            : }
      99                 :            : 
     100                 :            : static uint64_t
     101                 :          0 : dsw_xstats_port_get_event_proc_latency(struct dsw_evdev *dsw, uint8_t port_id,
     102                 :            :                                        uint8_t queue_id __rte_unused)
     103                 :            : {
     104                 :          0 :         uint64_t total_busy_cycles =
     105                 :          0 :                 dsw->ports[port_id].total_busy_cycles;
     106                 :          0 :         uint64_t dequeued =
     107                 :            :                 dsw->ports[port_id].dequeued;
     108                 :            : 
     109         [ #  # ]:          0 :         return dequeued > 0 ? total_busy_cycles / dequeued : 0;
     110                 :            : }
     111                 :            : 
     112                 :            : static uint64_t
     113                 :          0 : dsw_xstats_port_get_busy_cycles(struct dsw_evdev *dsw, uint8_t port_id,
     114                 :            :                                 uint8_t queue_id __rte_unused)
     115                 :            : {
     116                 :          0 :         return dsw->ports[port_id].total_busy_cycles;
     117                 :            : }
     118                 :            : 
     119                 :          0 : DSW_GEN_PORT_ACCESS_FN(inflight_credits)
     120                 :            : 
     121                 :          0 : DSW_GEN_PORT_ACCESS_FN(pending_releases)
     122                 :            : 
     123                 :            : static uint64_t
     124                 :          0 : dsw_xstats_port_get_load(struct dsw_evdev *dsw, uint8_t port_id,
     125                 :            :                          uint8_t queue_id __rte_unused)
     126                 :            : {
     127                 :            :         int16_t load;
     128                 :            : 
     129                 :          0 :         load = rte_atomic_load_explicit(&dsw->ports[port_id].load, rte_memory_order_relaxed);
     130                 :            : 
     131                 :          0 :         return DSW_LOAD_TO_PERCENT(load);
     132                 :            : }
     133                 :            : 
     134                 :          0 : DSW_GEN_PORT_ACCESS_FN(last_bg)
     135                 :            : 
     136                 :            : static struct dsw_xstats_port dsw_port_xstats[] = {
     137                 :            :         { "port_%u_new_enqueued", dsw_xstats_port_get_new_enqueued,
     138                 :            :           false },
     139                 :            :         { "port_%u_forward_enqueued", dsw_xstats_port_get_forward_enqueued,
     140                 :            :           false },
     141                 :            :         { "port_%u_release_enqueued", dsw_xstats_port_get_release_enqueued,
     142                 :            :           false },
     143                 :            :         { "port_%u_queue_%u_enqueued", dsw_xstats_port_get_queue_enqueued,
     144                 :            :           true },
     145                 :            :         { "port_%u_dequeued", dsw_xstats_port_get_dequeued,
     146                 :            :           false },
     147                 :            :         { "port_%u_queue_%u_dequeued", dsw_xstats_port_get_queue_dequeued,
     148                 :            :           true },
     149                 :            :         { "port_%u_emigrations", dsw_xstats_port_get_emigrations,
     150                 :            :           false },
     151                 :            :         { "port_%u_migration_latency", dsw_xstats_port_get_migration_latency,
     152                 :            :           false },
     153                 :            :         { "port_%u_immigrations", dsw_xstats_port_get_immigrations,
     154                 :            :           false },
     155                 :            :         { "port_%u_event_proc_latency", dsw_xstats_port_get_event_proc_latency,
     156                 :            :           false },
     157                 :            :         { "port_%u_busy_cycles", dsw_xstats_port_get_busy_cycles,
     158                 :            :           false },
     159                 :            :         { "port_%u_inflight_credits", dsw_xstats_port_get_inflight_credits,
     160                 :            :           false },
     161                 :            :         { "port_%u_pending_releases", dsw_xstats_port_get_pending_releases,
     162                 :            :           false },
     163                 :            :         { "port_%u_load", dsw_xstats_port_get_load,
     164                 :            :           false },
     165                 :            :         { "port_%u_last_bg", dsw_xstats_port_get_last_bg,
     166                 :            :           false }
     167                 :            : };
     168                 :            : 
     169                 :            : typedef
     170                 :            : void (*dsw_xstats_foreach_fn)(const char *xstats_name,
     171                 :            :                               enum rte_event_dev_xstats_mode mode,
     172                 :            :                               uint8_t queue_port_id, uint64_t xstats_id,
     173                 :            :                               void *data);
     174                 :            : 
     175                 :            : static void
     176                 :            : dsw_xstats_dev_foreach(dsw_xstats_foreach_fn fn, void *fn_data)
     177                 :            : {
     178                 :            :         unsigned int i;
     179                 :            : 
     180                 :            :         for (i = 0; i < RTE_DIM(dsw_dev_xstats); i++)
     181                 :          0 :                 fn(dsw_dev_xstats[i].name, RTE_EVENT_DEV_XSTATS_DEVICE, 0,
     182                 :            :                    i, fn_data);
     183                 :            : }
     184                 :            : 
     185                 :            : static void
     186                 :          0 : dsw_xstats_port_foreach(struct dsw_evdev *dsw, uint8_t port_id,
     187                 :            :                         dsw_xstats_foreach_fn fn, void *fn_data)
     188                 :            : {
     189                 :            :         uint8_t queue_id;
     190                 :            :         unsigned int stat_idx;
     191                 :            : 
     192                 :          0 :         for (stat_idx = 0, queue_id = 0;
     193         [ #  # ]:          0 :              stat_idx < RTE_DIM(dsw_port_xstats);) {
     194                 :            :                 struct dsw_xstats_port *xstat = &dsw_port_xstats[stat_idx];
     195                 :            :                 char xstats_name[RTE_EVENT_DEV_XSTATS_NAME_SIZE];
     196                 :            :                 uint64_t xstats_id;
     197                 :            : 
     198         [ #  # ]:          0 :                 if (xstat->per_queue) {
     199                 :          0 :                         xstats_id = DSW_XSTATS_ID_CREATE(stat_idx, queue_id);
     200                 :          0 :                         snprintf(xstats_name, sizeof(xstats_name),
     201                 :            :                                  dsw_port_xstats[stat_idx].name_fmt, port_id,
     202                 :            :                                  queue_id);
     203                 :          0 :                         queue_id++;
     204                 :            :                 } else {
     205                 :          0 :                         xstats_id = stat_idx;
     206                 :          0 :                         snprintf(xstats_name, sizeof(xstats_name),
     207                 :            :                                  dsw_port_xstats[stat_idx].name_fmt, port_id);
     208                 :            :                 }
     209                 :            : 
     210                 :          0 :                 fn(xstats_name, RTE_EVENT_DEV_XSTATS_PORT, port_id,
     211                 :            :                    xstats_id, fn_data);
     212                 :            : 
     213   [ #  #  #  # ]:          0 :                 if (!(xstat->per_queue && queue_id < dsw->num_queues)) {
     214                 :          0 :                         stat_idx++;
     215                 :            :                         queue_id = 0;
     216                 :            :                 }
     217                 :            :         }
     218                 :          0 : }
     219                 :            : 
     220                 :            : struct store_ctx {
     221                 :            :         struct rte_event_dev_xstats_name *names;
     222                 :            :         uint64_t *ids;
     223                 :            :         unsigned int count;
     224                 :            :         unsigned int capacity;
     225                 :            : };
     226                 :            : 
     227                 :            : static void
     228                 :          0 : dsw_xstats_store_stat(const char *xstats_name,
     229                 :            :                       enum rte_event_dev_xstats_mode mode,
     230                 :            :                       uint8_t queue_port_id, uint64_t xstats_id,
     231                 :            :                       void *data)
     232                 :            : {
     233                 :            :         struct store_ctx *ctx = data;
     234                 :            : 
     235                 :            :         RTE_SET_USED(mode);
     236                 :            :         RTE_SET_USED(queue_port_id);
     237                 :            : 
     238         [ #  # ]:          0 :         if (ctx->count < ctx->capacity) {
     239                 :          0 :                 strcpy(ctx->names[ctx->count].name, xstats_name);
     240                 :          0 :                 ctx->ids[ctx->count] = xstats_id;
     241                 :            :         }
     242                 :            : 
     243                 :          0 :         ctx->count++;
     244                 :          0 : }
     245                 :            : 
     246                 :            : int
     247   [ #  #  #  # ]:          0 : dsw_xstats_get_names(const struct rte_eventdev *dev,
     248                 :            :                      enum rte_event_dev_xstats_mode mode,
     249                 :            :                      uint8_t queue_port_id,
     250                 :            :                      struct rte_event_dev_xstats_name *xstats_names,
     251                 :            :                      uint64_t *ids, unsigned int capacity)
     252                 :            : {
     253                 :            :         struct dsw_evdev *dsw = dsw_pmd_priv(dev);
     254                 :            : 
     255                 :          0 :         struct store_ctx ctx = {
     256                 :            :                 .names = xstats_names,
     257                 :            :                 .ids = ids,
     258                 :            :                 .capacity = capacity
     259                 :            :         };
     260                 :            : 
     261   [ #  #  #  # ]:          0 :         switch (mode) {
     262                 :            :         case RTE_EVENT_DEV_XSTATS_DEVICE:
     263                 :            :                 dsw_xstats_dev_foreach(dsw_xstats_store_stat, &ctx);
     264                 :          0 :                 return ctx.count;
     265                 :          0 :         case RTE_EVENT_DEV_XSTATS_PORT:
     266                 :          0 :                 dsw_xstats_port_foreach(dsw, queue_port_id,
     267                 :            :                                         dsw_xstats_store_stat, &ctx);
     268                 :          0 :                 return ctx.count;
     269                 :            :         case RTE_EVENT_DEV_XSTATS_QUEUE:
     270                 :            :                 return 0;
     271                 :          0 :         default:
     272                 :            :                 RTE_ASSERT(false);
     273                 :          0 :                 return -1;
     274                 :            :         }
     275                 :            : }
     276                 :            : 
     277                 :            : static int
     278                 :            : dsw_xstats_dev_get(const struct rte_eventdev *dev,
     279                 :            :                    const uint64_t ids[], uint64_t values[], unsigned int n)
     280                 :            : {
     281                 :            :         struct dsw_evdev *dsw = dsw_pmd_priv(dev);
     282                 :            :         unsigned int i;
     283                 :            : 
     284         [ #  # ]:          0 :         for (i = 0; i < n; i++) {
     285                 :          0 :                 uint64_t id = ids[i];
     286                 :            :                 struct dsw_xstat_dev *xstat = &dsw_dev_xstats[id];
     287                 :          0 :                 values[i] = xstat->get_value_fn(dsw);
     288                 :            :         }
     289                 :          0 :         return n;
     290                 :            : }
     291                 :            : 
     292                 :            : static int
     293                 :          0 : dsw_xstats_port_get(const struct rte_eventdev *dev, uint8_t port_id,
     294                 :            :                     const uint64_t ids[], uint64_t values[], unsigned int n)
     295                 :            : {
     296                 :            :         struct dsw_evdev *dsw = dsw_pmd_priv(dev);
     297                 :            :         unsigned int i;
     298                 :            : 
     299         [ #  # ]:          0 :         for (i = 0; i < n; i++) {
     300                 :          0 :                 uint64_t id = ids[i];
     301                 :          0 :                 unsigned int stat_idx = DSW_XSTATS_ID_GET_STAT(id);
     302                 :            :                 struct dsw_xstats_port *xstat = &dsw_port_xstats[stat_idx];
     303                 :            :                 uint8_t queue_id = 0;
     304                 :            : 
     305         [ #  # ]:          0 :                 if (xstat->per_queue)
     306                 :          0 :                         queue_id = DSW_XSTATS_ID_GET_PARAM(id);
     307                 :            : 
     308                 :          0 :                 values[i] = xstat->get_value_fn(dsw, port_id, queue_id);
     309                 :            :         }
     310                 :          0 :         return n;
     311                 :            : }
     312                 :            : 
     313                 :            : int
     314                 :          0 : dsw_xstats_get(const struct rte_eventdev *dev,
     315                 :            :                enum rte_event_dev_xstats_mode mode, uint8_t queue_port_id,
     316                 :            :                const uint64_t ids[], uint64_t values[], unsigned int n)
     317                 :            : {
     318   [ #  #  #  # ]:          0 :         switch (mode) {
     319                 :            :         case RTE_EVENT_DEV_XSTATS_DEVICE:
     320                 :          0 :                 return dsw_xstats_dev_get(dev, ids, values, n);
     321                 :          0 :         case RTE_EVENT_DEV_XSTATS_PORT:
     322                 :          0 :                 return dsw_xstats_port_get(dev, queue_port_id, ids, values, n);
     323                 :            :         case RTE_EVENT_DEV_XSTATS_QUEUE:
     324                 :            :                 return 0;
     325                 :          0 :         default:
     326                 :            :                 RTE_ASSERT(false);
     327                 :          0 :                 return -1;
     328                 :            :         }
     329                 :            :         return 0;
     330                 :            : }
     331                 :            : 
     332                 :            : struct find_ctx {
     333                 :            :         const struct rte_eventdev *dev;
     334                 :            :         const char *name;
     335                 :            :         uint64_t *id;
     336                 :            :         uint64_t value;
     337                 :            : };
     338                 :            : 
     339                 :            : static void
     340                 :          0 : dsw_xstats_find_stat(const char *xstats_name,
     341                 :            :                      enum rte_event_dev_xstats_mode mode,
     342                 :            :                      uint8_t queue_port_id, uint64_t xstats_id,
     343                 :            :                      void *data)
     344                 :            : {
     345                 :            :         struct find_ctx *ctx = data;
     346                 :            : 
     347         [ #  # ]:          0 :         if (strcmp(ctx->name, xstats_name) == 0) {
     348         [ #  # ]:          0 :                 if (ctx->id != NULL)
     349                 :          0 :                         *ctx->id = xstats_id;
     350                 :          0 :                 dsw_xstats_get(ctx->dev, mode, queue_port_id, &xstats_id,
     351                 :            :                                &ctx->value, 1);
     352                 :            :         }
     353                 :          0 : }
     354                 :            : 
     355                 :            : uint64_t
     356                 :          0 : dsw_xstats_get_by_name(const struct rte_eventdev *dev, const char *name,
     357                 :            :                        uint64_t *id)
     358                 :            : {
     359                 :            :         struct dsw_evdev *dsw = dsw_pmd_priv(dev);
     360                 :            :         uint16_t port_id;
     361                 :            : 
     362                 :          0 :         struct find_ctx ctx = {
     363                 :            :                 .dev = dev,
     364                 :            :                 .name = name,
     365                 :            :                 .id = id,
     366                 :            :                 .value = -EINVAL
     367                 :            :         };
     368                 :            : 
     369                 :            :         dsw_xstats_dev_foreach(dsw_xstats_find_stat, &ctx);
     370                 :            : 
     371         [ #  # ]:          0 :         for (port_id = 0; port_id < dsw->num_ports; port_id++)
     372                 :          0 :                 dsw_xstats_port_foreach(dsw, port_id, dsw_xstats_find_stat,
     373                 :            :                                         &ctx);
     374                 :            : 
     375                 :          0 :         return ctx.value;
     376                 :            : }

Generated by: LCOV version 1.14