parse-events.c 27.9 KB
Newer Older
1
#include <linux/hw_breakpoint.h>
2
#include "util.h"
3
#include "../perf.h"
4
#include "evlist.h"
5
#include "evsel.h"
6 7 8
#include "parse-options.h"
#include "parse-events.h"
#include "exec_cmd.h"
9
#include "string.h"
10
#include "symbol.h"
11
#include "cache.h"
12
#include "header.h"
13
#include <lk/debugfs.h>
14
#include "parse-events-bison.h"
15
#define YY_EXTRA_TYPE int
16
#include "parse-events-flex.h"
17
#include "pmu.h"
18 19

#define MAX_NAME_LEN 100
20 21

struct event_symbol {
22 23
	const char	*symbol;
	const char	*alias;
24 25
};

26 27 28
#ifdef PARSER_DEBUG
extern int parse_events_debug;
#endif
29
int parse_events_parse(void *data, void *scanner);
30

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
	[PERF_COUNT_HW_CPU_CYCLES] = {
		.symbol = "cpu-cycles",
		.alias  = "cycles",
	},
	[PERF_COUNT_HW_INSTRUCTIONS] = {
		.symbol = "instructions",
		.alias  = "",
	},
	[PERF_COUNT_HW_CACHE_REFERENCES] = {
		.symbol = "cache-references",
		.alias  = "",
	},
	[PERF_COUNT_HW_CACHE_MISSES] = {
		.symbol = "cache-misses",
		.alias  = "",
	},
	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = {
		.symbol = "branch-instructions",
		.alias  = "branches",
	},
	[PERF_COUNT_HW_BRANCH_MISSES] = {
		.symbol = "branch-misses",
		.alias  = "",
	},
	[PERF_COUNT_HW_BUS_CYCLES] = {
		.symbol = "bus-cycles",
		.alias  = "",
	},
	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = {
		.symbol = "stalled-cycles-frontend",
		.alias  = "idle-cycles-frontend",
	},
	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = {
		.symbol = "stalled-cycles-backend",
		.alias  = "idle-cycles-backend",
	},
	[PERF_COUNT_HW_REF_CPU_CYCLES] = {
		.symbol = "ref-cycles",
		.alias  = "",
	},
};

static struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
	[PERF_COUNT_SW_CPU_CLOCK] = {
		.symbol = "cpu-clock",
		.alias  = "",
	},
	[PERF_COUNT_SW_TASK_CLOCK] = {
		.symbol = "task-clock",
		.alias  = "",
	},
	[PERF_COUNT_SW_PAGE_FAULTS] = {
		.symbol = "page-faults",
		.alias  = "faults",
	},
	[PERF_COUNT_SW_CONTEXT_SWITCHES] = {
		.symbol = "context-switches",
		.alias  = "cs",
	},
	[PERF_COUNT_SW_CPU_MIGRATIONS] = {
		.symbol = "cpu-migrations",
		.alias  = "migrations",
	},
	[PERF_COUNT_SW_PAGE_FAULTS_MIN] = {
		.symbol = "minor-faults",
		.alias  = "",
	},
	[PERF_COUNT_SW_PAGE_FAULTS_MAJ] = {
		.symbol = "major-faults",
		.alias  = "",
	},
	[PERF_COUNT_SW_ALIGNMENT_FAULTS] = {
		.symbol = "alignment-faults",
		.alias  = "",
	},
	[PERF_COUNT_SW_EMULATION_FAULTS] = {
		.symbol = "emulation-faults",
		.alias  = "",
	},
111 112
};

113 114
#define __PERF_EVENT_FIELD(config, name) \
	((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
115

116
#define PERF_EVENT_RAW(config)		__PERF_EVENT_FIELD(config, RAW)
117
#define PERF_EVENT_CONFIG(config)	__PERF_EVENT_FIELD(config, CONFIG)
118
#define PERF_EVENT_TYPE(config)		__PERF_EVENT_FIELD(config, TYPE)
119
#define PERF_EVENT_ID(config)		__PERF_EVENT_FIELD(config, EVENT)
120

121
#define for_each_subsystem(sys_dir, sys_dirent, sys_next)	       \
122
	while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next)	       \
123
	if (sys_dirent.d_type == DT_DIR &&				       \
124 125 126
	   (strcmp(sys_dirent.d_name, ".")) &&				       \
	   (strcmp(sys_dirent.d_name, "..")))

127 128 129 130 131
static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
{
	char evt_path[MAXPATHLEN];
	int fd;

132
	snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path,
133 134 135 136 137 138 139 140 141
			sys_dir->d_name, evt_dir->d_name);
	fd = open(evt_path, O_RDONLY);
	if (fd < 0)
		return -EINVAL;
	close(fd);

	return 0;
}

142
#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next)	       \
143
	while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next)        \
144
	if (evt_dirent.d_type == DT_DIR &&				       \
145
	   (strcmp(evt_dirent.d_name, ".")) &&				       \
146 147
	   (strcmp(evt_dirent.d_name, "..")) &&				       \
	   (!tp_event_has_id(&sys_dirent, &evt_dirent)))
