parse-events.c 23.9 KB
Newer Older
1
#include "../../../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 "debugfs.h"
14 15

struct event_symbol {
16 17 18 19
	u8		type;
	u64		config;
	const char	*symbol;
	const char	*alias;
20 21
};

22 23 24 25 26 27
enum event_result {
	EVT_FAILED,
	EVT_HANDLED,
	EVT_HANDLED_ALL
};

28 29
char debugfs_path[MAXPATHLEN];

30 31
#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x
#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
32

33
static struct event_symbol event_symbols[] = {
34
  { CHW(CPU_CYCLES),		"cpu-cycles",		"cycles"	},
35
  { CHW(STALLED_CYCLES),	"stalled-cycles",	"idle-cycles"	},
36 37 38 39 40 41 42 43 44
  { CHW(INSTRUCTIONS),		"instructions",		""		},
  { CHW(CACHE_REFERENCES),	"cache-references",	""		},
  { CHW(CACHE_MISSES),		"cache-misses",		""		},
  { CHW(BRANCH_INSTRUCTIONS),	"branch-instructions",	"branches"	},
  { CHW(BRANCH_MISSES),		"branch-misses",	""		},
  { CHW(BUS_CYCLES),		"bus-cycles",		""		},

  { CSW(CPU_CLOCK),		"cpu-clock",		""		},
  { CSW(TASK_CLOCK),		"task-clock",		""		},
45
  { CSW(PAGE_FAULTS),		"page-faults",		"faults"	},
46 47 48 49
  { CSW(PAGE_FAULTS_MIN),	"minor-faults",		""		},
  { CSW(PAGE_FAULTS_MAJ),	"major-faults",		""		},
  { CSW(CONTEXT_SWITCHES),	"context-switches",	"cs"		},
  { CSW(CPU_MIGRATIONS),	"cpu-migrations",	"migrations"	},
50 51
  { CSW(ALIGNMENT_FAULTS),	"alignment-faults",	""		},
  { CSW(EMULATION_FAULTS),	"emulation-faults",	""		},
52 53
};

