24 #include <vpp/app/version.h> 25 #include <linux/limits.h> 43 {0x2E, 0x0, 0,
"NehalemEX_core_V2.json"},
44 {0x1E, 0x0, 0,
"NehalemEP_core_V2.json"},
45 {0x1F, 0x0, 0,
"NehalemEP_core_V2.json"},
46 {0x1A, 0x0, 0,
"NehalemEP_core_V2.json"},
47 {0x2F, 0x0, 0,
"WestmereEX_core_V2.json"},
48 {0x25, 0x0, 0,
"WestmereEP-SP_core_V2.json"},
49 {0x2C, 0x0, 0,
"WestmereEP-DP_core_V2.json"},
50 {0x37, 0x0, 0,
"Silvermont_core_V14.json"},
51 {0x4D, 0x0, 0,
"Silvermont_core_V14.json"},
52 {0x4C, 0x0, 0,
"Silvermont_core_V14.json"},
53 {0x5C, 0x0, 0,
"goldmont_core_v13.json"},
54 {0x5F, 0x0, 0,
"goldmont_core_v13.json"},
55 {0x1C, 0x0, 0,
"Bonnell_core_V4.json"},
56 {0x26, 0x0, 0,
"Bonnell_core_V4.json"},
57 {0x27, 0x0, 0,
"Bonnell_core_V4.json"},
58 {0x36, 0x0, 0,
"Bonnell_core_V4.json"},
59 {0x35, 0x0, 0,
"Bonnell_core_V4.json"},
60 {0x2A, 0x0, 0,
"sandybridge_core_v16.json"},
61 {0x2D, 0x0, 0,
"Jaketown_core_V20.json"},
62 {0x3A, 0x0, 0,
"ivybridge_core_v21.json"},
63 {0x3E, 0x0, 0,
"ivytown_core_v20.json"},
64 {0x3C, 0x0, 0,
"haswell_core_v28.json"},
65 {0x45, 0x0, 0,
"haswell_core_v28.json"},
66 {0x46, 0x0, 0,
"haswell_core_v28.json"},
67 {0x3F, 0x0, 0,
"haswellx_core_v20.json"},
68 {0x3D, 0x0, 0,
"broadwell_core_v23.json"},
69 {0x47, 0x0, 0,
"broadwell_core_v23.json"},
70 {0x4F, 0x0, 0,
"broadwellx_core_v14.json"},
71 {0x56, 0x0, 0,
"broadwellde_core_v7.json"},
72 {0x4E, 0x0, 0,
"skylake_core_v42.json"},
73 {0x5E, 0x0, 0,
"skylake_core_v42.json"},
74 {0x8E, 0x0, 0,
"skylake_core_v42.json"},
75 {0x9E, 0x0, 0,
"skylake_core_v42.json"},
76 {0x57, 0x0, 0,
"KnightsLanding_core_V9.json"},
77 {0x85, 0x0, 0,
"KnightsLanding_core_V9.json"},
78 {0x55, 0x0, 1,
"skylakex_core_v1.12.json"},
79 {0x55, 0x1, 1,
"skylakex_core_v1.12.json"},
80 {0x55, 0x2, 1,
"skylakex_core_v1.12.json"},
81 {0x55, 0x3, 1,
"skylakex_core_v1.12.json"},
82 {0x55, 0x4, 1,
"skylakex_core_v1.12.json"},
83 {0x55, 0x5, 1,
"cascadelakex_core_v1.00.json"},
84 {0x55, 0x6, 1,
"cascadelakex_core_v1.00.json"},
85 {0x55, 0x7, 1,
"cascadelakex_core_v1.00.json"},
86 {0x55, 0x8, 1,
"cascadelakex_core_v1.00.json"},
87 {0x55, 0x9, 1,
"cascadelakex_core_v1.00.json"},
88 {0x55, 0xA, 1,
"cascadelakex_core_v1.00.json"},
89 {0x55, 0xB, 1,
"cascadelakex_core_v1.00.json"},
90 {0x55, 0xC, 1,
"cascadelakex_core_v1.00.json"},
91 {0x55, 0xD, 1,
"cascadelakex_core_v1.00.json"},
92 {0x55, 0xE, 1,
"cascadelakex_core_v1.00.json"},
93 {0x55, 0xF, 1,
"cascadelakex_core_v1.00.json"},
94 {0x7A, 0x0, 0,
"goldmontplus_core_v1.01.json"},
100 char *p, path[PATH_MAX];
105 if ((rv = readlink (
"/proc/self/exe", path, PATH_MAX - 1)) == -1)
112 if ((p = strrchr (path,
'/')) == 0)
117 if ((p = strrchr (path,
'/')) == 0)
122 s =
format (0,
"%s/share/vpp/plugins/perfmon", path);
130 #if defined(__x86_64__) 132 asm volatile (
"mov $1, %%eax; cpuid; mov %%eax, %0":
"=r" (cpuid)::
"%eax",
133 "%edx",
"%ecx",
"%rbx");
147 int found_a_table = 0;
172 for (i = 0; i <
ARRAY_LEN (fms_table); i++)
174 model = ((cpuid >> 12) & 0xf0) | ((cpuid >> 4) & 0xf);
175 stepping = cpuid & 0xf;
177 if (fms_table[i].model != model)
180 if (fms_table[i].has_stepping)
182 if (fms_table[i].stepping != stepping)
207 .version = VPP_BUILD_VER,
208 .description =
"Performance monitor plugin",
209 #if !defined(__x86_64__) 210 .default_disabled = 1,
222 if (*s >=
'0' && *s <=
'9')
223 rv = (rv << 4) | (*s -
'0');
224 else if (*s >=
'a' && *s <=
'f')
225 rv = (rv << 4) | (*s -
'a' + 10);
226 else if (*s >=
'A' && *s <=
'A')
227 rv = (rv << 4) | (*s -
'A' + 10);
264 for (i = 0; i <
vec_len (nvps); i++)
267 if (!strncmp ((
char *) nvp->
name,
"EventCode", 9))
272 else if (!strncmp ((
char *) nvp->
name,
"UMask", 5))
312 if (
unformat (line_input,
"timeout %u", &timeout_seconds))
314 else if (
unformat (line_input,
"instructions-per-clock"))
316 ec.
name =
"instructions";
317 ec.
pe_type = PERF_TYPE_HARDWARE;
318 ec.
pe_config = PERF_COUNT_HW_INSTRUCTIONS;
321 ec.
name =
"cpu-cycles";
322 ec.
pe_type = PERF_TYPE_HARDWARE;
326 else if (
unformat (line_input,
"branch-mispredict-rate"))
328 ec.
name =
"branch-misses";
329 ec.
pe_type = PERF_TYPE_HARDWARE;
330 ec.
pe_config = PERF_COUNT_HW_BRANCH_MISSES;
333 ec.
name =
"branches";
334 ec.
pe_type = PERF_TYPE_HARDWARE;
335 ec.
pe_config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
342 #define _(type,event,str) \ 343 else if (unformat (line_input, str)) \ 347 ec.pe_config = event; \ 348 vec_add1 (pm->events_to_collect, ec); \ 360 vlib_cli_output (vm,
"Start collection for %d events, wait %.2f seconds",
393 .short_help =
"set pmc c1 [..., use \"show pmc events\"]",
414 int verbose __attribute__ ((unused)) = va_arg (*args,
int);
420 s =
format (s,
"%=40s%=20s%=16s%=16s%=16s",
421 "Name",
"Counter",
"Count",
"Pkts",
"Counts/Pkt");
449 s =
format (s,
"%-40s%+20s%+16llu%+16llu%+16.2e\n",
450 name,
"instructions-per-clock",
465 mispredict_rate = 0.0;
467 s =
format (s,
"%-40s%+20s%+16llu%+16llu%+16.2e\n",
468 name,
"branch-mispredict-rate",
480 s =
format (s,
"%-40s%+20s%+16llu%+16llu%+16.2e",
491 int verbose = va_arg (*args,
int);
493 #define _(type,config,name) \ 495 s = format (s, "\n %s", name); \ 497 s = format (s, "\n %s (%d, %d)", name, type, config); 515 return strcmp ((
char *) nvp1->
name, (
char *) nvp2->
name);
522 int verbose = va_arg (*args,
int);
532 vec_add2 (sort_nvps, sn, 1);
541 for (i = 0; i <
vec_len (sort_nvps); i++)
546 for (i = 0; i <
vec_len (sort_nvps); i++)
551 nvps = sort_nvps[
i].
nvps;
553 for (j = 0; j <
vec_len (nvps); j++)
554 s =
format (s,
"\n %s = %s", nvps[j]->name, nvps[j]->value);
577 else if (
unformat (input,
"verbose"))
611 vec_add1 (captures, *c);
620 for (i = 0; i <
vec_len (captures); i++)
636 .short_help =
"show pmc [verbose]",
674 .short_help =
"clear the performance monitor counters",
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
perfmon_capture_t * capture_pool
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static clib_error_t * set_pmc_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u64 * vectors_this_counter
static int capture_name_sort(void *a1, void *a2)
perfmon_event_config_t * events_to_collect
vnet_main_t * vnet_get_main(void)
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).
u32 mispredict_event_index
#define hash_get_pair_mem(h, key)
vlib_main_t ** vlib_mains
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
#define clib_error_return(e, args...)
static clib_error_t * show_pmc_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u8 * thread_and_node_name
static uword unformat_processor_event(unformat_input_t *input, va_list *args)
static void set_perfmon_json_path()
#define hash_create_string(elts, value_bytes)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
static u8 * format_capture(u8 *s, va_list *args)
name_value_pair_t ** nvps
static char * perfmon_json_path
#define hash_foreach_mem(key_var, value_var, h, body)
vlib_log_class_t log_class
#define pool_free(p)
Free a pool.
static u32 get_cpuid(void)
static clib_error_t * clear_pmc_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define vec_free(V)
Free vector's memory (no header).
static int sort_nvps_by_name(void *a1, void *a2)
#define clib_warning(format, args...)
#define VLIB_CLI_COMMAND(x,...)
static uword hash_elts(void *v)
uword * perfmon_parse_table(perfmon_main_t *pm, char *path, char *table_name)
static u8 * format_processor_events(u8 *s, va_list *args)
static clib_error_t * perfmon_init(vlib_main_t *vm)
perfmon_main_t perfmon_main
#define foreach_perfmon_event
uword * capture_by_thread_and_node_name
static u8 * format_generic_events(u8 *s, va_list *args)
#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.
#define vlib_log_err(...)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static uword pool_elts(void *v)
Number of active elements in a pool.