148

L
Li Zefan 已提交
149
#define MAX_EVENT_LENGTH 512
150 151


152
struct tracepoint_path *tracepoint_id_to_path(u64 config)
153
{
154
	struct tracepoint_path *path = NULL;
155 156
	DIR *sys_dir, *evt_dir;
	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
157
	char id_buf[24];
E
Eric Dumazet 已提交
158
	int fd;
159 160
	u64 id;
	char evt_path[MAXPATHLEN];
E
Eric Dumazet 已提交
161
	char dir_path[MAXPATHLEN];
162

163
	if (debugfs_valid_mountpoint(tracing_events_path))
164
		return NULL;
165

166
	sys_dir = opendir(tracing_events_path);
167
	if (!sys_dir)
E
Eric Dumazet 已提交
168
		return NULL;
169 170

	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
E
Eric Dumazet 已提交
171

172
		snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
E
Eric Dumazet 已提交
173 174 175
			 sys_dirent.d_name);
		evt_dir = opendir(dir_path);
		if (!evt_dir)
176
			continue;
E
Eric Dumazet 已提交
177

178
		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
E
Eric Dumazet 已提交
179 180

			snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
181
				 evt_dirent.d_name);
E
Eric Dumazet 已提交
182
			fd = open(evt_path, O_RDONLY);
183 184 185 186 187 188 189 190 191 192 193
			if (fd < 0)
				continue;
			if (read(fd, id_buf, sizeof(id_buf)) < 0) {
				close(fd);
				continue;
			}
			close(fd);
			id = atoll(id_buf);
			if (id == config) {
				closedir(evt_dir);
				closedir(sys_dir);
194
				path = zalloc(sizeof(*path));
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
				path->system = malloc(MAX_EVENT_LENGTH);
				if (!path->system) {
					free(path);
					return NULL;
				}
				path->name = malloc(MAX_EVENT_LENGTH);
				if (!path->name) {
					free(path->system);
					free(path);
					return NULL;
				}
				strncpy(path->system, sys_dirent.d_name,
					MAX_EVENT_LENGTH);
				strncpy(path->name, evt_dirent.d_name,
					MAX_EVENT_LENGTH);
				return path;
211 212 213 214 215 216
			}
		}
		closedir(evt_dir);
	}

	closedir(sys_dir);
217 218 219
	return NULL;
}

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
struct tracepoint_path *tracepoint_name_to_path(const char *name)
{
	struct tracepoint_path *path = zalloc(sizeof(*path));
	char *str = strchr(name, ':');

	if (path == NULL || str == NULL) {
		free(path);
		return NULL;
	}

	path->system = strndup(name, str - name);
	path->name = strdup(str+1);

	if (path->system == NULL || path->name == NULL) {
		free(path->system);
		free(path->name);
		free(path);
		path = NULL;
	}

	return path;
}

243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
const char *event_type(int type)
{
	switch (type) {
	case PERF_TYPE_HARDWARE:
		return "hardware";

	case PERF_TYPE_SOFTWARE:
		return "software";

	case PERF_TYPE_TRACEPOINT:
		return "tracepoint";

	case PERF_TYPE_HW_CACHE:
		return "hardware-cache";

	default:
		break;
	}

	return "unknown";
}

Y
Yan, Zheng 已提交
265 266 267 268 269


static int __add_event(struct list_head **_list, int *idx,
		       struct perf_event_attr *attr,
		       char *name, struct cpu_map *cpus)
270 271
{
	struct perf_evsel *evsel;
272 273 274 275 276 277 278 279
	struct list_head *list = *_list;

	if (!list) {
		list = malloc(sizeof(*list));
		if (!list)
			return -ENOMEM;
		INIT_LIST_HEAD(list);
	}
280 281 282 283

	event_attr_init(attr);

	evsel = perf_evsel__new(attr, (*idx)++);
284 285
	if (!evsel) {
		free(list);
286
		return -ENOMEM;
287
	}
288

Y
Yan, Zheng 已提交
289
	evsel->cpus = cpus;
290 291
	if (name)
		evsel->name = strdup(name);
292 293
	list_add_tail(&evsel->node, list);
	*_list = list;
294 295 296
	return 0;
}

Y
Yan, Zheng 已提交
297 298 299 300 301 302
static int add_event(struct list_head **_list, int *idx,
		     struct perf_event_attr *attr, char *name)
{
	return __add_event(_list, idx, attr, name, NULL);
}

303
static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
304 305
{
	int i, j;
306
	int n, longest = -1;
307 308

	for (i = 0; i < size; i++) {
309
		for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) {
310
			n = strlen(names[i][j]);
311
			if (n > longest && !strncasecmp(str, names[i][j], n))
312 313
				longest = n;
		}
314
		if (longest > 0)
315
			return i;
316 317
	}

318
	return -1;
319 320
}

321
int parse_events_add_cache(struct list_head **list, int *idx,
322
			   char *type, char *op_result1, char *op_result2)