54 55
#define __PERF_EVENT_FIELD(config, name) \
	((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
56

57
#define PERF_EVENT_RAW(config)		__PERF_EVENT_FIELD(config, RAW)
58
#define PERF_EVENT_CONFIG(config)	__PERF_EVENT_FIELD(config, CONFIG)
59
#define PERF_EVENT_TYPE(config)		__PERF_EVENT_FIELD(config, TYPE)
60
#define PERF_EVENT_ID(config)		__PERF_EVENT_FIELD(config, EVENT)
61

62
static const char *hw_event_names[] = {
63
	"cycles",
64
	"instructions",
65 66
	"cache-references",
	"cache-misses",
67
	"branches",
68 69
	"branch-misses",
	"bus-cycles",
70
	"stalled-cycles",
71 72
};

73
static const char *sw_event_names[] = {
74 75
	"cpu-clock",
	"task-clock",
76 77 78 79 80
	"page-faults",
	"context-switches",
	"CPU-migrations",
	"minor-faults",
	"major-faults",
81 82
	"alignment-faults",
	"emulation-faults",
83 84
};

85 86
#define MAX_ALIASES 8

87
static const char *hw_cache[][MAX_ALIASES] = {
88 89
 { "L1-dcache",	"l1-d",		"l1d",		"L1-data",		},
 { "L1-icache",	"l1-i",		"l1i",		"L1-instruction",	},
90 91 92 93
 { "LLC",	"L2"							},
 { "dTLB",	"d-tlb",	"Data-TLB",				},
 { "iTLB",	"i-tlb",	"Instruction-TLB",			},
 { "branch",	"branches",	"bpu",		"btb",		"bpc",	},
94 95
};

96
static const char *hw_cache_op[][MAX_ALIASES] = {
97 98 99
 { "load",	"loads",	"read",					},
 { "store",	"stores",	"write",				},
 { "prefetch",	"prefetches",	"speculative-read", "speculative-load",	},
100 101
};

102
static const char *hw_cache_result[][MAX_ALIASES] = {
103 104
 { "refs",	"Reference",	"ops",		"access",		},
 { "misses",	"miss",							},
105 106
};

107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
#define C(x)		PERF_COUNT_HW_CACHE_##x
#define CACHE_READ	(1 << C(OP_READ))
#define CACHE_WRITE	(1 << C(OP_WRITE))
#define CACHE_PREFETCH	(1 << C(OP_PREFETCH))
#define COP(x)		(1 << x)

/*
 * cache operartion stat
 * L1I : Read and prefetch only
 * ITLB and BPU : Read-only
 */
static unsigned long hw_cache_stat[C(MAX)] = {
 [C(L1D)]	= (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
 [C(L1I)]	= (CACHE_READ | CACHE_PREFETCH),
 [C(LL)]	= (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
 [C(DTLB)]	= (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
 [C(ITLB)]	= (CACHE_READ),
 [C(BPU)]	= (CACHE_READ),
};

127
#define for_each_subsystem(sys_dir, sys_dirent, sys_next)	       \
128
	while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next)	       \
129
	if (sys_dirent.d_type == DT_DIR &&				       \
130 131 132
	   (strcmp(sys_dirent.d_name, ".")) &&				       \
	   (strcmp(sys_dirent.d_name, "..")))

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
{
	char evt_path[MAXPATHLEN];
	int fd;

	snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
			sys_dir->d_name, evt_dir->d_name);
	fd = open(evt_path, O_RDONLY);
	if (fd < 0)
		return -EINVAL;
	close(fd);

	return 0;
}

148
#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next)	       \
149
	while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next)        \
150
	if (evt_dirent.d_type == DT_DIR &&				       \
151
	   (strcmp(evt_dirent.d_name, ".")) &&				       \
152 153
	   (strcmp(evt_dirent.d_name, "..")) &&				       \
	   (!tp_event_has_id(&sys_dirent, &evt_dirent)))
154

L
Li Zefan 已提交
155
#define MAX_EVENT_LENGTH 512
156 157


158
struct tracepoint_path *tracepoint_id_to_path(u64 config)
159
{
160
	struct tracepoint_path *path = NULL;
161 162 163
	DIR *sys_dir, *evt_dir;
	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
	char id_buf[4];
E
Eric Dumazet 已提交
164
	int fd;
165 166
	u64 id;
	char evt_path[MAXPATHLEN];
E
Eric Dumazet 已提交
167
	char dir_path[MAXPATHLEN];
168

169
	if (debugfs_valid_mountpoint(debugfs_path))
170
		return NULL;
171

172
	sys_dir = opendir(debugfs_path);
173
	if (!sys_dir)
E
Eric Dumazet 已提交
174
		return NULL;
175 176

	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
E
Eric Dumazet 已提交
177 178 179 180 181

		snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
			 sys_dirent.d_name);
		evt_dir = opendir(dir_path);
		if (!evt_dir)
182
			continue;
E
Eric Dumazet 已提交
183

184
		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
E
Eric Dumazet 已提交
185 186

			snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
187
				 evt_dirent.d_name);
E
Eric Dumazet 已提交
188
			fd = open(evt_path, O_RDONLY);
189 190 191 192 193 194 195 196 197 198 199
			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);
200
				path = zalloc(sizeof(*path));
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
				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;
217 218 219 220 221 222
			}
		}
		closedir(evt_dir);
	}

	closedir(sys_dir);
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
	return NULL;
}

#define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1)
static const char *tracepoint_id_to_name(u64 config)
{
	static char buf[TP_PATH_LEN];
	struct tracepoint_path *path;

	path = tracepoint_id_to_path(config);
	if (path) {
		snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name);
		free(path->name);
		free(path->system);
		free(path);
	} else
		snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown");

	return buf;
242 243
}

