LCOV - code coverage report
Current view: top level - plugins/perfmon/intel - uncore.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 72 83 86.7 %
Date: 2023-07-05 22:20:52 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2020 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : 
      16             : #include <vnet/vnet.h>
      17             : #include <vppinfra/linux/sysfs.h>
      18             : #include <perfmon/perfmon.h>
      19             : #include <perfmon/intel/core.h>
      20             : #include <perfmon/intel/uncore.h>
      21             : 
      22         559 : VLIB_REGISTER_LOG_CLASS (if_intel_uncore_log, static) = {
      23             :   .class_name = "perfmon",
      24             :   .subclass_name = "intel-uncore",
      25             : };
      26             : 
      27             : #define log_debug(fmt, ...)                                                   \
      28             :   vlib_log_debug (if_intel_uncore_log.class, fmt, __VA_ARGS__)
      29             : #define log_warn(fmt, ...)                                                    \
      30             :   vlib_log_warn (if_intel_uncore_log.class, fmt, __VA_ARGS__)
      31             : #define log_err(fmt, ...)                                                     \
      32             :   vlib_log_err (if_intel_uncore_log.class, fmt, __VA_ARGS__)
      33             : 
      34             : #define PERF_INTEL_CODE(event, umask, edge, any, inv, cmask)                  \
      35             :   ((event) | (umask) << 8 | (edge) << 18 | (any) << 21 | (inv) << 23 |        \
      36             :    (cmask) << 24)
      37             : 
      38             : static intel_uncore_unit_type_names_t uncore_unit_names[] = {
      39             :   { INTEL_UNCORE_UNIT_IIO,
      40             :     PERFMON_STRINGS ("PCIe0", "PCIe1", "MCP", "PCIe2", "PCIe3", "CBDMA/DMI") }
      41             : };
      42             : 
      43             : static perfmon_event_t intel_uncore_events[] = {
      44             : #define _(unit, event, umask, ch_mask, fc_mask, n, suffix, desc)              \
      45             :   [INTEL_UNCORE_E_##unit##_##n##_##suffix] = {                                \
      46             :     .config =                                                                 \
      47             :       (event) | (umask) << 8 | (u64) (ch_mask) << 36 | (u64) (fc_mask) << 48, \
      48             :     .name = #n "." #suffix,                                                   \
      49             :     .description = desc,                                                      \
      50             :     .type_from_instance = 1,                                                  \
      51             :     .instance_type = INTEL_UNCORE_UNIT_##unit,                                \
      52             :     .implemented = 1,                                                         \
      53             :   },
      54             : 
      55             :   foreach_intel_uncore_event
      56             : #undef _
      57             : };
      58             : 
      59             : static int
      60       35217 : intel_uncore_instance_name_cmp (void *v1, void *v2)
      61             : {
      62       35217 :   perfmon_instance_t *i1 = v1;
      63       35217 :   perfmon_instance_t *i2 = v2;
      64       35217 :   return strcmp (i1->name, i2->name);
      65             : }
      66             : 
      67             : static u8 *
      68       16770 : format_instance_name (intel_uncore_unit_type_t u, char *unit_fmt, u8 socket_id,
      69             :                       u8 ubox)
      70             : {
      71       16770 :   u8 *s = 0;
      72             : 
      73             :   /* uncore ubox may have specific names */
      74       26832 :   for (u8 i = 0; i < ARRAY_LEN (uncore_unit_names); i++)
      75             :     {
      76       16770 :       intel_uncore_unit_type_names_t *n = &uncore_unit_names[i];
      77             : 
      78       16770 :       if (n->unit_type == u)
      79             :         {
      80        6708 :           u8 *fmt = 0;
      81             : 
      82        6708 :           fmt = format (0, "%s (%s)%c", unit_fmt, (n->unit_names[ubox]), 0);
      83        6708 :           s = format (0, (char *) fmt, socket_id, ubox);
      84        6708 :           vec_free (fmt);
      85             : 
      86        6708 :           return s;
      87             :         }
      88             :     }
      89             : 
      90       10062 :   return format (0, unit_fmt, socket_id, ubox);
      91             : }
      92             : 
      93             : static void
      94        1677 : intel_uncore_add_unit (perfmon_source_t *src, intel_uncore_unit_type_t u,
      95             :                        char *name, char *type_str, char *fmt,
      96             :                        int *socket_by_cpu_id)
      97             : {
      98             :   static char *base_path = "/sys/bus/event_source/devices/uncore";
      99             :   clib_error_t *err;
     100        1677 :   clib_bitmap_t *cpumask = 0;
     101             :   perfmon_instance_t *in;
     102             :   perfmon_instance_type_t *it;
     103        1677 :   u8 *s = 0;
     104        1677 :   int i = 0, j;
     105             :   u32 perf_type;
     106             : 
     107        1677 :   vec_validate (src->instances_by_type, u);
     108        1677 :   it = vec_elt_at_index (src->instances_by_type, u);
     109        1677 :   it->name = type_str;
     110             : 
     111             :   while (1)
     112             :     {
     113       10062 :       s = format (s, "%s_%s_%u/type%c", base_path, name, i, 0);
     114       10062 :       if ((err = clib_sysfs_read ((char *) s, "%u", &perf_type)))
     115        1677 :         break;
     116        8385 :       vec_reset_length (s);
     117             : 
     118        8385 :       s = format (s, "%s_%s_%u/cpumask%c", base_path, name, i, 0);
     119        8385 :       if ((err = clib_sysfs_read ((char *) s, "%U", unformat_bitmap_list,
     120             :                                   &cpumask)))
     121           0 :         break;
     122        8385 :       vec_reset_length (s);
     123             : 
     124       25155 :       clib_bitmap_foreach (j, cpumask)
     125             :         {
     126       16770 :           vec_add2 (it->instances, in, 1);
     127       16770 :           in->type = perf_type;
     128       16770 :           in->cpu = j;
     129       16770 :           in->pid = -1;
     130       33540 :           in->name =
     131       16770 :             (char *) format_instance_name (u, fmt, socket_by_cpu_id[j], i);
     132       16770 :           vec_terminate_c_string (in->name);
     133       16770 :           log_debug ("found %s %s", type_str, in->name);
     134             :         }
     135        8385 :       i++;
     136             :     };
     137        1677 :   clib_error_free (err);
     138        1677 :   clib_bitmap_free (cpumask);
     139        1677 :   vec_free (s);
     140        1677 : }
     141             : 
     142             : static clib_error_t *
     143         559 : intel_uncore_init (vlib_main_t *vm, perfmon_source_t *src)
     144             : {
     145         559 :   clib_error_t *err = 0;
     146         559 :   clib_bitmap_t *node_bitmap = 0, *cpumask = 0;
     147         559 :   int *numa_by_cpu_id = 0;
     148             :   u32 i, j;
     149         559 :   u8 *s = 0;
     150             : 
     151         559 :   if ((err = clib_sysfs_read ("/sys/devices/system/node/online", "%U",
     152             :                               unformat_bitmap_list, &node_bitmap)))
     153             :     {
     154           0 :       clib_error_free (err);
     155           0 :       return clib_error_return (0, "failed to discover numa topology");
     156             :     }
     157             : 
     158        1677 :   clib_bitmap_foreach (i, node_bitmap)
     159             :     {
     160        1118 :       s = format (s, "/sys/devices/system/node/node%u/cpulist%c", i, 0);
     161        1118 :       if ((err = clib_sysfs_read ((char *) s, "%U", unformat_bitmap_list,
     162             :                                   &cpumask)))
     163             :         {
     164           0 :           clib_error_free (err);
     165           0 :           err = clib_error_return (0, "failed to discover numa topology");
     166           0 :           goto done;
     167             :         }
     168             : 
     169        1118 :       if (!cpumask)
     170             :         {
     171           0 :           clib_error_free (err);
     172           0 :           err = clib_error_return (
     173             :             0, "while discovering numa topology: cpumask unexpectedly NULL");
     174           0 :           goto done;
     175             :         }
     176             : 
     177       63726 :       clib_bitmap_foreach (j, cpumask)
     178             :         {
     179      125216 :           vec_validate_init_empty (numa_by_cpu_id, j, -1);
     180       62608 :           numa_by_cpu_id[j] = i;
     181             :         }
     182        1118 :       clib_bitmap_free (cpumask);
     183        1118 :       vec_reset_length (s);
     184             :     }
     185             : 
     186             : #define _(t, n, name, fmt)                                                    \
     187             :   intel_uncore_add_unit (src, INTEL_UNCORE_UNIT_##t, n, name, fmt,            \
     188             :                          numa_by_cpu_id);
     189         559 :   foreach_intel_uncore_unit_type;
     190             : #undef _
     191             : 
     192        2236 :   for (i = 0, j = 0; i < vec_len (src->instances_by_type); i++)
     193             :     {
     194             :       perfmon_instance_type_t *it;
     195             : 
     196        1677 :       it = vec_elt_at_index (src->instances_by_type, i);
     197        1677 :       vec_sort_with_function (it->instances, intel_uncore_instance_name_cmp);
     198        1677 :       j += vec_len (it->instances);
     199             :     }
     200             : 
     201         559 :   if (j == 0)
     202             :     {
     203           0 :       vec_free (src->instances_by_type);
     204           0 :       return clib_error_return (0, "no uncore units found");
     205             :     }
     206             : 
     207         559 : done:
     208         559 :   vec_free (s);
     209         559 :   vec_free (cpumask);
     210         559 :   vec_free (node_bitmap);
     211         559 :   vec_free (numa_by_cpu_id);
     212         559 :   return err;
     213             : }
     214             : 
     215             : format_function_t format_intel_core_config;
     216             : 
     217         559 : PERFMON_REGISTER_SOURCE (intel_uncore) = {
     218             :   .name = "intel-uncore",
     219             :   .description = "intel uncore events",
     220             :   .events = intel_uncore_events,
     221             :   .n_events = INTEL_UNCORE_N_EVENTS,
     222             :   .init_fn = intel_uncore_init,
     223             :   .format_config = format_intel_core_config,
     224             :   .bundle_support = intel_bundle_supported,
     225             : };

Generated by: LCOV version 1.14