323
{
324 325
	struct perf_event_attr attr;
	char name[MAX_NAME_LEN];
326
	int cache_type = -1, cache_op = -1, cache_result = -1;
327 328
	char *op_result[2] = { op_result1, op_result2 };
	int i, n;
329 330 331 332 333

	/*
	 * No fallback - if we cannot get a clear cache type
	 * then bail out:
	 */
334
	cache_type = parse_aliases(type, perf_evsel__hw_cache,
335
				   PERF_COUNT_HW_CACHE_MAX);
336
	if (cache_type == -1)
337 338 339
		return -EINVAL;

	n = snprintf(name, MAX_NAME_LEN, "%s", type);
340

341 342 343
	for (i = 0; (i < 2) && (op_result[i]); i++) {
		char *str = op_result[i];

344
		n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str);
345 346

		if (cache_op == -1) {
347
			cache_op = parse_aliases(str, perf_evsel__hw_cache_op,
348
						 PERF_COUNT_HW_CACHE_OP_MAX);
349
			if (cache_op >= 0) {
350
				if (!perf_evsel__is_cache_op_valid(cache_type, cache_op))
351
					return -EINVAL;
352 353 354 355 356
				continue;
			}
		}

		if (cache_result == -1) {
357 358
			cache_result = parse_aliases(str, perf_evsel__hw_cache_result,
						     PERF_COUNT_HW_CACHE_RESULT_MAX);
359 360 361 362
			if (cache_result >= 0)
				continue;
		}
	}
363 364 365 366

	/*
	 * Fall back to reads:
	 */
367 368
	if (cache_op == -1)
		cache_op = PERF_COUNT_HW_CACHE_OP_READ;
369 370 371 372 373 374 375

	/*
	 * Fall back to accesses:
	 */
	if (cache_result == -1)
		cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS;

376 377 378 379
	memset(&attr, 0, sizeof(attr));
	attr.config = cache_type | (cache_op << 8) | (cache_result << 16);
	attr.type = PERF_TYPE_HW_CACHE;
	return add_event(list, idx, &attr, name);
380 381
}

382
static int add_tracepoint(struct list_head **listp, int *idx,
383
			  char *sys_name, char *evt_name)
384
{
385 386
	struct perf_evsel *evsel;
	struct list_head *list = *listp;
387

388 389 390 391 392
	if (!list) {
		list = malloc(sizeof(*list));
		if (!list)
			return -ENOMEM;
		INIT_LIST_HEAD(list);
393 394
	}

395 396 397 398 399
	evsel = perf_evsel__newtp(sys_name, evt_name, (*idx)++);
	if (!evsel) {
		free(list);
		return -ENOMEM;
	}
400

401 402 403
	list_add_tail(&evsel->node, list);
	*listp = list;
	return 0;
404 405
}

406 407
static int add_tracepoint_multi_event(struct list_head **list, int *idx,
				      char *sys_name, char *evt_name)
408 409 410 411
{
	char evt_path[MAXPATHLEN];
	struct dirent *evt_ent;
	DIR *evt_dir;
412
	int ret = 0;
413

414
	snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name);
415 416 417
	evt_dir = opendir(evt_path);
	if (!evt_dir) {
		perror("Can't open event dir");
418
		return -1;
419 420
	}

421
	while (!ret && (evt_ent = readdir(evt_dir))) {
422 423 424 425 426 427
		if (!strcmp(evt_ent->d_name, ".")
		    || !strcmp(evt_ent->d_name, "..")
		    || !strcmp(evt_ent->d_name, "enable")
		    || !strcmp(evt_ent->d_name, "filter"))
			continue;

428
		if (!strglobmatch(evt_ent->d_name, evt_name))
429 430
			continue;

431
		ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name);
432 433
	}

434
	closedir(evt_dir);
435
	return ret;
436 437
}

438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
static int add_tracepoint_event(struct list_head **list, int *idx,
				char *sys_name, char *evt_name)
{
	return strpbrk(evt_name, "*?") ?
	       add_tracepoint_multi_event(list, idx, sys_name, evt_name) :
	       add_tracepoint(list, idx, sys_name, evt_name);
}

static int add_tracepoint_multi_sys(struct list_head **list, int *idx,
				    char *sys_name, char *evt_name)
{
	struct dirent *events_ent;
	DIR *events_dir;
	int ret = 0;

	events_dir = opendir(tracing_events_path);
	if (!events_dir) {
		perror("Can't open event dir");
		return -1;
	}

	while (!ret && (events_ent = readdir(events_dir))) {
		if (!strcmp(events_ent->d_name, ".")
		    || !strcmp(events_ent->d_name, "..")
		    || !strcmp(events_ent->d_name, "enable")
		    || !strcmp(events_ent->d_name, "header_event")
		    || !strcmp(events_ent->d_name, "header_page"))
			continue;

		if (!strglobmatch(events_ent->d_name, sys_name))
			continue;

		ret = add_tracepoint_event(list, idx, events_ent->d_name,
					   evt_name);
	}

	closedir(events_dir);
	return ret;
}