244 245 246 247 248 249 250 251
static int is_cache_op_valid(u8 cache_type, u8 cache_op)
{
	if (hw_cache_stat[cache_type] & COP(cache_op))
		return 1;	/* valid */
	else
		return 0;	/* invalid */
}

252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
{
	static char name[50];

	if (cache_result) {
		sprintf(name, "%s-%s-%s", hw_cache[cache_type][0],
			hw_cache_op[cache_op][0],
			hw_cache_result[cache_result][0]);
	} else {
		sprintf(name, "%s-%s", hw_cache[cache_type][0],
			hw_cache_op[cache_op][1]);
	}

	return name;
}

268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
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";
}

290
const char *event_name(struct perf_evsel *evsel)
291
{
292 293
	u64 config = evsel->attr.config;
	int type = evsel->attr.type;
294

295 296 297
	if (evsel->name)
		return evsel->name;

298 299 300
	return __event_name(type, config);
}

301
const char *__event_name(int type, u64 config)
302
{
303 304
	static char buf[32];

305
	if (type == PERF_TYPE_RAW) {
306
		sprintf(buf, "raw 0x%" PRIx64, config);
307 308 309 310 311
		return buf;
	}

	switch (type) {
	case PERF_TYPE_HARDWARE:
312
		if (config < PERF_COUNT_HW_MAX && hw_event_names[config])
313
			return hw_event_names[config];
314 315
		return "unknown-hardware";

316
	case PERF_TYPE_HW_CACHE: {
317
		u8 cache_type, cache_op, cache_result;
318 319 320 321 322 323

		cache_type   = (config >>  0) & 0xff;
		if (cache_type > PERF_COUNT_HW_CACHE_MAX)
			return "unknown-ext-hardware-cache-type";

		cache_op     = (config >>  8) & 0xff;
324 325
		if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX)
			return "unknown-ext-hardware-cache-op";
326 327

		cache_result = (config >> 16) & 0xff;
328 329
		if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX)
			return "unknown-ext-hardware-cache-result";
330

331 332
		if (!is_cache_op_valid(cache_type, cache_op))
			return "invalid-cache";
333

334
		return event_cache_name(cache_type, cache_op, cache_result);
335 336
	}

337
	case PERF_TYPE_SOFTWARE:
338
		if (config < PERF_COUNT_SW_MAX && sw_event_names[config])
339
			return sw_event_names[config];
340 341
		return "unknown-software";

342 343 344
	case PERF_TYPE_TRACEPOINT:
		return tracepoint_id_to_name(config);

345 346 347 348 349 350 351
	default:
		break;
	}

	return "unknown";
}

352
static int parse_aliases(const char **str, const char *names[][MAX_ALIASES], int size)
353 354
{
	int i, j;
355
	int n, longest = -1;
356 357

	for (i = 0; i < size; i++) {
358 359 360 361 362 363 364 365
		for (j = 0; j < MAX_ALIASES && names[i][j]; j++) {
			n = strlen(names[i][j]);
			if (n > longest && !strncasecmp(*str, names[i][j], n))
				longest = n;
		}
		if (longest > 0) {
			*str += longest;
			return i;
366 367 368
		}
	}

369
	return -1;
370 371
}

