xref: /linux/tools/perf/util/parse-events.c (revision faafec1e61e61d350248af2a7e5f047606adab6e)
186470930SIngo Molnar 
286470930SIngo Molnar #include "../perf.h"
386470930SIngo Molnar #include "util.h"
486470930SIngo Molnar #include "parse-options.h"
586470930SIngo Molnar #include "parse-events.h"
686470930SIngo Molnar #include "exec_cmd.h"
786470930SIngo Molnar #include "string.h"
886470930SIngo Molnar 
986470930SIngo Molnar extern char *strcasestr(const char *haystack, const char *needle);
1086470930SIngo Molnar 
1186470930SIngo Molnar int					nr_counters;
1286470930SIngo Molnar 
1386470930SIngo Molnar struct perf_counter_attr		attrs[MAX_COUNTERS];
1486470930SIngo Molnar 
1586470930SIngo Molnar struct event_symbol {
1686470930SIngo Molnar 	__u8	type;
1786470930SIngo Molnar 	__u64	config;
1886470930SIngo Molnar 	char	*symbol;
1986470930SIngo Molnar };
2086470930SIngo Molnar 
2186470930SIngo Molnar #define C(x, y) .type = PERF_TYPE_##x, .config = PERF_COUNT_##y
2286470930SIngo Molnar #define CR(x, y) .type = PERF_TYPE_##x, .config = y
2386470930SIngo Molnar 
2486470930SIngo Molnar static struct event_symbol event_symbols[] = {
25f4dbfa8fSPeter Zijlstra   { C(HARDWARE, HW_CPU_CYCLES),		"cpu-cycles",		},
26f4dbfa8fSPeter Zijlstra   { C(HARDWARE, HW_CPU_CYCLES),		"cycles",		},
27f4dbfa8fSPeter Zijlstra   { C(HARDWARE, HW_INSTRUCTIONS),	"instructions",		},
28f4dbfa8fSPeter Zijlstra   { C(HARDWARE, HW_CACHE_REFERENCES),	"cache-references",	},
29f4dbfa8fSPeter Zijlstra   { C(HARDWARE, HW_CACHE_MISSES),	"cache-misses",		},
30f4dbfa8fSPeter Zijlstra   { C(HARDWARE, HW_BRANCH_INSTRUCTIONS),"branch-instructions",	},
31f4dbfa8fSPeter Zijlstra   { C(HARDWARE, HW_BRANCH_INSTRUCTIONS),"branches",		},
32f4dbfa8fSPeter Zijlstra   { C(HARDWARE, HW_BRANCH_MISSES),	"branch-misses",	},
33f4dbfa8fSPeter Zijlstra   { C(HARDWARE, HW_BUS_CYCLES),		"bus-cycles",		},
3486470930SIngo Molnar 
35f4dbfa8fSPeter Zijlstra   { C(SOFTWARE, SW_CPU_CLOCK),		"cpu-clock",		},
36f4dbfa8fSPeter Zijlstra   { C(SOFTWARE, SW_TASK_CLOCK),		"task-clock",		},
37f4dbfa8fSPeter Zijlstra   { C(SOFTWARE, SW_PAGE_FAULTS),	"page-faults",		},
38f4dbfa8fSPeter Zijlstra   { C(SOFTWARE, SW_PAGE_FAULTS),	"faults",		},
39f4dbfa8fSPeter Zijlstra   { C(SOFTWARE, SW_PAGE_FAULTS_MIN),	"minor-faults",		},
40f4dbfa8fSPeter Zijlstra   { C(SOFTWARE, SW_PAGE_FAULTS_MAJ),	"major-faults",		},
41f4dbfa8fSPeter Zijlstra   { C(SOFTWARE, SW_CONTEXT_SWITCHES),	"context-switches",	},
42f4dbfa8fSPeter Zijlstra   { C(SOFTWARE, SW_CONTEXT_SWITCHES),	"cs",			},
43f4dbfa8fSPeter Zijlstra   { C(SOFTWARE, SW_CPU_MIGRATIONS),	"cpu-migrations",	},
44f4dbfa8fSPeter Zijlstra   { C(SOFTWARE, SW_CPU_MIGRATIONS),	"migrations",		},
4586470930SIngo Molnar };
4686470930SIngo Molnar 
4786470930SIngo Molnar #define __PERF_COUNTER_FIELD(config, name) \
4886470930SIngo Molnar 	((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT)
4986470930SIngo Molnar 
5086470930SIngo Molnar #define PERF_COUNTER_RAW(config)	__PERF_COUNTER_FIELD(config, RAW)
5186470930SIngo Molnar #define PERF_COUNTER_CONFIG(config)	__PERF_COUNTER_FIELD(config, CONFIG)
5286470930SIngo Molnar #define PERF_COUNTER_TYPE(config)	__PERF_COUNTER_FIELD(config, TYPE)
5386470930SIngo Molnar #define PERF_COUNTER_ID(config)		__PERF_COUNTER_FIELD(config, EVENT)
5486470930SIngo Molnar 
5586470930SIngo Molnar static char *hw_event_names[] = {
5686470930SIngo Molnar 	"cycles",
5786470930SIngo Molnar 	"instructions",
5886470930SIngo Molnar 	"cache-references",
5986470930SIngo Molnar 	"cache-misses",
6086470930SIngo Molnar 	"branches",
6186470930SIngo Molnar 	"branch-misses",
6286470930SIngo Molnar 	"bus-cycles",
6386470930SIngo Molnar };
6486470930SIngo Molnar 
6586470930SIngo Molnar static char *sw_event_names[] = {
6686470930SIngo Molnar 	"cpu-clock-ticks",
6786470930SIngo Molnar 	"task-clock-ticks",
6886470930SIngo Molnar 	"page-faults",
6986470930SIngo Molnar 	"context-switches",
7086470930SIngo Molnar 	"CPU-migrations",
7186470930SIngo Molnar 	"minor-faults",
7286470930SIngo Molnar 	"major-faults",
7386470930SIngo Molnar };
7486470930SIngo Molnar 
7586470930SIngo Molnar #define MAX_ALIASES 8
7686470930SIngo Molnar 
7786470930SIngo Molnar static char *hw_cache [][MAX_ALIASES] = {
78*faafec1eSYong Wang 	{ "L1-data"		, "l1-d", "l1d"					},
7986470930SIngo Molnar 	{ "L1-instruction"	, "l1-i", "l1i"					},
8086470930SIngo Molnar 	{ "L2"			, "l2"						},
8186470930SIngo Molnar 	{ "Data-TLB"		, "dtlb", "d-tlb"				},
8286470930SIngo Molnar 	{ "Instruction-TLB"	, "itlb", "i-tlb"				},
8386470930SIngo Molnar 	{ "Branch"		, "bpu" , "btb", "bpc"				},
8486470930SIngo Molnar };
8586470930SIngo Molnar 
8686470930SIngo Molnar static char *hw_cache_op [][MAX_ALIASES] = {
8786470930SIngo Molnar 	{ "Load"		, "read"					},
8886470930SIngo Molnar 	{ "Store"		, "write"					},
8986470930SIngo Molnar 	{ "Prefetch"		, "speculative-read", "speculative-load"	},
9086470930SIngo Molnar };
9186470930SIngo Molnar 
9286470930SIngo Molnar static char *hw_cache_result [][MAX_ALIASES] = {
9386470930SIngo Molnar 	{ "Reference"		, "ops", "access"				},
9486470930SIngo Molnar 	{ "Miss"								},
9586470930SIngo Molnar };
9686470930SIngo Molnar 
9786470930SIngo Molnar char *event_name(int counter)
9886470930SIngo Molnar {
9986470930SIngo Molnar 	__u64 config = attrs[counter].config;
10086470930SIngo Molnar 	int type = attrs[counter].type;
10186470930SIngo Molnar 	static char buf[32];
10286470930SIngo Molnar 
10386470930SIngo Molnar 	if (attrs[counter].type == PERF_TYPE_RAW) {
10486470930SIngo Molnar 		sprintf(buf, "raw 0x%llx", config);
10586470930SIngo Molnar 		return buf;
10686470930SIngo Molnar 	}
10786470930SIngo Molnar 
10886470930SIngo Molnar 	switch (type) {
10986470930SIngo Molnar 	case PERF_TYPE_HARDWARE:
110f4dbfa8fSPeter Zijlstra 		if (config < PERF_COUNT_HW_MAX)
11186470930SIngo Molnar 			return hw_event_names[config];
11286470930SIngo Molnar 		return "unknown-hardware";
11386470930SIngo Molnar 
11486470930SIngo Molnar 	case PERF_TYPE_HW_CACHE: {
11586470930SIngo Molnar 		__u8 cache_type, cache_op, cache_result;
11686470930SIngo Molnar 		static char name[100];
11786470930SIngo Molnar 
11886470930SIngo Molnar 		cache_type   = (config >>  0) & 0xff;
11986470930SIngo Molnar 		if (cache_type > PERF_COUNT_HW_CACHE_MAX)
12086470930SIngo Molnar 			return "unknown-ext-hardware-cache-type";
12186470930SIngo Molnar 
12286470930SIngo Molnar 		cache_op     = (config >>  8) & 0xff;
12386470930SIngo Molnar 		if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX)
12486470930SIngo Molnar 			return "unknown-ext-hardware-cache-op";
12586470930SIngo Molnar 
12686470930SIngo Molnar 		cache_result = (config >> 16) & 0xff;
12786470930SIngo Molnar 		if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX)
12886470930SIngo Molnar 			return "unknown-ext-hardware-cache-result";
12986470930SIngo Molnar 
13086470930SIngo Molnar 		sprintf(name, "%s-Cache-%s-%ses",
13186470930SIngo Molnar 			hw_cache[cache_type][0],
13286470930SIngo Molnar 			hw_cache_op[cache_op][0],
13386470930SIngo Molnar 			hw_cache_result[cache_result][0]);
13486470930SIngo Molnar 
13586470930SIngo Molnar 		return name;
13686470930SIngo Molnar 	}
13786470930SIngo Molnar 
13886470930SIngo Molnar 	case PERF_TYPE_SOFTWARE:
139f4dbfa8fSPeter Zijlstra 		if (config < PERF_COUNT_SW_MAX)
14086470930SIngo Molnar 			return sw_event_names[config];
14186470930SIngo Molnar 		return "unknown-software";
14286470930SIngo Molnar 
14386470930SIngo Molnar 	default:
14486470930SIngo Molnar 		break;
14586470930SIngo Molnar 	}
14686470930SIngo Molnar 
14786470930SIngo Molnar 	return "unknown";
14886470930SIngo Molnar }
14986470930SIngo Molnar 
15086470930SIngo Molnar static int parse_aliases(const char *str, char *names[][MAX_ALIASES], int size)
15186470930SIngo Molnar {
15286470930SIngo Molnar 	int i, j;
15386470930SIngo Molnar 
15486470930SIngo Molnar 	for (i = 0; i < size; i++) {
15586470930SIngo Molnar 		for (j = 0; j < MAX_ALIASES; j++) {
15686470930SIngo Molnar 			if (!names[i][j])
15786470930SIngo Molnar 				break;
15886470930SIngo Molnar 			if (strcasestr(str, names[i][j]))
15986470930SIngo Molnar 				return i;
16086470930SIngo Molnar 		}
16186470930SIngo Molnar 	}
16286470930SIngo Molnar 
1638953645fSIngo Molnar 	return -1;
16486470930SIngo Molnar }
16586470930SIngo Molnar 
16686470930SIngo Molnar static int parse_generic_hw_symbols(const char *str, struct perf_counter_attr *attr)
16786470930SIngo Molnar {
1688953645fSIngo Molnar 	int cache_type = -1, cache_op = 0, cache_result = 0;
16986470930SIngo Molnar 
17086470930SIngo Molnar 	cache_type = parse_aliases(str, hw_cache, PERF_COUNT_HW_CACHE_MAX);
17186470930SIngo Molnar 	/*
17286470930SIngo Molnar 	 * No fallback - if we cannot get a clear cache type
17386470930SIngo Molnar 	 * then bail out:
17486470930SIngo Molnar 	 */
17586470930SIngo Molnar 	if (cache_type == -1)
17686470930SIngo Molnar 		return -EINVAL;
17786470930SIngo Molnar 
17886470930SIngo Molnar 	cache_op = parse_aliases(str, hw_cache_op, PERF_COUNT_HW_CACHE_OP_MAX);
17986470930SIngo Molnar 	/*
18086470930SIngo Molnar 	 * Fall back to reads:
18186470930SIngo Molnar 	 */
1828953645fSIngo Molnar 	if (cache_op == -1)
1838953645fSIngo Molnar 		cache_op = PERF_COUNT_HW_CACHE_OP_READ;
18486470930SIngo Molnar 
18586470930SIngo Molnar 	cache_result = parse_aliases(str, hw_cache_result,
18686470930SIngo Molnar 					PERF_COUNT_HW_CACHE_RESULT_MAX);
18786470930SIngo Molnar 	/*
18886470930SIngo Molnar 	 * Fall back to accesses:
18986470930SIngo Molnar 	 */
19086470930SIngo Molnar 	if (cache_result == -1)
19186470930SIngo Molnar 		cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS;
19286470930SIngo Molnar 
19386470930SIngo Molnar 	attr->config = cache_type | (cache_op << 8) | (cache_result << 16);
19486470930SIngo Molnar 	attr->type = PERF_TYPE_HW_CACHE;
19586470930SIngo Molnar 
19686470930SIngo Molnar 	return 0;
19786470930SIngo Molnar }
19886470930SIngo Molnar 
19986470930SIngo Molnar /*
20086470930SIngo Molnar  * Each event can have multiple symbolic names.
20186470930SIngo Molnar  * Symbolic names are (almost) exactly matched.
20286470930SIngo Molnar  */
20386470930SIngo Molnar static int parse_event_symbols(const char *str, struct perf_counter_attr *attr)
20486470930SIngo Molnar {
20586470930SIngo Molnar 	__u64 config, id;
20686470930SIngo Molnar 	int type;
20786470930SIngo Molnar 	unsigned int i;
20886470930SIngo Molnar 	const char *sep, *pstr;
20986470930SIngo Molnar 
21086470930SIngo Molnar 	if (str[0] == 'r' && hex2u64(str + 1, &config) > 0) {
21186470930SIngo Molnar 		attr->type = PERF_TYPE_RAW;
21286470930SIngo Molnar 		attr->config = config;
21386470930SIngo Molnar 
21486470930SIngo Molnar 		return 0;
21586470930SIngo Molnar 	}
21686470930SIngo Molnar 
21786470930SIngo Molnar 	pstr = str;
21886470930SIngo Molnar 	sep = strchr(pstr, ':');
21986470930SIngo Molnar 	if (sep) {
22086470930SIngo Molnar 		type = atoi(pstr);
22186470930SIngo Molnar 		pstr = sep + 1;
22286470930SIngo Molnar 		id = atoi(pstr);
22386470930SIngo Molnar 		sep = strchr(pstr, ':');
22486470930SIngo Molnar 		if (sep) {
22586470930SIngo Molnar 			pstr = sep + 1;
22686470930SIngo Molnar 			if (strchr(pstr, 'k'))
22786470930SIngo Molnar 				attr->exclude_user = 1;
22886470930SIngo Molnar 			if (strchr(pstr, 'u'))
22986470930SIngo Molnar 				attr->exclude_kernel = 1;
23086470930SIngo Molnar 		}
23186470930SIngo Molnar 		attr->type = type;
23286470930SIngo Molnar 		attr->config = id;
23386470930SIngo Molnar 
23486470930SIngo Molnar 		return 0;
23586470930SIngo Molnar 	}
23686470930SIngo Molnar 
23786470930SIngo Molnar 	for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
23886470930SIngo Molnar 		if (!strncmp(str, event_symbols[i].symbol,
23986470930SIngo Molnar 			     strlen(event_symbols[i].symbol))) {
24086470930SIngo Molnar 
24186470930SIngo Molnar 			attr->type = event_symbols[i].type;
24286470930SIngo Molnar 			attr->config = event_symbols[i].config;
24386470930SIngo Molnar 
24486470930SIngo Molnar 			return 0;
24586470930SIngo Molnar 		}
24686470930SIngo Molnar 	}
24786470930SIngo Molnar 
24886470930SIngo Molnar 	return parse_generic_hw_symbols(str, attr);
24986470930SIngo Molnar }
25086470930SIngo Molnar 
25186470930SIngo Molnar int parse_events(const struct option *opt, const char *str, int unset)
25286470930SIngo Molnar {
25386470930SIngo Molnar 	struct perf_counter_attr attr;
25486470930SIngo Molnar 	int ret;
25586470930SIngo Molnar 
25686470930SIngo Molnar 	memset(&attr, 0, sizeof(attr));
25786470930SIngo Molnar again:
25886470930SIngo Molnar 	if (nr_counters == MAX_COUNTERS)
25986470930SIngo Molnar 		return -1;
26086470930SIngo Molnar 
26186470930SIngo Molnar 	ret = parse_event_symbols(str, &attr);
26286470930SIngo Molnar 	if (ret < 0)
26386470930SIngo Molnar 		return ret;
26486470930SIngo Molnar 
26586470930SIngo Molnar 	attrs[nr_counters] = attr;
26686470930SIngo Molnar 	nr_counters++;
26786470930SIngo Molnar 
26886470930SIngo Molnar 	str = strstr(str, ",");
26986470930SIngo Molnar 	if (str) {
27086470930SIngo Molnar 		str++;
27186470930SIngo Molnar 		goto again;
27286470930SIngo Molnar 	}
27386470930SIngo Molnar 
27486470930SIngo Molnar 	return 0;
27586470930SIngo Molnar }
27686470930SIngo Molnar 
27786470930SIngo Molnar static const char * const event_type_descriptors[] = {
27886470930SIngo Molnar 	"",
27986470930SIngo Molnar 	"Hardware event",
28086470930SIngo Molnar 	"Software event",
28186470930SIngo Molnar 	"Tracepoint event",
28286470930SIngo Molnar 	"Hardware cache event",
28386470930SIngo Molnar };
28486470930SIngo Molnar 
28586470930SIngo Molnar /*
28686470930SIngo Molnar  * Print the help text for the event symbols:
28786470930SIngo Molnar  */
28886470930SIngo Molnar void print_events(void)
28986470930SIngo Molnar {
29086470930SIngo Molnar 	struct event_symbol *syms = event_symbols;
29186470930SIngo Molnar 	unsigned int i, type, prev_type = -1;
29286470930SIngo Molnar 
29386470930SIngo Molnar 	fprintf(stderr, "\n");
29486470930SIngo Molnar 	fprintf(stderr, "List of pre-defined events (to be used in -e):\n");
29586470930SIngo Molnar 
29686470930SIngo Molnar 	for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
29786470930SIngo Molnar 		type = syms->type + 1;
29886470930SIngo Molnar 		if (type > ARRAY_SIZE(event_type_descriptors))
29986470930SIngo Molnar 			type = 0;
30086470930SIngo Molnar 
30186470930SIngo Molnar 		if (type != prev_type)
30286470930SIngo Molnar 			fprintf(stderr, "\n");
30386470930SIngo Molnar 
30486470930SIngo Molnar 		fprintf(stderr, "  %-30s [%s]\n", syms->symbol,
30586470930SIngo Molnar 			event_type_descriptors[type]);
30686470930SIngo Molnar 
30786470930SIngo Molnar 		prev_type = type;
30886470930SIngo Molnar 	}
30986470930SIngo Molnar 
31086470930SIngo Molnar 	fprintf(stderr, "\n");
31186470930SIngo Molnar 	fprintf(stderr, "  %-30s [raw hardware event descriptor]\n",
31286470930SIngo Molnar 		"rNNN");
31386470930SIngo Molnar 	fprintf(stderr, "\n");
31486470930SIngo Molnar 
31586470930SIngo Molnar 	exit(129);
31686470930SIngo Molnar }
317