478
int parse_events_add_tracepoint(struct list_head **list, int *idx,
479
				char *sys, char *event)
480
{
481
	int ret;
482

483 484 485
	ret = debugfs_valid_mountpoint(tracing_events_path);
	if (ret)
		return ret;
486

487 488 489 490
	if (strpbrk(sys, "*?"))
		return add_tracepoint_multi_sys(list, idx, sys, event);
	else
		return add_tracepoint_event(list, idx, sys, event);
491 492
}

493 494
static int
parse_breakpoint_type(const char *type, struct perf_event_attr *attr)
495 496 497 498
{
	int i;

	for (i = 0; i < 3; i++) {
499
		if (!type || !type[i])
500 501
			break;

502 503 504 505 506 507 508 509
#define CHECK_SET_TYPE(bit)		\
do {					\
	if (attr->bp_type & bit)	\
		return -EINVAL;		\
	else				\
		attr->bp_type |= bit;	\
} while (0)

510 511
		switch (type[i]) {
		case 'r':
512
			CHECK_SET_TYPE(HW_BREAKPOINT_R);
513 514
			break;
		case 'w':
515
			CHECK_SET_TYPE(HW_BREAKPOINT_W);
516 517
			break;
		case 'x':
518
			CHECK_SET_TYPE(HW_BREAKPOINT_X);
519 520
			break;
		default:
521
			return -EINVAL;
522 523
		}
	}
524

525 526
#undef CHECK_SET_TYPE

527 528 529
	if (!attr->bp_type) /* Default */
		attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;

530
	return 0;
531 532
}

533
int parse_events_add_breakpoint(struct list_head **list, int *idx,
534
				void *ptr, char *type)
535
{
536
	struct perf_event_attr attr;
537

538
	memset(&attr, 0, sizeof(attr));
539
	attr.bp_addr = (unsigned long) ptr;
540

541 542
	if (parse_breakpoint_type(type, &attr))
		return -EINVAL;
543

544 545 546 547
	/*
	 * We should find a nice way to override the access length
	 * Provide some defaults for now
	 */
548 549
	if (attr.bp_type == HW_BREAKPOINT_X)
		attr.bp_len = sizeof(long);
550
	else
551
		attr.bp_len = HW_BREAKPOINT_LEN_4;
552

553
	attr.type = PERF_TYPE_BREAKPOINT;
554
	attr.sample_period = 1;
555

556
	return add_event(list, idx, &attr, NULL);
557 558
}

559
static int config_term(struct perf_event_attr *attr,
560
		       struct parse_events_term *term)
561
{
562 563 564 565 566 567 568
#define CHECK_TYPE_VAL(type)					\
do {								\
	if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val)	\
		return -EINVAL;					\
} while (0)

	switch (term->type_term) {
569
	case PARSE_EVENTS__TERM_TYPE_CONFIG:
570
		CHECK_TYPE_VAL(NUM);
571 572 573
		attr->config = term->val.num;
		break;
	case PARSE_EVENTS__TERM_TYPE_CONFIG1:
574
		CHECK_TYPE_VAL(NUM);
575 576 577
		attr->config1 = term->val.num;
		break;
	case PARSE_EVENTS__TERM_TYPE_CONFIG2:
578
		CHECK_TYPE_VAL(NUM);
579 580 581
		attr->config2 = term->val.num;
		break;
	case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
582
		CHECK_TYPE_VAL(NUM);
583 584 585 586 587 588 589 590
		attr->sample_period = term->val.num;
		break;
	case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
		/*
		 * TODO uncomment when the field is available
		 * attr->branch_sample_type = term->val.num;
		 */
		break;
591 592 593
	case PARSE_EVENTS__TERM_TYPE_NAME:
		CHECK_TYPE_VAL(STR);
		break;
594 595 596
	default:
		return -EINVAL;
	}
597

598
	return 0;
599
#undef CHECK_TYPE_VAL
600 601 602 603 604
}

static int config_attr(struct perf_event_attr *attr,
		       struct list_head *head, int fail)
{
605
	struct parse_events_term *term;
606 607 608 609 610 611 612 613

	list_for_each_entry(term, head, list)
		if (config_term(attr, term) && fail)
			return -EINVAL;

	return 0;
}

614
int parse_events_add_numeric(struct list_head **list, int *idx,
615
			     u32 type, u64 config,
616
			     struct list_head *head_config)
617
{
618
	struct perf_event_attr attr;
619

620 621 622
	memset(&attr, 0, sizeof(attr));
	attr.type = type;
	attr.config = config;
623 624 625 626 627

	if (head_config &&
	    config_attr(&attr, head_config, 1))
		return -EINVAL;

628
	return add_event(list, idx, &attr, NULL);
629
}
630

631
static int parse_events__is_name_term(struct parse_events_term *term)
632 633 634 635
{
	return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME;
}