372
static enum event_result
373
parse_generic_hw_event(const char **str, struct perf_event_attr *attr)
374
{
375 376
	const char *s = *str;
	int cache_type = -1, cache_op = -1, cache_result = -1;
377

378
	cache_type = parse_aliases(&s, hw_cache, PERF_COUNT_HW_CACHE_MAX);
379 380 381 382 383
	/*
	 * No fallback - if we cannot get a clear cache type
	 * then bail out:
	 */
	if (cache_type == -1)
384
		return EVT_FAILED;
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412

	while ((cache_op == -1 || cache_result == -1) && *s == '-') {
		++s;

		if (cache_op == -1) {
			cache_op = parse_aliases(&s, hw_cache_op,
						PERF_COUNT_HW_CACHE_OP_MAX);
			if (cache_op >= 0) {
				if (!is_cache_op_valid(cache_type, cache_op))
					return 0;
				continue;
			}
		}

		if (cache_result == -1) {
			cache_result = parse_aliases(&s, hw_cache_result,
						PERF_COUNT_HW_CACHE_RESULT_MAX);
			if (cache_result >= 0)
				continue;
		}

		/*
		 * Can't parse this as a cache op or result, so back up
		 * to the '-'.
		 */
		--s;
		break;
	}
413 414 415 416

	/*
	 * Fall back to reads:
	 */
417 418
	if (cache_op == -1)
		cache_op = PERF_COUNT_HW_CACHE_OP_READ;
419 420 421 422 423 424 425 426 427 428

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

	attr->config = cache_type | (cache_op << 8) | (cache_result << 16);
	attr->type = PERF_TYPE_HW_CACHE;

429
	*str = s;
430 431 432 433 434 435 436
	return EVT_HANDLED;
}

static enum event_result
parse_single_tracepoint_event(char *sys_name,
			      const char *evt_name,
			      unsigned int evt_length,
437
			      struct perf_event_attr *attr,
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
			      const char **strp)
{
	char evt_path[MAXPATHLEN];
	char id_buf[4];
	u64 id;
	int fd;

	snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
		 sys_name, evt_name);

	fd = open(evt_path, O_RDONLY);
	if (fd < 0)
		return EVT_FAILED;

	if (read(fd, id_buf, sizeof(id_buf)) < 0) {
		close(fd);
		return EVT_FAILED;
	}

	close(fd);
	id = atoll(id_buf);
	attr->config = id;
	attr->type = PERF_TYPE_TRACEPOINT;
461
	*strp += strlen(sys_name) + evt_length + 1; /* + 1 for the ':' */
462

463 464 465 466 467 468 469
	attr->sample_type |= PERF_SAMPLE_RAW;
	attr->sample_type |= PERF_SAMPLE_TIME;
	attr->sample_type |= PERF_SAMPLE_CPU;

	attr->sample_period = 1;


470
	return EVT_HANDLED;
471 472
}

473 474 475
/* sys + ':' + event + ':' + flags*/
#define MAX_EVOPT_LEN	(MAX_EVENT_LENGTH * 2 + 2 + 128)
static enum event_result
476 477
parse_multiple_tracepoint_event(const struct option *opt, char *sys_name,
				const char *evt_exp, char *flags)
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
{
	char evt_path[MAXPATHLEN];
	struct dirent *evt_ent;
	DIR *evt_dir;

	snprintf(evt_path, MAXPATHLEN, "%s/%s", debugfs_path, sys_name);
	evt_dir = opendir(evt_path);

	if (!evt_dir) {
		perror("Can't open event dir");
		return EVT_FAILED;
	}

	while ((evt_ent = readdir(evt_dir))) {
		char event_opt[MAX_EVOPT_LEN + 1];
		int len;

		if (!strcmp(evt_ent->d_name, ".")
		    || !strcmp(evt_ent->d_name, "..")
		    || !strcmp(evt_ent->d_name, "enable")
		    || !strcmp(evt_ent->d_name, "filter"))
			continue;

501 502 503
		if (!strglobmatch(evt_ent->d_name, evt_exp))
			continue;

504 505 506
		len = snprintf(event_opt, MAX_EVOPT_LEN, "%s:%s%s%s", sys_name,
			       evt_ent->d_name, flags ? ":" : "",
			       flags ?: "");
507 508 509
		if (len < 0)
			return EVT_FAILED;

510
		if (parse_events(opt, event_opt, 0))
511 512 513 514 515 516
			return EVT_FAILED;
	}

	return EVT_HANDLED_ALL;
}

517 518 519
static enum event_result
parse_tracepoint_event(const struct option *opt, const char **strp,
		       struct perf_event_attr *attr)
