FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
perfmon.c
Go to the documentation of this file.
1 /*
2  * perfmon.c - skeleton vpp engine plug-in
3  *
4  * Copyright (c) <current-year> <your-organization>
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vnet/vnet.h>
19 #include <perfmon/perfmon.h>
20 #include <perfmon/perfmon_intel.h>
21 
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vpp/app/version.h>
25 #include <linux/limits.h>
26 
28 
29 void
31  perfmon_intel_pmc_event_t * e, int n_events)
32 {
35 
36  r.events = e;
37  r.models = m;
38  r.n_events = n_events;
39  r.n_models = n_models;
40 
41  vec_add1 (pm->perfmon_tables, r);
42 }
43 
44 static inline u32
45 get_cpuid (void)
46 {
47 #if defined(__x86_64__)
48  u32 cpuid;
49  asm volatile ("mov $1, %%eax; cpuid; mov %%eax, %0":"=r" (cpuid)::"%eax",
50  "%edx", "%ecx", "%rbx");
51  return cpuid;
52 #else
53  return 0;
54 #endif
55 }
56 
57 static int
59  u32 n_models, u8 model, u8 stepping)
60 {
61  u32 i;
62  for (i = 0; i < n_models; i++)
63  {
64  if (mt[i].model != model)
65  continue;
66 
67  if (mt[i].has_stepping)
68  {
69  if (mt[i].stepping != stepping)
70  continue;
71  }
72 
73  return 1;
74  }
75  return 0;
76 }
77 
80  u8 model, u8 stepping)
81 {
83 
84  vec_foreach (rt, pm->perfmon_tables)
85  {
86  if (perfmon_cpu_model_matches (rt->models, rt->n_models, model, stepping))
87  return rt->events;
88  }
89  return 0;
90 }
91 
92 static clib_error_t *
94 {
96  clib_error_t *error = 0;
97  u32 cpuid;
98  u8 model, stepping;
100  int i;
101 
102  pm->vlib_main = vm;
103  pm->vnet_main = vnet_get_main ();
104 
106  hash_create_string (0, sizeof (uword));
107 
108  pm->log_class = vlib_log_register_class ("perfmon", 0);
109 
110  /* Default data collection interval */
111  pm->timeout_interval = 2.0; /* seconds */
112 
113  vec_validate (pm->threads, vlib_get_thread_main ()->n_vlib_mains - 1);
114  for (i = 0; i < vec_len (pm->threads); i++)
115  {
118  clib_memset (pt, 0, sizeof (*pt));
119  pm->threads[i] = pt;
120  pt->pm_fds[0] = -1;
121  pt->pm_fds[1] = -1;
122  }
123  pm->page_size = getpagesize ();
124 
125  pm->perfmon_table = 0;
126  pm->pmc_event_by_name = 0;
127 
128  cpuid = get_cpuid ();
129  model = ((cpuid >> 12) & 0xf0) | ((cpuid >> 4) & 0xf);
130  stepping = cpuid & 0xf;
131 
133  model, stepping);
134 
135  if (pm->perfmon_table == 0)
136  {
137  vlib_log_err (pm->log_class, "No table for cpuid %x", cpuid);
138  vlib_log_err (pm->log_class, " model %x, stepping %x",
139  model, stepping);
140  }
141  else
142  {
143  pm->pmc_event_by_name = hash_create_string (0, sizeof (u32));
144  ev = pm->perfmon_table;
145 
146  for (; ev->event_name; ev++)
147  {
149  ev - pm->perfmon_table);
150  }
151  }
152 
153  return error;
154 }
155 
157 
158 uword
160 {
161  perfmon_main_t *pm = va_arg (*args, perfmon_main_t *);
162  perfmon_event_config_t *ep = va_arg (*args, perfmon_event_config_t *);
163  u8 *s = 0;
164  hash_pair_t *hp;
165  u32 idx;
166  u32 pe_config = 0;
167 
168  if (pm->perfmon_table == 0 || pm->pmc_event_by_name == 0)
169  return 0;
170 
171  if (!unformat (input, "%s", &s))
172  return 0;
173 
174  hp = hash_get_pair_mem (pm->pmc_event_by_name, s);
175 
176  vec_free (s);
177 
178  if (hp == 0)
179  return 0;
180 
181  idx = (u32) (hp->value[0]);
182 
183  pe_config |= pm->perfmon_table[idx].event_code[0];
184  pe_config |= pm->perfmon_table[idx].umask << 8;
185  pe_config |= pm->perfmon_table[idx].edge << 18;
186  pe_config |= pm->perfmon_table[idx].anyt << 21;
187  pe_config |= pm->perfmon_table[idx].inv << 23;
188  pe_config |= pm->perfmon_table[idx].cmask << 24;
189 
190  ep->name = (char *) hp->key;
191  ep->pe_type = PERF_TYPE_RAW;
192  ep->pe_config = pe_config;
193  return 1;
194 }
195 
196 static clib_error_t *
198  unformat_input_t * input, vlib_cli_command_t * cmd)
199 {
202  int num_threads = 1 + vtm->n_threads;
203  unformat_input_t _line_input, *line_input = &_line_input;
205  f64 delay;
206  u32 timeout_seconds;
207  u32 deadman;
208  int last_set;
209  clib_error_t *error;
210 
213  pm->ipc_event_index = ~0;
214  pm->mispredict_event_index = ~0;
215 
216  if (!unformat_user (input, unformat_line_input, line_input))
217  return clib_error_return (0, "counter names required...");
218 
220 
221  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
222  {
223  if (unformat (line_input, "timeout %u", &timeout_seconds))
224  pm->timeout_interval = (f64) timeout_seconds;
225  else if (unformat (line_input, "instructions-per-clock"))
226  {
227  ec.name = "instructions";
228  ec.pe_type = PERF_TYPE_HARDWARE;
229  ec.pe_config = PERF_COUNT_HW_INSTRUCTIONS;
232  ec.name = "cpu-cycles";
233  ec.pe_type = PERF_TYPE_HARDWARE;
234  ec.pe_config = PERF_COUNT_HW_CPU_CYCLES;
236  }
237  else if (unformat (line_input, "branch-mispredict-rate"))
238  {
239  ec.name = "branch-misses";
240  ec.pe_type = PERF_TYPE_HARDWARE;
241  ec.pe_config = PERF_COUNT_HW_BRANCH_MISSES;
244  ec.name = "branches";
245  ec.pe_type = PERF_TYPE_HARDWARE;
246  ec.pe_config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
248  }
249  else if (unformat (line_input, "threads %U",
250  unformat_bitmap_list, &pm->thread_bitmap))
251  ;
252  else if (unformat (line_input, "thread %U",
253  unformat_bitmap_list, &pm->thread_bitmap))
254  ;
255  else if (unformat (line_input, "%U", unformat_processor_event, pm, &ec))
256  {
258  }
259 #define _(type,event,str) \
260  else if (unformat (line_input, str)) \
261  { \
262  ec.name = str; \
263  ec.pe_type = type; \
264  ec.pe_config = event; \
265  vec_add1 (pm->single_events_to_collect, ec); \
266  }
268 #undef _
269  else
270  {
271  error = clib_error_return (0, "unknown input '%U'",
272  format_unformat_error, line_input);
273  unformat_free (line_input);
274  return error;
275  }
276  }
277 
278  unformat_free (line_input);
279 
280  last_set = clib_bitmap_last_set (pm->thread_bitmap);
281  if (last_set != ~0 && last_set >= num_threads)
282  return clib_error_return (0, "thread %d does not exist", last_set);
283 
284  /* Stick paired events at the front of the (unified) list */
285  if (vec_len (pm->paired_events_to_collect) > 0)
286  {
288  /* first 2n events are pairs... */
290  tmp = pm->single_events_to_collect;
292  pm->paired_events_to_collect = tmp;
293  }
294 
295  if (vec_len (pm->single_events_to_collect) == 0)
296  return clib_error_return (0, "no events specified...");
297 
298  /* Figure out how long data collection will take */
299  delay =
301  delay /= 2.0; /* collect 2 stats at once */
302 
303  vlib_cli_output (vm, "Start collection for %d events, wait %.2f seconds",
304  vec_len (pm->single_events_to_collect), delay);
305 
307  PERFMON_START, 0);
308 
309  /* Coarse-grained wait */
310  vlib_process_suspend (vm, delay);
311 
312  deadman = 0;
313  /* Reasonable to guess that collection may not be quite done... */
314  while (pm->state == PERFMON_STATE_RUNNING)
315  {
316  vlib_process_suspend (vm, 10e-3);
317  if (deadman++ > 200)
318  {
319  vlib_cli_output (vm, "DEADMAN: collection still running...");
320  break;
321  }
322  }
323 
324  vlib_cli_output (vm, "Data collection complete...");
325  return 0;
326 }
327 
328 /* *INDENT-OFF* */
329 VLIB_CLI_COMMAND (set_pmc_command, static) =
330 {
331  .path = "set pmc",
332  .short_help = "set pmc [threads n,n1-n2] c1... [see \"show pmc events\"]",
333  .function = set_pmc_command_fn,
334  .is_mp_safe = 1,
335 };
336 /* *INDENT-ON* */
337 
338 static int
339 capture_name_sort (void *a1, void *a2)
340 {
341  perfmon_capture_t *c1 = a1;
342  perfmon_capture_t *c2 = a2;
343 
344  return strcmp ((char *) c1->thread_and_node_name,
345  (char *) c2->thread_and_node_name);
346 }
347 
348 static u8 *
349 format_capture (u8 * s, va_list * args)
350 {
351  perfmon_main_t *pm = va_arg (*args, perfmon_main_t *);
352  perfmon_capture_t *c = va_arg (*args, perfmon_capture_t *);
353  int verbose __attribute__ ((unused)) = va_arg (*args, int);
354  f64 ticks_per_pkt;
355  int i;
356 
357  if (c == 0)
358  {
359  s = format (s, "%=40s%=20s%=16s%=16s%=16s",
360  "Name", "Counter", "Count", "Pkts", "Counts/Pkt");
361  return s;
362  }
363 
364  for (i = 0; i < vec_len (c->counter_names); i++)
365  {
366  u8 *name;
367 
368  if (i == 0)
369  name = c->thread_and_node_name;
370  else
371  {
372  vec_add1 (s, '\n');
373  name = (u8 *) "";
374  }
375 
376  /* Deal with synthetic events right here */
377  if (i == pm->ipc_event_index)
378  {
379  f64 ipc_rate;
380  ASSERT ((i + 1) < vec_len (c->counter_names));
381 
382  if (c->counter_values[i + 1] > 0)
383  ipc_rate = (f64) c->counter_values[i]
384  / (f64) c->counter_values[i + 1];
385  else
386  ipc_rate = 0.0;
387 
388  s = format (s, "%-40s%+20s%+16llu%+16llu%+16.2e\n",
389  name, "instructions-per-clock",
390  c->counter_values[i],
391  c->counter_values[i + 1], ipc_rate);
392  name = (u8 *) "";
393  }
394 
395  if (i == pm->mispredict_event_index)
396  {
397  f64 mispredict_rate;
398  ASSERT (i + 1 < vec_len (c->counter_names));
399 
400  if (c->counter_values[i + 1] > 0)
401  mispredict_rate = (f64) c->counter_values[i]
402  / (f64) c->counter_values[i + 1];
403  else
404  mispredict_rate = 0.0;
405 
406  s = format (s, "%-40s%+20s%+16llu%+16llu%+16.2e\n",
407  name, "branch-mispredict-rate",
408  c->counter_values[i],
409  c->counter_values[i + 1], mispredict_rate);
410  name = (u8 *) "";
411  }
412 
413  if (c->vectors_this_counter[i])
414  ticks_per_pkt =
415  ((f64) c->counter_values[i]) / ((f64) c->vectors_this_counter[i]);
416  else
417  ticks_per_pkt = 0.0;
418 
419  s = format (s, "%-40s%+20s%+16llu%+16llu%+16.2e",
420  name, c->counter_names[i],
421  c->counter_values[i],
422  c->vectors_this_counter[i], ticks_per_pkt);
423  }
424  return s;
425 }
426 
427 static u8 *
428 format_generic_events (u8 * s, va_list * args)
429 {
430  int verbose = va_arg (*args, int);
431 
432 #define _(type,config,name) \
433  if (verbose == 0) \
434  s = format (s, "\n %s", name); \
435  else \
436  s = format (s, "\n %s (%d, %d)", name, type, config);
438 #undef _
439  return s;
440 }
441 
442 typedef struct
443 {
446 } sort_nvp_t;
447 
448 static int
449 sort_nvps_by_name (void *a1, void *a2)
450 {
451  sort_nvp_t *nvp1 = a1;
452  sort_nvp_t *nvp2 = a2;
453 
454  return strcmp ((char *) nvp1->name, (char *) nvp2->name);
455 }
456 
457 static u8 *
458 format_pmc_event (u8 * s, va_list * args)
459 {
461 
462  s = format (s, "%s\n", ev->event_name);
463  s = format (s, " umask: 0x%x\n", ev->umask);
464  s = format (s, " code: 0x%x", ev->event_code[0]);
465 
466  if (ev->event_code[1])
467  s = format (s, " , 0x%x\n", ev->event_code[1]);
468  else
469  s = format (s, "\n");
470 
471  return s;
472 }
473 
474 static u8 *
475 format_processor_events (u8 * s, va_list * args)
476 {
477  perfmon_main_t *pm = va_arg (*args, perfmon_main_t *);
478  int verbose = va_arg (*args, int);
479  sort_nvp_t *sort_nvps = 0;
480  sort_nvp_t *sn;
481  u8 *key;
482  u32 value;
483 
484  /* *INDENT-OFF* */
485  hash_foreach_mem (key, value, pm->pmc_event_by_name,
486  ({
487  vec_add2 (sort_nvps, sn, 1);
488  sn->name = key;
489  sn->index = value;
490  }));
491 
493 
494  if (verbose == 0)
495  {
496  vec_foreach (sn, sort_nvps)
497  s = format (s, "\n %s ", sn->name);
498  }
499  else
500  {
501  vec_foreach (sn, sort_nvps)
502  s = format(s, "%U", format_pmc_event, &pm->perfmon_table[sn->index]);
503  }
504  vec_free (sort_nvps);
505  return s;
506 }
507 
508 
509 static clib_error_t *
511  unformat_input_t * input, vlib_cli_command_t * cmd)
512 {
514  int verbose = 0;
515  int events = 0;
516  int i;
518  perfmon_capture_t *captures = 0;
519 
521  {
522  if (unformat (input, "events"))
523  events = 1;
524  else if (unformat (input, "verbose"))
525  verbose = 1;
526  else
527  break;
528  }
529 
530  if (events)
531  {
532  vlib_cli_output (vm, "Generic Events %U",
533  format_generic_events, verbose);
534  vlib_cli_output (vm, "Synthetic Events");
535  vlib_cli_output (vm, " instructions-per-clock");
536  vlib_cli_output (vm, " branch-mispredict-rate");
537  if (pm->perfmon_table)
538  vlib_cli_output (vm, "Processor Events %U",
539  format_processor_events, pm, verbose);
540  return 0;
541  }
542 
543  if (pm->state == PERFMON_STATE_RUNNING)
544  {
545  vlib_cli_output (vm, "Data collection in progress...");
546  return 0;
547  }
548 
549  if (pool_elts (pm->capture_pool) == 0)
550  {
551  vlib_cli_output (vm, "No data...");
552  return 0;
553  }
554 
555  /* *INDENT-OFF* */
556  pool_foreach (c, pm->capture_pool,
557  ({
558  vec_add1 (captures, *c);
559  }));
560  /* *INDENT-ON* */
561 
563 
564  vlib_cli_output (vm, "%U", format_capture, pm, 0 /* header */ ,
565  0 /* verbose */ );
566 
567  for (i = 0; i < vec_len (captures); i++)
568  {
569  c = captures + i;
570 
571  vlib_cli_output (vm, "%U", format_capture, pm, c, verbose);
572  }
573 
574  vec_free (captures);
575 
576  return 0;
577 }
578 
579 /* *INDENT-OFF* */
580 VLIB_CLI_COMMAND (show_pmc_command, static) =
581 {
582  .path = "show pmc",
583  .short_help = "show pmc [verbose]",
584  .function = show_pmc_command_fn,
585  .is_mp_safe = 1,
586 };
587 /* *INDENT-ON* */
588 
589 static clib_error_t *
591  unformat_input_t * input, vlib_cli_command_t * cmd)
592 {
594  u8 *key;
595  u32 *value;
596 
597  if (pm->state == PERFMON_STATE_RUNNING)
598  {
599  vlib_cli_output (vm, "Performance monitor is still running...");
600  return 0;
601  }
602 
603  pool_free (pm->capture_pool);
604 
605  /* *INDENT-OFF* */
607  ({
608  vec_free (key);
609  }));
610  /* *INDENT-ON* */
613  hash_create_string (0, sizeof (uword));
614  return 0;
615 }
616 
617 /* *INDENT-OFF* */
618 VLIB_CLI_COMMAND (clear_pmc_command, static) =
619 {
620  .path = "clear pmc",
621  .short_help = "clear the performance monitor counters",
622  .function = clear_pmc_command_fn,
623 };
624 /* *INDENT-ON* */
625 
626 
627 /*
628  * fd.io coding-style-patch-verification: ON
629  *
630  * Local Variables:
631  * eval: (c-set-style "gnu")
632  * End:
633  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:209
perfmon_capture_t * capture_pool
Definition: perfmon.h:114
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
volatile u8 state
Definition: perfmon.h:111
f64 timeout_interval
Definition: perfmon.h:136
static clib_error_t * set_pmc_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: perfmon.c:197
u64 * vectors_this_counter
Definition: perfmon.h:70
perfmon_event_config_t * paired_events_to_collect
Definition: perfmon.h:129
perfmon_thread_t ** threads
Definition: perfmon.h:148
static int capture_name_sort(void *a1, void *a2)
Definition: perfmon.c:339
u8 * name
Definition: perfmon.c:444
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_node_registration_t perfmon_periodic_node
(constructor) VLIB_REGISTER_NODE (perfmon_periodic_node)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
uword unformat_processor_event(unformat_input_t *input, va_list *args)
Definition: perfmon.c:159
u32 mispredict_event_index
Definition: perfmon.h:133
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
#define hash_set_mem(h, key, value)
Definition: hash.h:275
#define hash_get_pair_mem(h, key)
Definition: hash.h:272
vlib_main_t * vm
Definition: in2out_ed.c:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
vlib_main_t * vlib_main
Definition: perfmon.h:154
unsigned char u8
Definition: types.h:56
#define clib_bitmap_zero(v)
Clear a bitmap.
Definition: bitmap.h:102
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
double f64
Definition: types.h:142
uword value[0]
Definition: hash.h:165
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
Definition: node_funcs.h:482
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
#define clib_error_return(e, args...)
Definition: error.h:99
static clib_error_t * show_pmc_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: perfmon.c:510
u8 * thread_and_node_name
Definition: perfmon.h:67
unsigned int u32
Definition: types.h:88
#define hash_create_string(elts, value_bytes)
Definition: hash.h:690
unformat_function_t unformat_line_input
Definition: format.h:283
vnet_main_t * vnet_main
Definition: perfmon.h:155
static u8 * format_pmc_event(u8 *s, va_list *args)
Definition: perfmon.c:458
perfmon_intel_pmc_event_t * events
Definition: perfmon_intel.h:44
static perfmon_intel_pmc_event_t * perfmon_find_table_by_model_stepping(perfmon_main_t *pm, u8 model, u8 stepping)
Definition: perfmon.c:79
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:1015
u8 ** counter_names
Definition: perfmon.h:68
static uword clib_bitmap_last_set(uword *ai)
Return the higest numbered set bit in a bitmap.
Definition: bitmap.h:423
struct _unformat_input_t unformat_input_t
#define hash_free(h)
Definition: hash.h:310
uword * pmc_event_by_name
Definition: perfmon.h:123
perfmon_intel_pmc_cpu_model_t * models
Definition: perfmon_intel.h:45
perfmon_intel_pmc_event_t * perfmon_table
Definition: perfmon.h:121
u32 index
Definition: perfmon.c:445
static u8 * format_capture(u8 *s, va_list *args)
Definition: perfmon.c:349
#define hash_foreach_mem(key_var, value_var, h, body)
Definition: hash.h:461
vlib_log_class_t log_class
Definition: perfmon.h:151
#define pool_free(p)
Free a pool.
Definition: pool.h:427
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
svmdb_client_t * c
static u32 get_cpuid(void)
Definition: perfmon.c:45
static clib_error_t * clear_pmc_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: perfmon.c:590
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
static int sort_nvps_by_name(void *a1, void *a2)
Definition: perfmon.c:449
string name[64]
Definition: ip.api:44
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
u8 value
Definition: qos.api:54
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
perfmon_event_config_t * single_events_to_collect
Definition: perfmon.h:126
#define vec_append(v1, v2)
Append v2 after v1.
Definition: vec.h:890
static u8 * format_processor_events(u8 *s, va_list *args)
Definition: perfmon.c:475
u32 ipc_event_index
Definition: perfmon.h:132
static clib_error_t * perfmon_init(vlib_main_t *vm)
Definition: perfmon.c:93
perfmon_main_t perfmon_main
Definition: perfmon.c:27
void perfmon_register_intel_pmc(perfmon_intel_pmc_cpu_model_t *m, int n_models, perfmon_intel_pmc_event_t *e, int n_events)
Definition: perfmon.c:30
#define foreach_perfmon_event
Definition: perfmon.h:31
uword * capture_by_thread_and_node_name
Definition: perfmon.h:115
static u8 * format_generic_events(u8 *s, va_list *args)
Definition: perfmon.c:428
typedef key
Definition: ipsec_types.api:85
uword * thread_bitmap
Definition: perfmon.h:145
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u64 * counter_values
Definition: perfmon.h:69
perfmon_intel_pmc_registration_t * perfmon_tables
Definition: perfmon.h:118
u64 uword
Definition: types.h:112
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1055
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:165
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
#define vec_foreach(var, vec)
Vector iterator.
#define vlib_log_err(...)
Definition: log.h:105
static int perfmon_cpu_model_matches(perfmon_intel_pmc_cpu_model_t *mt, u32 n_models, u8 model, u8 stepping)
Definition: perfmon.c:58
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
int pm_fds[2]
Definition: perfmon.h:93
uword key
Definition: hash.h:162
#define PERFMON_START
Definition: perfmon.h:167
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128