636
static char *pmu_event_name(struct list_head *head_terms)
637
{
638
	struct parse_events_term *term;
639 640 641 642 643

	list_for_each_entry(term, head_terms, list)
		if (parse_events__is_name_term(term))
			return term->val.str;

644
	return NULL;
645 646
}

647
int parse_events_add_pmu(struct list_head **list, int *idx,
648 649 650 651 652 653 654 655 656 657 658
			 char *name, struct list_head *head_config)
{
	struct perf_event_attr attr;
	struct perf_pmu *pmu;

	pmu = perf_pmu__find(name);
	if (!pmu)
		return -EINVAL;

	memset(&attr, 0, sizeof(attr));

659 660 661
	if (perf_pmu__check_alias(pmu, head_config))
		return -EINVAL;

662 663 664 665 666 667 668 669 670
	/*
	 * Configure hardcoded terms first, no need to check
	 * return value when called with fail == 0 ;)
	 */
	config_attr(&attr, head_config, 0);

	if (perf_pmu__config(pmu, &attr, head_config))
		return -EINVAL;

Y
Yan, Zheng 已提交
671 672
	return __add_event(list, idx, &attr, pmu_event_name(head_config),
			   pmu->cpus);
673 674
}

675 676
int parse_events__modifier_group(struct list_head *list,
				 char *event_mod)
677
{
678 679 680
	return parse_events__modifier_event(list, event_mod, true);
}

681
void parse_events__set_leader(char *name, struct list_head *list)
682 683 684
{
	struct perf_evsel *leader;

685 686
	__perf_evlist__set_leader(list);
	leader = list_entry(list->next, struct perf_evsel, node);
687
	leader->group_name = name ? strdup(name) : NULL;
688 689
}

690 691 692 693 694
void parse_events_update_lists(struct list_head *list_event,
			       struct list_head *list_all)
{
	/*
	 * Called for single event definition. Update the
695
	 * 'all event' list, and reinit the 'single event'
696 697 698
	 * list, for next event definition.
	 */
	list_splice_tail(list_event, list_all);
699
	free(list_event);
700 701
}

702 703 704 705 706 707 708 709 710 711 712 713
struct event_modifier {
	int eu;
	int ek;
	int eh;
	int eH;
	int eG;
	int precise;
	int exclude_GH;
};

static int get_event_modifier(struct event_modifier *mod, char *str,
			       struct perf_evsel *evsel)
714
{
715 716 717 718 719 720
	int eu = evsel ? evsel->attr.exclude_user : 0;
	int ek = evsel ? evsel->attr.exclude_kernel : 0;
	int eh = evsel ? evsel->attr.exclude_hv : 0;
	int eH = evsel ? evsel->attr.exclude_host : 0;
	int eG = evsel ? evsel->attr.exclude_guest : 0;
	int precise = evsel ? evsel->attr.precise_ip : 0;
721

722 723 724 725
	int exclude = eu | ek | eh;
	int exclude_GH = evsel ? evsel->exclude_GH : 0;

	memset(mod, 0, sizeof(*mod));
726

727
	while (*str) {
P
Peter Zijlstra 已提交
728 729 730
		if (*str == 'u') {
			if (!exclude)
				exclude = eu = ek = eh = 1;
731
			eu = 0;
P
Peter Zijlstra 已提交
732 733 734
		} else if (*str == 'k') {
			if (!exclude)
				exclude = eu = ek = eh = 1;
735
			ek = 0;
P
Peter Zijlstra 已提交
736 737 738
		} else if (*str == 'h') {
			if (!exclude)
				exclude = eu = ek = eh = 1;
739
			eh = 0;
740 741 742 743 744 745 746 747
		} else if (*str == 'G') {
			if (!exclude_GH)
				exclude_GH = eG = eH = 1;
			eG = 0;
		} else if (*str == 'H') {
			if (!exclude_GH)
				exclude_GH = eG = eH = 1;
			eH = 0;
P
Peter Zijlstra 已提交
748 749
		} else if (*str == 'p') {
			precise++;
750 751 752
			/* use of precise requires exclude_guest */
			if (!exclude_GH)
				eG = 1;
P
Peter Zijlstra 已提交
753
		} else
754
			break;
P
Peter Zijlstra 已提交
755

756
		++str;
757
	}
758

759 760 761 762 763 764 765 766 767 768 769 770
	/*
	 * precise ip:
	 *
	 *  0 - SAMPLE_IP can have arbitrary skid
	 *  1 - SAMPLE_IP must have constant skid
	 *  2 - SAMPLE_IP requested to have 0 skid
	 *  3 - SAMPLE_IP must have 0 skid
	 *
	 *  See also PERF_RECORD_MISC_EXACT_IP
	 */
	if (precise > 3)
		return -EINVAL;
771

772 773 774 775 776 777 778 779 780 781
	mod->eu = eu;
	mod->ek = ek;
	mod->eh = eh;
	mod->eH = eH;
	mod->eG = eG;
	mod->precise = precise;
	mod->exclude_GH = exclude_GH;
	return 0;
}