520 521
{
	const char *evt_name;
522
	char *flags = NULL, *comma_loc;
523 524 525
	char sys_name[MAX_EVENT_LENGTH];
	unsigned int sys_length, evt_length;

526
	if (debugfs_valid_mountpoint(debugfs_path))
527 528 529 530
		return 0;

	evt_name = strchr(*strp, ':');
	if (!evt_name)
531
		return EVT_FAILED;
532 533 534 535 536 537 538 539

	sys_length = evt_name - *strp;
	if (sys_length >= MAX_EVENT_LENGTH)
		return 0;

	strncpy(sys_name, *strp, sys_length);
	sys_name[sys_length] = '\0';
	evt_name = evt_name + 1;
540

541 542 543 544 545
	comma_loc = strchr(evt_name, ',');
	if (comma_loc) {
		/* take the event name up to the comma */
		evt_name = strndup(evt_name, comma_loc - evt_name);
	}
546 547
	flags = strchr(evt_name, ':');
	if (flags) {
548 549
		/* split it out: */
		evt_name = strndup(evt_name, flags - evt_name);
550 551 552
		flags++;
	}

553 554
	evt_length = strlen(evt_name);
	if (evt_length >= MAX_EVENT_LENGTH)
555
		return EVT_FAILED;
556
	if (strpbrk(evt_name, "*?")) {
557
		*strp += strlen(sys_name) + evt_length + 1; /* 1 == the ':' */
558
		return parse_multiple_tracepoint_event(opt, sys_name, evt_name,
559
						       flags);
560
	} else {
561
		return parse_single_tracepoint_event(sys_name, evt_name,
562
						     evt_length, attr, strp);
563
	}
564 565
}

566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
static enum event_result
parse_breakpoint_type(const char *type, const char **strp,
		      struct perf_event_attr *attr)
{
	int i;

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

		switch (type[i]) {
		case 'r':
			attr->bp_type |= HW_BREAKPOINT_R;
			break;
		case 'w':
			attr->bp_type |= HW_BREAKPOINT_W;
			break;
		case 'x':
			attr->bp_type |= HW_BREAKPOINT_X;
			break;
		default:
			return EVT_FAILED;
		}
	}
	if (!attr->bp_type) /* Default */
		attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;

	*strp = type + i;

	return EVT_HANDLED;
}

static enum event_result
parse_breakpoint_event(const char **strp, struct perf_event_attr *attr)
{
	const char *target;
	const char *type;
	char *endaddr;
	u64 addr;
	enum event_result err;

	target = strchr(*strp, ':');
	if (!target)
		return EVT_FAILED;

	if (strncmp(*strp, "mem", target - *strp) != 0)
		return EVT_FAILED;

	target++;

	addr = strtoull(target, &endaddr, 0);
	if (target == endaddr)
		return EVT_FAILED;

	attr->bp_addr = addr;
	*strp = endaddr;

	type = strchr(target, ':');

	/* If no type is defined, just rw as default */
	if (!type) {
		attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;
	} else {
		err = parse_breakpoint_type(++type, strp, attr);
		if (err == EVT_FAILED)
			return EVT_FAILED;
	}

634 635 636 637 638 639 640 641 642
	/*
	 * We should find a nice way to override the access length
	 * Provide some defaults for now
	 */
	if (attr->bp_type == HW_BREAKPOINT_X)
		attr->bp_len = sizeof(long);
	else
		attr->bp_len = HW_BREAKPOINT_LEN_4;

643 644 645 646 647
	attr->type = PERF_TYPE_BREAKPOINT;

	return EVT_HANDLED;
}

648 649
static int check_events(const char *str, unsigned int i)
{
650
	int n;
651

652
	n = strlen(event_symbols[i].symbol);
653
	if (!strncasecmp(str, event_symbols[i].symbol, n))
654 655 656
		return n;

	n = strlen(event_symbols[i].alias);
657 658
	if (n) {
		if (!strncasecmp(str, event_symbols[i].alias, n))
659
			return n;
660 661
	}

662 663 664
	return 0;
}

