FD.io VPP  v21.06
Vector Packet Processing
uncore.c
Go to the documentation of this file.
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 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 perfmon_event_t intel_uncore_events[] = {
39 #define _(unit, event, umask, n, suffix, desc) \
40  [INTEL_UNCORE_E_##unit##_##n##_##suffix] = { \
41  .config = (event) | (umask) << 8, \
42  .name = #n "." #suffix, \
43  .description = desc, \
44  .type_from_instance = 1, \
45  .instance_type = INTEL_UNCORE_UNIT_##unit, \
46  },
47 
49 #undef _
50 };
51 
52 static int
53 intel_uncore_instance_name_cmp (void *v1, void *v2)
54 {
55  perfmon_instance_t *i1 = v1;
56  perfmon_instance_t *i2 = v2;
57  return strcmp (i1->name, i2->name);
58 }
59 
60 static void
62  char *name, char *type_str, char *fmt,
63  int *socket_by_cpu_id)
64 {
65  static char *base_path = "/sys/bus/event_source/devices/uncore";
66  clib_error_t *err;
67  clib_bitmap_t *cpumask = 0;
70  u8 *s = 0;
71  int i = 0, j;
72  u32 perf_type;
73 
75  it = vec_elt_at_index (src->instances_by_type, u);
76  it->name = type_str;
77 
78  while (1)
79  {
80  s = format (s, "%s_%s_%u/type%c", base_path, name, i, 0);
81  if ((err = clib_sysfs_read ((char *) s, "%u", &perf_type)))
82  break;
83  vec_reset_length (s);
84 
85  s = format (s, "%s_%s_%u/cpumask%c", base_path, name, i, 0);
86  if ((err = clib_sysfs_read ((char *) s, "%U", unformat_bitmap_list,
87  &cpumask)))
88  break;
89  vec_reset_length (s);
90 
91  clib_bitmap_foreach (j, cpumask)
92  {
93  vec_add2 (it->instances, in, 1);
94  in->type = perf_type;
95  in->cpu = j;
96  in->pid = -1;
97  in->name = (char *) format (0, fmt, socket_by_cpu_id[j], i);
99  log_debug ("found %s %s", type_str, in->name);
100  }
101  i++;
102  };
103  clib_error_free (err);
104  clib_bitmap_free (cpumask);
105  vec_free (s);
106 }
107 
108 static clib_error_t *
110 {
111  clib_error_t *err = 0;
112  clib_bitmap_t *node_bitmap = 0, *cpumask = 0;
113  int *numa_by_cpu_id = 0;
114  u32 i, j;
115  u8 *s = 0;
116 
117  if ((err = clib_sysfs_read ("/sys/devices/system/node/has_cpu", "%U",
118  unformat_bitmap_list, &node_bitmap)))
119  {
120  clib_error_free (err);
121  return clib_error_return (0, "failed to discover numa topology");
122  }
123 
124  clib_bitmap_foreach (i, node_bitmap)
125  {
126  s = format (s, "/sys/devices/system/node/node%u/cpulist%c", i, 0);
127  if ((err = clib_sysfs_read ((char *) s, "%U", unformat_bitmap_list,
128  &cpumask)))
129  {
130  clib_error_free (err);
131  err = clib_error_return (0, "failed to discover numa topology");
132  goto done;
133  }
134 
135  clib_bitmap_foreach (j, cpumask)
136  {
137  vec_validate_init_empty (numa_by_cpu_id, j, -1);
138  numa_by_cpu_id[j] = i;
139  }
140  clib_bitmap_free (cpumask);
141  vec_reset_length (s);
142  }
143 
144 #define _(t, n, name, fmt) \
145  intel_uncore_add_unit (src, INTEL_UNCORE_UNIT_##t, n, name, fmt, \
146  numa_by_cpu_id);
148 #undef _
149 
150  for (i = 0, j = 0; i < vec_len (src->instances_by_type); i++)
151  {
153 
154  it = vec_elt_at_index (src->instances_by_type, i);
156  j += vec_len (it->instances);
157  }
158 
159  if (j == 0)
160  {
162  return clib_error_return (0, "no uncore units found");
163  }
164 
165 done:
166  vec_free (s);
167  vec_free (cpumask);
168  vec_free (node_bitmap);
169  vec_free (numa_by_cpu_id);
170  return err;
171 }
172 
174 
175 PERFMON_REGISTER_SOURCE (intel_uncore) = {
176  .name = "intel-uncore",
177  .description = "intel uncore events",
178  .events = intel_uncore_events,
179  .n_events = INTEL_UNCORE_N_EVENTS,
180  .init_fn = intel_uncore_init,
181  .format_config = format_intel_core_config,
182 };
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
#define foreach_intel_uncore_unit_type
Definition: uncore.h:19
#define foreach_intel_uncore_event
Definition: uncore.h:36
perfmon_instance_t * instances
Definition: perfmon.h:68
#define clib_bitmap_foreach(i, ai)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
#define vec_terminate_c_string(V)
(If necessary) NULL terminate a vector containing a c-string.
Definition: vec.h:1133
vl_api_address_t src
Definition: gre.api:54
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:645
string name[64]
Definition: fib.api:25
unsigned char u8
Definition: types.h:56
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static int intel_uncore_instance_name_cmp(void *v1, void *v2)
Definition: uncore.c:53
unsigned int u32
Definition: types.h:88
u8 *() format_function_t(u8 *s, va_list *args)
Definition: format.h:48
description fragment has unexpected format
Definition: map.api:433
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
Definition: error.h:99
PERFMON_REGISTER_SOURCE(intel_uncore)
static perfmon_event_t intel_uncore_events[]
Definition: uncore.c:38
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
int cJSON_bool fmt
Definition: cJSON.h:160
static clib_error_t * intel_uncore_init(vlib_main_t *vm, perfmon_source_t *src)
Definition: uncore.c:109
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
__clib_export uword unformat_bitmap_list(unformat_input_t *input, va_list *va)
unformat a list of bit ranges into a bitmap (eg "0-3,5-7,11" )
Definition: bitmap.c:55
format_function_t format_intel_core_config
Definition: uncore.c:173
perfmon_instance_type_t * instances_by_type
Definition: perfmon.h:88
#define clib_bitmap_free(v)
Free a bitmap.
Definition: bitmap.h:92
#define log_debug(fmt,...)
Definition: uncore.c:27
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1098
#define clib_error_free(e)
Definition: error.h:86
uword clib_bitmap_t
Definition: bitmap.h:50
__clib_export clib_error_t * clib_sysfs_read(char *file_name, char *fmt,...)
Definition: sysfs.c:51
static void intel_uncore_add_unit(perfmon_source_t *src, intel_uncore_unit_type_t u, char *name, char *type_str, char *fmt, int *socket_by_cpu_id)
Definition: uncore.c:61
save_rewrite_length must be aligned so that reass doesn t overwrite it
Definition: buffer.h:421
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:571
intel_uncore_unit_type_t
Definition: uncore.h:23
VLIB_REGISTER_LOG_CLASS(if_intel_uncore_log, static)