782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802
/*
 * Basic modifier sanity check to validate it contains only one
 * instance of any modifier (apart from 'p') present.
 */
static int check_modifier(char *str)
{
	char *p = str;

	/* The sizeof includes 0 byte as well. */
	if (strlen(str) > (sizeof("ukhGHppp") - 1))
		return -1;

	while (*p) {
		if (*p != 'p' && strchr(p + 1, *p))
			return -1;
		p++;
	}

	return 0;
}

803 804 805 806 807 808 809 810
int parse_events__modifier_event(struct list_head *list, char *str, bool add)
{
	struct perf_evsel *evsel;
	struct event_modifier mod;

	if (str == NULL)
		return 0;

811 812 813
	if (check_modifier(str))
		return -EINVAL;

814 815 816
	if (!add && get_event_modifier(&mod, str, NULL))
		return -EINVAL;

817
	list_for_each_entry(evsel, list, node) {
818 819 820 821 822 823 824 825 826 827 828

		if (add && get_event_modifier(&mod, str, evsel))
			return -EINVAL;

		evsel->attr.exclude_user   = mod.eu;
		evsel->attr.exclude_kernel = mod.ek;
		evsel->attr.exclude_hv     = mod.eh;
		evsel->attr.precise_ip     = mod.precise;
		evsel->attr.exclude_host   = mod.eH;
		evsel->attr.exclude_guest  = mod.eG;
		evsel->exclude_GH          = mod.exclude_GH;
829
	}
830

831 832
	return 0;
}
833

834 835 836 837 838 839 840 841 842 843 844 845
int parse_events_name(struct list_head *list, char *name)
{
	struct perf_evsel *evsel;

	list_for_each_entry(evsel, list, node) {
		if (!evsel->name)
			evsel->name = strdup(name);
	}

	return 0;
}

846
static int parse_events__scanner(const char *str, void *data, int start_token)
847
{
848
	YY_BUFFER_STATE buffer;
849
	void *scanner;
850
	int ret;
851

852
	ret = parse_events_lex_init_extra(start_token, &scanner);
853 854 855 856
	if (ret)
		return ret;

	buffer = parse_events__scan_string(str, scanner);
857

858 859 860
#ifdef PARSER_DEBUG
	parse_events_debug = 1;
#endif
861 862 863 864 865 866 867
	ret = parse_events_parse(data, scanner);

	parse_events__flush_buffer(buffer, scanner);
	parse_events__delete_buffer(buffer, scanner);
	parse_events_lex_destroy(scanner);
	return ret;
}
868

869 870 871 872 873
/*
 * parse event config string, return a list of event terms.
 */
int parse_events_terms(struct list_head *terms, const char *str)
{
874
	struct parse_events_terms data = {
875 876 877 878 879 880 881 882 883 884 885
		.terms = NULL,
	};
	int ret;

	ret = parse_events__scanner(str, &data, PE_START_TERMS);
	if (!ret) {
		list_splice(data.terms, terms);
		free(data.terms);
		return 0;
	}

886 887
	if (data.terms)
		parse_events__free_terms(data.terms);
888 889 890
	return ret;
}

891
int parse_events(struct perf_evlist *evlist, const char *str)
892
{
893
	struct parse_events_evlist data = {
894 895 896 897
		.list = LIST_HEAD_INIT(data.list),
		.idx  = evlist->nr_entries,
	};
	int ret;
898

899
	ret = parse_events__scanner(str, &data, PE_START_EVENTS);
900
	if (!ret) {
901 902
		int entries = data.idx - evlist->nr_entries;
		perf_evlist__splice_list_tail(evlist, &data.list, entries);
903
		evlist->nr_groups += data.nr_groups;
904 905
		return 0;
	}
906

907 908 909 910 911
	/*
	 * There are 2 users - builtin-record and builtin-test objects.
	 * Both call perf_evlist__delete in case of error, so we dont
	 * need to bother.
	 */
912
	return ret;
913 914
}

915
int parse_events_option(const struct option *opt, const char *str,
916
			int unset __maybe_unused)
917 918
{
	struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
919
	int ret = parse_events(evlist, str);
920 921 922 923 924 925

	if (ret) {
		fprintf(stderr, "invalid or unsupported event: '%s'\n", str);
		fprintf(stderr, "Run 'perf list' for a list of valid events\n");
	}
	return ret;
926 927
}

928
int parse_filter(const struct option *opt, const char *str,
929
		 int unset __maybe_unused)
L
Li Zefan 已提交
930
{
931
	struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
932
	struct perf_evsel *last = NULL;
L
Li Zefan 已提交
933

934
	if (evlist->nr_entries > 0)
935
		last = perf_evlist__last(evlist);
936 937

	if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) {
L
Li Zefan 已提交
938 939 940 941 942
		fprintf(stderr,
			"-F option should follow a -e tracepoint option\n");
		return -1;
	}

943 944
	last->filter = strdup(str);
	if (last->filter == NULL) {
L
Li Zefan 已提交
945 946 947 948 949 950 951
		fprintf(stderr, "not enough memory to hold filter string\n");
		return -1;
	}

	return 0;
}