665
static enum event_result
666
parse_symbolic_event(const char **strp, struct perf_event_attr *attr)
667
{
668
	const char *str = *strp;
669
	unsigned int i;
670
	int n;
671

672 673 674 675 676 677
	for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
		n = check_events(str, i);
		if (n > 0) {
			attr->type = event_symbols[i].type;
			attr->config = event_symbols[i].config;
			*strp = str + n;
678
			return EVT_HANDLED;
679 680
		}
	}
681
	return EVT_FAILED;
682 683
}

684
static enum event_result
685
parse_raw_event(const char **strp, struct perf_event_attr *attr)
686 687 688 689
{
	const char *str = *strp;
	u64 config;
	int n;
690

691
	if (*str != 'r')
692
		return EVT_FAILED;
693 694 695 696 697
	n = hex2u64(str + 1, &config);
	if (n > 0) {
		*strp = str + n + 1;
		attr->type = PERF_TYPE_RAW;
		attr->config = config;
698
		return EVT_HANDLED;
699
	}
700
	return EVT_FAILED;
701
}
702

703
static enum event_result
704
parse_numeric_event(const char **strp, struct perf_event_attr *attr)
705 706 707 708 709 710 711 712 713 714 715 716 717 718
{
	const char *str = *strp;
	char *endp;
	unsigned long type;
	u64 config;

	type = strtoul(str, &endp, 0);
	if (endp > str && type < PERF_TYPE_MAX && *endp == ':') {
		str = endp + 1;
		config = strtoul(str, &endp, 0);
		if (endp > str) {
			attr->type = type;
			attr->config = config;
			*strp = endp;
719
			return EVT_HANDLED;
720
		}
721
	}
722
	return EVT_FAILED;
723 724
}

725
static int
726
parse_event_modifier(const char **strp, struct perf_event_attr *attr)
727 728
{
	const char *str = *strp;
P
Peter Zijlstra 已提交
729 730
	int exclude = 0;
	int eu = 0, ek = 0, eh = 0, precise = 0;
731

732
	if (!*str)
733
		return 0;
734 735 736 737

	if (*str++ != ':')
		return -1;

738
	while (*str) {
P
Peter Zijlstra 已提交
739 740 741
		if (*str == 'u') {
			if (!exclude)
				exclude = eu = ek = eh = 1;
742
			eu = 0;
P
Peter Zijlstra 已提交
743 744 745
		} else if (*str == 'k') {
			if (!exclude)
				exclude = eu = ek = eh = 1;
746
			ek = 0;
P
Peter Zijlstra 已提交
747 748 749
		} else if (*str == 'h') {
			if (!exclude)
				exclude = eu = ek = eh = 1;
750
			eh = 0;
P
Peter Zijlstra 已提交
751 752 753
		} else if (*str == 'p') {
			precise++;
		} else
754
			break;
P
Peter Zijlstra 已提交
755

756
		++str;
757
	}
758 759 760 761 762 763 764 765 766 767
	if (str < *strp + 2)
		return -1;

	*strp = str;

	attr->exclude_user   = eu;
	attr->exclude_kernel = ek;
	attr->exclude_hv     = eh;
	attr->precise_ip     = precise;

768 769
	return 0;
}
770

771 772 773 774
/*
 * Each event can have multiple symbolic names.
 * Symbolic names are (almost) exactly matched.
 */
775
static enum event_result
776 777
parse_event_symbols(const struct option *opt, const char **str,
		    struct perf_event_attr *attr)