952 953 954 955 956
static const char * const event_type_descriptors[] = {
	"Hardware event",
	"Software event",
	"Tracepoint event",
	"Hardware cache event",
957 958
	"Raw hardware event descriptor",
	"Hardware breakpoint",
959 960
};

961 962 963 964
/*
 * Print the events from <debugfs_mount_point>/tracing/events
 */

965 966
void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
			     bool name_only)
967 968 969 970
{
	DIR *sys_dir, *evt_dir;
	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
	char evt_path[MAXPATHLEN];
E
Eric Dumazet 已提交
971
	char dir_path[MAXPATHLEN];
972

973
	if (debugfs_valid_mountpoint(tracing_events_path))
974 975
		return;

976
	sys_dir = opendir(tracing_events_path);
977
	if (!sys_dir)
E
Eric Dumazet 已提交
978
		return;
979 980

	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
981 982 983
		if (subsys_glob != NULL && 
		    !strglobmatch(sys_dirent.d_name, subsys_glob))
			continue;
E
Eric Dumazet 已提交
984

985
		snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
E
Eric Dumazet 已提交
986 987 988
			 sys_dirent.d_name);
		evt_dir = opendir(dir_path);
		if (!evt_dir)
989
			continue;
E
Eric Dumazet 已提交
990

991
		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
992 993 994 995
			if (event_glob != NULL && 
			    !strglobmatch(evt_dirent.d_name, event_glob))
				continue;

996 997 998 999 1000
			if (name_only) {
				printf("%s:%s ", sys_dirent.d_name, evt_dirent.d_name);
				continue;
			}

1001 1002
			snprintf(evt_path, MAXPATHLEN, "%s:%s",
				 sys_dirent.d_name, evt_dirent.d_name);
1003
			printf("  %-50s [%s]\n", evt_path,
1004
				event_type_descriptors[PERF_TYPE_TRACEPOINT]);
1005 1006 1007 1008 1009 1010
		}
		closedir(evt_dir);
	}
	closedir(sys_dir);
}

1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
/*
 * Check whether event is in <debugfs_mount_point>/tracing/events
 */

int is_valid_tracepoint(const char *event_string)
{
	DIR *sys_dir, *evt_dir;
	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
	char evt_path[MAXPATHLEN];
	char dir_path[MAXPATHLEN];

1022
	if (debugfs_valid_mountpoint(tracing_events_path))
1023 1024
		return 0;

1025
	sys_dir = opendir(tracing_events_path);
1026 1027 1028 1029 1030
	if (!sys_dir)
		return 0;

	for_each_subsystem(sys_dir, sys_dirent, sys_next) {

1031
		snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
			 sys_dirent.d_name);
		evt_dir = opendir(dir_path);
		if (!evt_dir)
			continue;

		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
			snprintf(evt_path, MAXPATHLEN, "%s:%s",
				 sys_dirent.d_name, evt_dirent.d_name);
			if (!strcmp(evt_path, event_string)) {
				closedir(evt_dir);
				closedir(sys_dir);
				return 1;
			}
		}
		closedir(evt_dir);
	}
	closedir(sys_dir);
	return 0;
}

1052 1053
static void __print_events_type(u8 type, struct event_symbol *syms,
				unsigned max)
1054 1055
{
	char name[64];
1056
	unsigned i;
1057

1058
	for (i = 0; i < max ; i++, syms++) {
1059 1060 1061 1062 1063 1064
		if (strlen(syms->alias))
			snprintf(name, sizeof(name),  "%s OR %s",
				 syms->symbol, syms->alias);
		else
			snprintf(name, sizeof(name), "%s", syms->symbol);

1065
		printf("  %-50s [%s]\n", name,
1066 1067 1068 1069
			event_type_descriptors[type]);
	}
}

1070 1071 1072 1073 1074 1075 1076 1077
void print_events_type(u8 type)
{
	if (type == PERF_TYPE_SOFTWARE)
		__print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX);
	else
		__print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX);
}

1078
int print_hwcache_events(const char *event_glob, bool name_only)
1079 1080
{
	unsigned int type, op, i, printed = 0;
1081
	char name[64];
1082 1083 1084 1085

	for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
		for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
			/* skip invalid cache type */
1086
			if (!perf_evsel__is_cache_op_valid(type, op))
1087 1088 1089
				continue;

			for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
1090 1091
				__perf_evsel__hw_cache_type_op_res_name(type, op, i,
									name, sizeof(name));
1092
				if (event_glob != NULL && !strglobmatch(name, event_glob))
1093 1094
					continue;

1095 1096 1097 1098 1099
				if (name_only)
					printf("%s ", name);
				else
					printf("  %-50s [%s]\n", name,
					       event_type_descriptors[PERF_TYPE_HW_CACHE]);
1100 1101 1102 1103 1104 1105 1106 1107
				++printed;
			}
		}
	}

	return printed;
}

1108
static void print_symbol_events(const char *event_glob, unsigned type,
1109 1110
				struct event_symbol *syms, unsigned max,
				bool name_only)
1111
{
1112
	unsigned i, printed = 0;
1113
	char name[MAX_NAME_LEN];
1114

1115
	for (i = 0; i < max; i++, syms++) {
1116 1117 1118 1119 1120

		if (event_glob != NULL && 
		    !(strglobmatch(syms->symbol, event_glob) ||
		      (syms->alias && strglobmatch(syms->alias, event_glob))))
			continue;
1121

1122 1123 1124 1125 1126
		if (name_only) {
			printf("%s ", syms->symbol);
			continue;
		}

1127
		if (strlen(syms->alias))
1128
			snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
1129
		else
1130
			strncpy(name, syms->symbol, MAX_NAME_LEN);
1131

1132 1133 1134
		printf("  %-50s [%s]\n", name, event_type_descriptors[type]);

		printed++;
1135 1136
	}

1137
	if (printed)
1138
		printf("\n");
1139 1140 1141 1142 1143
}

/*
 * Print the help text for the event symbols:
 */
1144
void print_events(const char *event_glob, bool name_only)
1145
{
1146 1147 1148 1149
	if (!name_only) {
		printf("\n");
		printf("List of pre-defined events (to be used in -e):\n");
	}
1150 1151

	print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
1152
			    event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
1153 1154

	print_symbol_events(event_glob, PERF_TYPE_SOFTWARE,
1155
			    event_symbols_sw, PERF_COUNT_SW_MAX, name_only);
1156

1157
	print_hwcache_events(event_glob, name_only);
1158 1159 1160

	if (event_glob != NULL)
		return;
1161

1162 1163 1164 1165 1166 1167 1168 1169
	if (!name_only) {
		printf("\n");
		printf("  %-50s [%s]\n",
		       "rNNN",
		       event_type_descriptors[PERF_TYPE_RAW]);
		printf("  %-50s [%s]\n",
		       "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
		       event_type_descriptors[PERF_TYPE_RAW]);
1170
		printf("   (see 'man perf-list' on how to encode it)\n");
1171 1172 1173 1174
		printf("\n");

		printf("  %-50s [%s]\n",
		       "mem:<addr>[:access]",
1175
			event_type_descriptors[PERF_TYPE_BREAKPOINT]);
1176 1177
		printf("\n");
	}
1178

1179
	print_tracepoint_events(NULL, NULL, name_only);
1180
}
1181

1182
int parse_events__is_hardcoded_term(struct parse_events_term *term)
1183
{
1184
	return term->type_term != PARSE_EVENTS__TERM_TYPE_USER;
1185 1186
}

1187
static int new_term(struct parse_events_term **_term, int type_val,
1188
		    int type_term, char *config,
1189
		    char *str, u64 num)
1190
{
1191
	struct parse_events_term *term;
1192 1193 1194 1195 1196 1197

	term = zalloc(sizeof(*term));
	if (!term)
		return -ENOMEM;

	INIT_LIST_HEAD(&term->list);
1198 1199
	term->type_val  = type_val;
	term->type_term = type_term;
1200 1201
	term->config = config;

1202
	switch (type_val) {
1203 1204 1205 1206 1207 1208 1209
	case PARSE_EVENTS__TERM_TYPE_NUM:
		term->val.num = num;
		break;
	case PARSE_EVENTS__TERM_TYPE_STR:
		term->val.str = str;
		break;
	default:
1210
		free(term);
1211 1212 1213 1214 1215 1216 1217
		return -EINVAL;
	}

	*_term = term;
	return 0;
}

1218
int parse_events_term__num(struct parse_events_term **term,
1219
			   int type_term, char *config, u64 num)
1220 1221 1222 1223 1224
{
	return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term,
			config, NULL, num);
}

1225
int parse_events_term__str(struct parse_events_term **term,
1226 1227 1228 1229 1230 1231
			   int type_term, char *config, char *str)
{
	return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term,
			config, str, 0);
}

1232
int parse_events_term__sym_hw(struct parse_events_term **term,
1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249
			      char *config, unsigned idx)
{
	struct event_symbol *sym;

	BUG_ON(idx >= PERF_COUNT_HW_MAX);
	sym = &event_symbols_hw[idx];

	if (config)
		return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
				PARSE_EVENTS__TERM_TYPE_USER, config,
				(char *) sym->symbol, 0);
	else
		return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
				PARSE_EVENTS__TERM_TYPE_USER,
				(char *) "event", (char *) sym->symbol, 0);
}

1250 1251
int parse_events_term__clone(struct parse_events_term **new,
			     struct parse_events_term *term)
1252 1253 1254 1255 1256
{
	return new_term(new, term->type_val, term->type_term, term->config,
			term->val.str, term->val.num);
}

1257 1258
void parse_events__free_terms(struct list_head *terms)
{
1259
	struct parse_events_term *term, *h;
1260 1261 1262 1263

	list_for_each_entry_safe(term, h, terms, list)
		free(term);
}