778
{
779 780
	enum event_result ret;

781
	ret = parse_tracepoint_event(opt, str, attr);
782 783 784 785 786 787
	if (ret != EVT_FAILED)
		goto modifier;

	ret = parse_raw_event(str, attr);
	if (ret != EVT_FAILED)
		goto modifier;
788

789 790 791 792 793 794 795 796 797 798 799 800
	ret = parse_numeric_event(str, attr);
	if (ret != EVT_FAILED)
		goto modifier;

	ret = parse_symbolic_event(str, attr);
	if (ret != EVT_FAILED)
		goto modifier;

	ret = parse_generic_hw_event(str, attr);
	if (ret != EVT_FAILED)
		goto modifier;

801 802 803 804
	ret = parse_breakpoint_event(str, attr);
	if (ret != EVT_FAILED)
		goto modifier;

805 806
	fprintf(stderr, "invalid or unsupported event: '%s'\n", *str);
	fprintf(stderr, "Run 'perf list' for a list of valid events\n");
807 808 809
	return EVT_FAILED;

modifier:
810 811 812 813 814 815
	if (parse_event_modifier(str, attr) < 0) {
		fprintf(stderr, "invalid event modifier: '%s'\n", *str);
		fprintf(stderr, "Run 'perf list' for a list of valid events and modifiers\n");

		return EVT_FAILED;
	}
816

817
	return ret;
818 819
}

820
int parse_events(const struct option *opt, const char *str, int unset __used)
821
{
822
	struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
823
	struct perf_event_attr attr;
824
	enum event_result ret;
825
	const char *ostr;
826

827
	for (;;) {
828
		ostr = str;
829
		memset(&attr, 0, sizeof(attr));
830
		ret = parse_event_symbols(opt, &str, &attr);
831
		if (ret == EVT_FAILED)
832
			return -1;
833

834 835
		if (!(*str == 0 || *str == ',' || isspace(*str)))
			return -1;
836

837
		if (ret != EVT_HANDLED_ALL) {
838
			struct perf_evsel *evsel;
839
			evsel = perf_evsel__new(&attr, evlist->nr_entries);
840 841
			if (evsel == NULL)
				return -1;
842
			perf_evlist__add(evlist, evsel);
843 844 845 846 847

			evsel->name = calloc(str - ostr + 1, 1);
			if (!evsel->name)
				return -1;
			strncpy(evsel->name, ostr, str - ostr);
848
		}
849

850 851 852 853 854 855
		if (*str == 0)
			break;
		if (*str == ',')
			++str;
		while (isspace(*str))
			++str;
856 857 858 859 860
	}

	return 0;
}

861
int parse_filter(const struct option *opt, const char *str,
L
Li Zefan 已提交
862 863
		 int unset __used)
{
864
	struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
865
	struct perf_evsel *last = NULL;
L
Li Zefan 已提交
866

867 868
	if (evlist->nr_entries > 0)
		last = list_entry(evlist->entries.prev, struct perf_evsel, node);
869 870

	if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) {
L
Li Zefan 已提交
871 872 873 874 875
		fprintf(stderr,
			"-F option should follow a -e tracepoint option\n");
		return -1;
	}

876 877
	last->filter = strdup(str);
	if (last->filter == NULL) {
L
Li Zefan 已提交
878 879 880 881 882 883 884
		fprintf(stderr, "not enough memory to hold filter string\n");
		return -1;
	}

	return 0;
}

885 886 887 888 889
static const char * const event_type_descriptors[] = {
	"Hardware event",
	"Software event",
	"Tracepoint event",
	"Hardware cache event",
890 891
	"Raw hardware event descriptor",
	"Hardware breakpoint",
892 893
};

894 895 896 897
/*
 * Print the events from <debugfs_mount_point>/tracing/events
 */

898
void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
899 900 901 902
{
	DIR *sys_dir, *evt_dir;
	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
	char evt_path[MAXPATHLEN];
E
Eric Dumazet 已提交
903
	char dir_path[MAXPATHLEN];
904

905
	if (debugfs_valid_mountpoint(debugfs_path))
906 907
		return;

908
	sys_dir = opendir(debugfs_path);
909
	if (!sys_dir)
E
Eric Dumazet 已提交
910
		return;
911 912

	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
913 914 915
		if (subsys_glob != NULL && 
		    !strglobmatch(sys_dirent.d_name, subsys_glob))
			continue;
E
Eric Dumazet 已提交
916 917 918 919 920

		snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
			 sys_dirent.d_name);
		evt_dir = opendir(dir_path);
		if (!evt_dir)
921
			continue;
E
Eric Dumazet 已提交
922

923
		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
924 925 926 927
			if (event_glob != NULL && 
			    !strglobmatch(evt_dirent.d_name, event_glob))
				continue;

928 929
			snprintf(evt_path, MAXPATHLEN, "%s:%s",
				 sys_dirent.d_name, evt_dirent.d_name);
930
			printf("  %-42s [%s]\n", evt_path,
931
				event_type_descriptors[PERF_TYPE_TRACEPOINT]);
932 933 934 935 936 937
		}
		closedir(evt_dir);
	}
	closedir(sys_dir);
}

938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
/*
 * 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];

	if (debugfs_valid_mountpoint(debugfs_path))
		return 0;

	sys_dir = opendir(debugfs_path);
	if (!sys_dir)
		return 0;

	for_each_subsystem(sys_dir, sys_dirent, sys_next) {

		snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
			 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;
}

979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
void print_events_type(u8 type)
{
	struct event_symbol *syms = event_symbols;
	unsigned int i;
	char name[64];

	for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
		if (type != syms->type)
			continue;

		if (strlen(syms->alias))
			snprintf(name, sizeof(name),  "%s OR %s",
				 syms->symbol, syms->alias);
		else
			snprintf(name, sizeof(name), "%s", syms->symbol);

		printf("  %-42s [%s]\n", name,
			event_type_descriptors[type]);
	}
}

int print_hwcache_events(const char *event_glob)
{
	unsigned int type, op, i, printed = 0;

	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 */
			if (!is_cache_op_valid(type, op))
				continue;

			for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
				char *name = event_cache_name(type, op, i);

				if (event_glob != NULL && 
				    !strglobmatch(name, event_glob))
					continue;

				printf("  %-42s [%s]\n", name,
					event_type_descriptors[PERF_TYPE_HW_CACHE]);
				++printed;
			}
		}
	}

	return printed;
}

1027
/*
1028
 * Print the help text for the event symbols:
1029
 */
1030
void print_events(const char *event_glob)
1031
{
1032
	struct event_symbol *syms = event_symbols;
1033
	unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0;
1034
	char name[40];
1035

1036 1037
	printf("\n");
	printf("List of pre-defined events (to be used in -e):\n");
1038

1039
	for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
1040
		type = syms->type;
1041

1042
		if (type != prev_type && printed) {
1043
			printf("\n");
1044 1045 1046 1047 1048 1049 1050 1051
			printed = 0;
			ntypes_printed++;
		}

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

1053 1054 1055 1056
		if (strlen(syms->alias))
			sprintf(name, "%s OR %s", syms->symbol, syms->alias);
		else
			strcpy(name, syms->symbol);
1057
		printf("  %-42s [%s]\n", name,
1058
			event_type_descriptors[type]);
1059

1060
		prev_type = type;
1061
		++printed;
1062 1063
	}

1064 1065 1066
	if (ntypes_printed) {
		printed = 0;
		printf("\n");
1067
	}
1068 1069 1070 1071
	print_hwcache_events(event_glob);

	if (event_glob != NULL)
		return;
1072

1073
	printf("\n");
1074
	printf("  %-42s [%s]\n",
1075 1076
		"rNNN (see 'perf list --help' on how to encode it)",
	       event_type_descriptors[PERF_TYPE_RAW]);
1077
	printf("\n");
1078

1079 1080 1081
	printf("  %-42s [%s]\n",
			"mem:<addr>[:access]",
			event_type_descriptors[PERF_TYPE_BREAKPOINT]);
1082 1083
	printf("\n");

1084
	print_tracepoint_events(NULL, NULL);
1085

1086
	exit(129);
1087
}