xref: /openbmc/linux/tools/perf/util/pmu.c (revision 09b35b41)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/list.h>
3 #include <linux/compiler.h>
4 #include <linux/string.h>
5 #include <linux/zalloc.h>
6 #include <subcmd/pager.h>
7 #include <sys/types.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <sys/stat.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <stdbool.h>
14 #include <stdarg.h>
15 #include <dirent.h>
16 #include <api/fs/fs.h>
17 #include <locale.h>
18 #include <regex.h>
19 #include <perf/cpumap.h>
20 #include "debug.h"
21 #include "pmu.h"
22 #include "parse-events.h"
23 #include "cpumap.h"
24 #include "header.h"
25 #include "pmu-events/pmu-events.h"
26 #include "string2.h"
27 #include "strbuf.h"
28 
29 struct perf_pmu_format {
30 	char *name;
31 	int value;
32 	DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
33 	struct list_head list;
34 };
35 
36 int perf_pmu_parse(struct list_head *list, char *name);
37 extern FILE *perf_pmu_in;
38 
39 static LIST_HEAD(pmus);
40 
41 /*
42  * Parse & process all the sysfs attributes located under
43  * the directory specified in 'dir' parameter.
44  */
45 int perf_pmu__format_parse(char *dir, struct list_head *head)
46 {
47 	struct dirent *evt_ent;
48 	DIR *format_dir;
49 	int ret = 0;
50 
51 	format_dir = opendir(dir);
52 	if (!format_dir)
53 		return -EINVAL;
54 
55 	while (!ret && (evt_ent = readdir(format_dir))) {
56 		char path[PATH_MAX];
57 		char *name = evt_ent->d_name;
58 		FILE *file;
59 
60 		if (!strcmp(name, ".") || !strcmp(name, ".."))
61 			continue;
62 
63 		snprintf(path, PATH_MAX, "%s/%s", dir, name);
64 
65 		ret = -EINVAL;
66 		file = fopen(path, "r");
67 		if (!file)
68 			break;
69 
70 		perf_pmu_in = file;
71 		ret = perf_pmu_parse(head, name);
72 		fclose(file);
73 	}
74 
75 	closedir(format_dir);
76 	return ret;
77 }
78 
79 /*
80  * Reading/parsing the default pmu format definition, which should be
81  * located at:
82  * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
83  */
84 static int pmu_format(const char *name, struct list_head *format)
85 {
86 	struct stat st;
87 	char path[PATH_MAX];
88 	const char *sysfs = sysfs__mountpoint();
89 
90 	if (!sysfs)
91 		return -1;
92 
93 	snprintf(path, PATH_MAX,
94 		 "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name);
95 
96 	if (stat(path, &st) < 0)
97 		return 0;	/* no error if format does not exist */
98 
99 	if (perf_pmu__format_parse(path, format))
100 		return -1;
101 
102 	return 0;
103 }
104 
105 int perf_pmu__convert_scale(const char *scale, char **end, double *sval)
106 {
107 	char *lc;
108 	int ret = 0;
109 
110 	/*
111 	 * save current locale
112 	 */
113 	lc = setlocale(LC_NUMERIC, NULL);
114 
115 	/*
116 	 * The lc string may be allocated in static storage,
117 	 * so get a dynamic copy to make it survive setlocale
118 	 * call below.
119 	 */
120 	lc = strdup(lc);
121 	if (!lc) {
122 		ret = -ENOMEM;
123 		goto out;
124 	}
125 
126 	/*
127 	 * force to C locale to ensure kernel
128 	 * scale string is converted correctly.
129 	 * kernel uses default C locale.
130 	 */
131 	setlocale(LC_NUMERIC, "C");
132 
133 	*sval = strtod(scale, end);
134 
135 out:
136 	/* restore locale */
137 	setlocale(LC_NUMERIC, lc);
138 	free(lc);
139 	return ret;
140 }
141 
142 static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
143 {
144 	struct stat st;
145 	ssize_t sret;
146 	char scale[128];
147 	int fd, ret = -1;
148 	char path[PATH_MAX];
149 
150 	scnprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
151 
152 	fd = open(path, O_RDONLY);
153 	if (fd == -1)
154 		return -1;
155 
156 	if (fstat(fd, &st) < 0)
157 		goto error;
158 
159 	sret = read(fd, scale, sizeof(scale)-1);
160 	if (sret < 0)
161 		goto error;
162 
163 	if (scale[sret - 1] == '\n')
164 		scale[sret - 1] = '\0';
165 	else
166 		scale[sret] = '\0';
167 
168 	ret = perf_pmu__convert_scale(scale, NULL, &alias->scale);
169 error:
170 	close(fd);
171 	return ret;
172 }
173 
174 static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
175 {
176 	char path[PATH_MAX];
177 	ssize_t sret;
178 	int fd;
179 
180 	scnprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
181 
182 	fd = open(path, O_RDONLY);
183 	if (fd == -1)
184 		return -1;
185 
186 	sret = read(fd, alias->unit, UNIT_MAX_LEN);
187 	if (sret < 0)
188 		goto error;
189 
190 	close(fd);
191 
192 	if (alias->unit[sret - 1] == '\n')
193 		alias->unit[sret - 1] = '\0';
194 	else
195 		alias->unit[sret] = '\0';
196 
197 	return 0;
198 error:
199 	close(fd);
200 	alias->unit[0] = '\0';
201 	return -1;
202 }
203 
204 static int
205 perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name)
206 {
207 	char path[PATH_MAX];
208 	int fd;
209 
210 	scnprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
211 
212 	fd = open(path, O_RDONLY);
213 	if (fd == -1)
214 		return -1;
215 
216 	close(fd);
217 
218 	alias->per_pkg = true;
219 	return 0;
220 }
221 
222 static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
223 				    char *dir, char *name)
224 {
225 	char path[PATH_MAX];
226 	int fd;
227 
228 	scnprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
229 
230 	fd = open(path, O_RDONLY);
231 	if (fd == -1)
232 		return -1;
233 
234 	alias->snapshot = true;
235 	close(fd);
236 	return 0;
237 }
238 
239 static void perf_pmu_assign_str(char *name, const char *field, char **old_str,
240 				char **new_str)
241 {
242 	if (!*old_str)
243 		goto set_new;
244 
245 	if (*new_str) {	/* Have new string, check with old */
246 		if (strcasecmp(*old_str, *new_str))
247 			pr_debug("alias %s differs in field '%s'\n",
248 				 name, field);
249 		zfree(old_str);
250 	} else		/* Nothing new --> keep old string */
251 		return;
252 set_new:
253 	*old_str = *new_str;
254 	*new_str = NULL;
255 }
256 
257 static void perf_pmu_update_alias(struct perf_pmu_alias *old,
258 				  struct perf_pmu_alias *newalias)
259 {
260 	perf_pmu_assign_str(old->name, "desc", &old->desc, &newalias->desc);
261 	perf_pmu_assign_str(old->name, "long_desc", &old->long_desc,
262 			    &newalias->long_desc);
263 	perf_pmu_assign_str(old->name, "topic", &old->topic, &newalias->topic);
264 	perf_pmu_assign_str(old->name, "metric_expr", &old->metric_expr,
265 			    &newalias->metric_expr);
266 	perf_pmu_assign_str(old->name, "metric_name", &old->metric_name,
267 			    &newalias->metric_name);
268 	perf_pmu_assign_str(old->name, "value", &old->str, &newalias->str);
269 	old->scale = newalias->scale;
270 	old->per_pkg = newalias->per_pkg;
271 	old->snapshot = newalias->snapshot;
272 	memcpy(old->unit, newalias->unit, sizeof(old->unit));
273 }
274 
275 /* Delete an alias entry. */
276 static void perf_pmu_free_alias(struct perf_pmu_alias *newalias)
277 {
278 	zfree(&newalias->name);
279 	zfree(&newalias->desc);
280 	zfree(&newalias->long_desc);
281 	zfree(&newalias->topic);
282 	zfree(&newalias->str);
283 	zfree(&newalias->metric_expr);
284 	zfree(&newalias->metric_name);
285 	parse_events_terms__purge(&newalias->terms);
286 	free(newalias);
287 }
288 
289 /* Merge an alias, search in alias list. If this name is already
290  * present merge both of them to combine all information.
291  */
292 static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias,
293 				 struct list_head *alist)
294 {
295 	struct perf_pmu_alias *a;
296 
297 	list_for_each_entry(a, alist, list) {
298 		if (!strcasecmp(newalias->name, a->name)) {
299 			perf_pmu_update_alias(a, newalias);
300 			perf_pmu_free_alias(newalias);
301 			return true;
302 		}
303 	}
304 	return false;
305 }
306 
307 static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
308 				 char *desc, char *val,
309 				 char *long_desc, char *topic,
310 				 char *unit, char *perpkg,
311 				 char *metric_expr,
312 				 char *metric_name)
313 {
314 	struct parse_events_term *term;
315 	struct perf_pmu_alias *alias;
316 	int ret;
317 	int num;
318 	char newval[256];
319 
320 	alias = malloc(sizeof(*alias));
321 	if (!alias)
322 		return -ENOMEM;
323 
324 	INIT_LIST_HEAD(&alias->terms);
325 	alias->scale = 1.0;
326 	alias->unit[0] = '\0';
327 	alias->per_pkg = false;
328 	alias->snapshot = false;
329 
330 	ret = parse_events_terms(&alias->terms, val);
331 	if (ret) {
332 		pr_err("Cannot parse alias %s: %d\n", val, ret);
333 		free(alias);
334 		return ret;
335 	}
336 
337 	/* Scan event and remove leading zeroes, spaces, newlines, some
338 	 * platforms have terms specified as
339 	 * event=0x0091 (read from files ../<PMU>/events/<FILE>
340 	 * and terms specified as event=0x91 (read from JSON files).
341 	 *
342 	 * Rebuild string to make alias->str member comparable.
343 	 */
344 	memset(newval, 0, sizeof(newval));
345 	ret = 0;
346 	list_for_each_entry(term, &alias->terms, list) {
347 		if (ret)
348 			ret += scnprintf(newval + ret, sizeof(newval) - ret,
349 					 ",");
350 		if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM)
351 			ret += scnprintf(newval + ret, sizeof(newval) - ret,
352 					 "%s=%#x", term->config, term->val.num);
353 		else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
354 			ret += scnprintf(newval + ret, sizeof(newval) - ret,
355 					 "%s=%s", term->config, term->val.str);
356 	}
357 
358 	alias->name = strdup(name);
359 	if (dir) {
360 		/*
361 		 * load unit name and scale if available
362 		 */
363 		perf_pmu__parse_unit(alias, dir, name);
364 		perf_pmu__parse_scale(alias, dir, name);
365 		perf_pmu__parse_per_pkg(alias, dir, name);
366 		perf_pmu__parse_snapshot(alias, dir, name);
367 	}
368 
369 	alias->metric_expr = metric_expr ? strdup(metric_expr) : NULL;
370 	alias->metric_name = metric_name ? strdup(metric_name): NULL;
371 	alias->desc = desc ? strdup(desc) : NULL;
372 	alias->long_desc = long_desc ? strdup(long_desc) :
373 				desc ? strdup(desc) : NULL;
374 	alias->topic = topic ? strdup(topic) : NULL;
375 	if (unit) {
376 		if (perf_pmu__convert_scale(unit, &unit, &alias->scale) < 0)
377 			return -1;
378 		snprintf(alias->unit, sizeof(alias->unit), "%s", unit);
379 	}
380 	alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1;
381 	alias->str = strdup(newval);
382 
383 	if (!perf_pmu_merge_alias(alias, list))
384 		list_add_tail(&alias->list, list);
385 
386 	return 0;
387 }
388 
389 static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
390 {
391 	char buf[256];
392 	int ret;
393 
394 	ret = fread(buf, 1, sizeof(buf), file);
395 	if (ret == 0)
396 		return -EINVAL;
397 
398 	buf[ret] = 0;
399 
400 	/* Remove trailing newline from sysfs file */
401 	strim(buf);
402 
403 	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
404 				     NULL, NULL, NULL);
405 }
406 
407 static inline bool pmu_alias_info_file(char *name)
408 {
409 	size_t len;
410 
411 	len = strlen(name);
412 	if (len > 5 && !strcmp(name + len - 5, ".unit"))
413 		return true;
414 	if (len > 6 && !strcmp(name + len - 6, ".scale"))
415 		return true;
416 	if (len > 8 && !strcmp(name + len - 8, ".per-pkg"))
417 		return true;
418 	if (len > 9 && !strcmp(name + len - 9, ".snapshot"))
419 		return true;
420 
421 	return false;
422 }
423 
424 /*
425  * Process all the sysfs attributes located under the directory
426  * specified in 'dir' parameter.
427  */
428 static int pmu_aliases_parse(char *dir, struct list_head *head)
429 {
430 	struct dirent *evt_ent;
431 	DIR *event_dir;
432 
433 	event_dir = opendir(dir);
434 	if (!event_dir)
435 		return -EINVAL;
436 
437 	while ((evt_ent = readdir(event_dir))) {
438 		char path[PATH_MAX];
439 		char *name = evt_ent->d_name;
440 		FILE *file;
441 
442 		if (!strcmp(name, ".") || !strcmp(name, ".."))
443 			continue;
444 
445 		/*
446 		 * skip info files parsed in perf_pmu__new_alias()
447 		 */
448 		if (pmu_alias_info_file(name))
449 			continue;
450 
451 		scnprintf(path, PATH_MAX, "%s/%s", dir, name);
452 
453 		file = fopen(path, "r");
454 		if (!file) {
455 			pr_debug("Cannot open %s\n", path);
456 			continue;
457 		}
458 
459 		if (perf_pmu__new_alias(head, dir, name, file) < 0)
460 			pr_debug("Cannot set up %s\n", name);
461 		fclose(file);
462 	}
463 
464 	closedir(event_dir);
465 	return 0;
466 }
467 
468 /*
469  * Reading the pmu event aliases definition, which should be located at:
470  * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
471  */
472 static int pmu_aliases(const char *name, struct list_head *head)
473 {
474 	struct stat st;
475 	char path[PATH_MAX];
476 	const char *sysfs = sysfs__mountpoint();
477 
478 	if (!sysfs)
479 		return -1;
480 
481 	snprintf(path, PATH_MAX,
482 		 "%s/bus/event_source/devices/%s/events", sysfs, name);
483 
484 	if (stat(path, &st) < 0)
485 		return 0;	 /* no error if 'events' does not exist */
486 
487 	if (pmu_aliases_parse(path, head))
488 		return -1;
489 
490 	return 0;
491 }
492 
493 static int pmu_alias_terms(struct perf_pmu_alias *alias,
494 			   struct list_head *terms)
495 {
496 	struct parse_events_term *term, *cloned;
497 	LIST_HEAD(list);
498 	int ret;
499 
500 	list_for_each_entry(term, &alias->terms, list) {
501 		ret = parse_events_term__clone(&cloned, term);
502 		if (ret) {
503 			parse_events_terms__purge(&list);
504 			return ret;
505 		}
506 		/*
507 		 * Weak terms don't override command line options,
508 		 * which we don't want for implicit terms in aliases.
509 		 */
510 		cloned->weak = true;
511 		list_add_tail(&cloned->list, &list);
512 	}
513 	list_splice(&list, terms);
514 	return 0;
515 }
516 
517 /*
518  * Reading/parsing the default pmu type value, which should be
519  * located at:
520  * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
521  */
522 static int pmu_type(const char *name, __u32 *type)
523 {
524 	struct stat st;
525 	char path[PATH_MAX];
526 	FILE *file;
527 	int ret = 0;
528 	const char *sysfs = sysfs__mountpoint();
529 
530 	if (!sysfs)
531 		return -1;
532 
533 	snprintf(path, PATH_MAX,
534 		 "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name);
535 
536 	if (stat(path, &st) < 0)
537 		return -1;
538 
539 	file = fopen(path, "r");
540 	if (!file)
541 		return -EINVAL;
542 
543 	if (1 != fscanf(file, "%u", type))
544 		ret = -1;
545 
546 	fclose(file);
547 	return ret;
548 }
549 
550 /* Add all pmus in sysfs to pmu list: */
551 static void pmu_read_sysfs(void)
552 {
553 	char path[PATH_MAX];
554 	DIR *dir;
555 	struct dirent *dent;
556 	const char *sysfs = sysfs__mountpoint();
557 
558 	if (!sysfs)
559 		return;
560 
561 	snprintf(path, PATH_MAX,
562 		 "%s" EVENT_SOURCE_DEVICE_PATH, sysfs);
563 
564 	dir = opendir(path);
565 	if (!dir)
566 		return;
567 
568 	while ((dent = readdir(dir))) {
569 		if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
570 			continue;
571 		/* add to static LIST_HEAD(pmus): */
572 		perf_pmu__find(dent->d_name);
573 	}
574 
575 	closedir(dir);
576 }
577 
578 static struct perf_cpu_map *__pmu_cpumask(const char *path)
579 {
580 	FILE *file;
581 	struct perf_cpu_map *cpus;
582 
583 	file = fopen(path, "r");
584 	if (!file)
585 		return NULL;
586 
587 	cpus = perf_cpu_map__read(file);
588 	fclose(file);
589 	return cpus;
590 }
591 
592 /*
593  * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64)
594  * may have a "cpus" file.
595  */
596 #define CPUS_TEMPLATE_UNCORE	"%s/bus/event_source/devices/%s/cpumask"
597 #define CPUS_TEMPLATE_CPU	"%s/bus/event_source/devices/%s/cpus"
598 
599 static struct perf_cpu_map *pmu_cpumask(const char *name)
600 {
601 	char path[PATH_MAX];
602 	struct perf_cpu_map *cpus;
603 	const char *sysfs = sysfs__mountpoint();
604 	const char *templates[] = {
605 		CPUS_TEMPLATE_UNCORE,
606 		CPUS_TEMPLATE_CPU,
607 		NULL
608 	};
609 	const char **template;
610 
611 	if (!sysfs)
612 		return NULL;
613 
614 	for (template = templates; *template; template++) {
615 		snprintf(path, PATH_MAX, *template, sysfs, name);
616 		cpus = __pmu_cpumask(path);
617 		if (cpus)
618 			return cpus;
619 	}
620 
621 	return NULL;
622 }
623 
624 static bool pmu_is_uncore(const char *name)
625 {
626 	char path[PATH_MAX];
627 	struct perf_cpu_map *cpus;
628 	const char *sysfs = sysfs__mountpoint();
629 
630 	snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name);
631 	cpus = __pmu_cpumask(path);
632 	perf_cpu_map__put(cpus);
633 
634 	return !!cpus;
635 }
636 
637 /*
638  *  PMU CORE devices have different name other than cpu in sysfs on some
639  *  platforms.
640  *  Looking for possible sysfs files to identify the arm core device.
641  */
642 static int is_arm_pmu_core(const char *name)
643 {
644 	struct stat st;
645 	char path[PATH_MAX];
646 	const char *sysfs = sysfs__mountpoint();
647 
648 	if (!sysfs)
649 		return 0;
650 
651 	/* Look for cpu sysfs (specific to arm) */
652 	scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus",
653 				sysfs, name);
654 	if (stat(path, &st) == 0)
655 		return 1;
656 
657 	return 0;
658 }
659 
660 static char *perf_pmu__getcpuid(struct perf_pmu *pmu)
661 {
662 	char *cpuid;
663 	static bool printed;
664 
665 	cpuid = getenv("PERF_CPUID");
666 	if (cpuid)
667 		cpuid = strdup(cpuid);
668 	if (!cpuid)
669 		cpuid = get_cpuid_str(pmu);
670 	if (!cpuid)
671 		return NULL;
672 
673 	if (!printed) {
674 		pr_debug("Using CPUID %s\n", cpuid);
675 		printed = true;
676 	}
677 	return cpuid;
678 }
679 
680 struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu)
681 {
682 	struct pmu_events_map *map;
683 	char *cpuid = perf_pmu__getcpuid(pmu);
684 	int i;
685 
686 	/* on some platforms which uses cpus map, cpuid can be NULL for
687 	 * PMUs other than CORE PMUs.
688 	 */
689 	if (!cpuid)
690 		return NULL;
691 
692 	i = 0;
693 	for (;;) {
694 		map = &pmu_events_map[i++];
695 		if (!map->table) {
696 			map = NULL;
697 			break;
698 		}
699 
700 		if (!strcmp_cpuid_str(map->cpuid, cpuid))
701 			break;
702 	}
703 	free(cpuid);
704 	return map;
705 }
706 
707 static bool pmu_uncore_alias_match(const char *pmu_name, const char *name)
708 {
709 	char *tmp = NULL, *tok, *str;
710 	bool res;
711 
712 	str = strdup(pmu_name);
713 	if (!str)
714 		return false;
715 
716 	/*
717 	 * uncore alias may be from different PMU with common prefix
718 	 */
719 	tok = strtok_r(str, ",", &tmp);
720 	if (strncmp(pmu_name, tok, strlen(tok))) {
721 		res = false;
722 		goto out;
723 	}
724 
725 	/*
726 	 * Match more complex aliases where the alias name is a comma-delimited
727 	 * list of tokens, orderly contained in the matching PMU name.
728 	 *
729 	 * Example: For alias "socket,pmuname" and PMU "socketX_pmunameY", we
730 	 *	    match "socket" in "socketX_pmunameY" and then "pmuname" in
731 	 *	    "pmunameY".
732 	 */
733 	for (; tok; name += strlen(tok), tok = strtok_r(NULL, ",", &tmp)) {
734 		name = strstr(name, tok);
735 		if (!name) {
736 			res = false;
737 			goto out;
738 		}
739 	}
740 
741 	res = true;
742 out:
743 	free(str);
744 	return res;
745 }
746 
747 /*
748  * From the pmu_events_map, find the table of PMU events that corresponds
749  * to the current running CPU. Then, add all PMU events from that table
750  * as aliases.
751  */
752 static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
753 {
754 	int i;
755 	struct pmu_events_map *map;
756 	const char *name = pmu->name;
757 
758 	map = perf_pmu__find_map(pmu);
759 	if (!map)
760 		return;
761 
762 	/*
763 	 * Found a matching PMU events table. Create aliases
764 	 */
765 	i = 0;
766 	while (1) {
767 		const char *cpu_name = is_arm_pmu_core(name) ? name : "cpu";
768 		struct pmu_event *pe = &map->table[i++];
769 		const char *pname = pe->pmu ? pe->pmu : cpu_name;
770 
771 		if (!pe->name) {
772 			if (pe->metric_group || pe->metric_name)
773 				continue;
774 			break;
775 		}
776 
777 		if (pmu_is_uncore(name) &&
778 		    pmu_uncore_alias_match(pname, name))
779 			goto new_alias;
780 
781 		if (strcmp(pname, name))
782 			continue;
783 
784 new_alias:
785 		/* need type casts to override 'const' */
786 		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
787 				(char *)pe->desc, (char *)pe->event,
788 				(char *)pe->long_desc, (char *)pe->topic,
789 				(char *)pe->unit, (char *)pe->perpkg,
790 				(char *)pe->metric_expr,
791 				(char *)pe->metric_name);
792 	}
793 }
794 
795 struct perf_event_attr * __weak
796 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
797 {
798 	return NULL;
799 }
800 
801 static int pmu_max_precise(const char *name)
802 {
803 	char path[PATH_MAX];
804 	int max_precise = -1;
805 
806 	scnprintf(path, PATH_MAX,
807 		 "bus/event_source/devices/%s/caps/max_precise",
808 		 name);
809 
810 	sysfs__read_int(path, &max_precise);
811 	return max_precise;
812 }
813 
814 static struct perf_pmu *pmu_lookup(const char *name)
815 {
816 	struct perf_pmu *pmu;
817 	LIST_HEAD(format);
818 	LIST_HEAD(aliases);
819 	__u32 type;
820 
821 	/*
822 	 * The pmu data we store & need consists of the pmu
823 	 * type value and format definitions. Load both right
824 	 * now.
825 	 */
826 	if (pmu_format(name, &format))
827 		return NULL;
828 
829 	/*
830 	 * Check the type first to avoid unnecessary work.
831 	 */
832 	if (pmu_type(name, &type))
833 		return NULL;
834 
835 	if (pmu_aliases(name, &aliases))
836 		return NULL;
837 
838 	pmu = zalloc(sizeof(*pmu));
839 	if (!pmu)
840 		return NULL;
841 
842 	pmu->cpus = pmu_cpumask(name);
843 	pmu->name = strdup(name);
844 	pmu->type = type;
845 	pmu->is_uncore = pmu_is_uncore(name);
846 	pmu->max_precise = pmu_max_precise(name);
847 	pmu_add_cpu_aliases(&aliases, pmu);
848 
849 	INIT_LIST_HEAD(&pmu->format);
850 	INIT_LIST_HEAD(&pmu->aliases);
851 	list_splice(&format, &pmu->format);
852 	list_splice(&aliases, &pmu->aliases);
853 	list_add_tail(&pmu->list, &pmus);
854 
855 	pmu->default_config = perf_pmu__get_default_config(pmu);
856 
857 	return pmu;
858 }
859 
860 static struct perf_pmu *pmu_find(const char *name)
861 {
862 	struct perf_pmu *pmu;
863 
864 	list_for_each_entry(pmu, &pmus, list)
865 		if (!strcmp(pmu->name, name))
866 			return pmu;
867 
868 	return NULL;
869 }
870 
871 struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
872 {
873 	/*
874 	 * pmu iterator: If pmu is NULL, we start at the begin,
875 	 * otherwise return the next pmu. Returns NULL on end.
876 	 */
877 	if (!pmu) {
878 		pmu_read_sysfs();
879 		pmu = list_prepare_entry(pmu, &pmus, list);
880 	}
881 	list_for_each_entry_continue(pmu, &pmus, list)
882 		return pmu;
883 	return NULL;
884 }
885 
886 struct perf_pmu *perf_pmu__find(const char *name)
887 {
888 	struct perf_pmu *pmu;
889 
890 	/*
891 	 * Once PMU is loaded it stays in the list,
892 	 * so we keep us from multiple reading/parsing
893 	 * the pmu format definitions.
894 	 */
895 	pmu = pmu_find(name);
896 	if (pmu)
897 		return pmu;
898 
899 	return pmu_lookup(name);
900 }
901 
902 static struct perf_pmu_format *
903 pmu_find_format(struct list_head *formats, const char *name)
904 {
905 	struct perf_pmu_format *format;
906 
907 	list_for_each_entry(format, formats, list)
908 		if (!strcmp(format->name, name))
909 			return format;
910 
911 	return NULL;
912 }
913 
914 __u64 perf_pmu__format_bits(struct list_head *formats, const char *name)
915 {
916 	struct perf_pmu_format *format = pmu_find_format(formats, name);
917 	__u64 bits = 0;
918 	int fbit;
919 
920 	if (!format)
921 		return 0;
922 
923 	for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS)
924 		bits |= 1ULL << fbit;
925 
926 	return bits;
927 }
928 
929 /*
930  * Sets value based on the format definition (format parameter)
931  * and unformated value (value parameter).
932  */
933 static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
934 			     bool zero)
935 {
936 	unsigned long fbit, vbit;
937 
938 	for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
939 
940 		if (!test_bit(fbit, format))
941 			continue;
942 
943 		if (value & (1llu << vbit++))
944 			*v |= (1llu << fbit);
945 		else if (zero)
946 			*v &= ~(1llu << fbit);
947 	}
948 }
949 
950 static __u64 pmu_format_max_value(const unsigned long *format)
951 {
952 	int w;
953 
954 	w = bitmap_weight(format, PERF_PMU_FORMAT_BITS);
955 	if (!w)
956 		return 0;
957 	if (w < 64)
958 		return (1ULL << w) - 1;
959 	return -1;
960 }
961 
962 /*
963  * Term is a string term, and might be a param-term. Try to look up it's value
964  * in the remaining terms.
965  * - We have a term like "base-or-format-term=param-term",
966  * - We need to find the value supplied for "param-term" (with param-term named
967  *   in a config string) later on in the term list.
968  */
969 static int pmu_resolve_param_term(struct parse_events_term *term,
970 				  struct list_head *head_terms,
971 				  __u64 *value)
972 {
973 	struct parse_events_term *t;
974 
975 	list_for_each_entry(t, head_terms, list) {
976 		if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
977 			if (!strcmp(t->config, term->config)) {
978 				t->used = true;
979 				*value = t->val.num;
980 				return 0;
981 			}
982 		}
983 	}
984 
985 	if (verbose > 0)
986 		printf("Required parameter '%s' not specified\n", term->config);
987 
988 	return -1;
989 }
990 
991 static char *pmu_formats_string(struct list_head *formats)
992 {
993 	struct perf_pmu_format *format;
994 	char *str = NULL;
995 	struct strbuf buf = STRBUF_INIT;
996 	unsigned i = 0;
997 
998 	if (!formats)
999 		return NULL;
1000 
1001 	/* sysfs exported terms */
1002 	list_for_each_entry(format, formats, list)
1003 		if (strbuf_addf(&buf, i++ ? ",%s" : "%s", format->name) < 0)
1004 			goto error;
1005 
1006 	str = strbuf_detach(&buf, NULL);
1007 error:
1008 	strbuf_release(&buf);
1009 
1010 	return str;
1011 }
1012 
1013 /*
1014  * Setup one of config[12] attr members based on the
1015  * user input data - term parameter.
1016  */
1017 static int pmu_config_term(struct list_head *formats,
1018 			   struct perf_event_attr *attr,
1019 			   struct parse_events_term *term,
1020 			   struct list_head *head_terms,
1021 			   bool zero, struct parse_events_error *err)
1022 {
1023 	struct perf_pmu_format *format;
1024 	__u64 *vp;
1025 	__u64 val, max_val;
1026 
1027 	/*
1028 	 * If this is a parameter we've already used for parameterized-eval,
1029 	 * skip it in normal eval.
1030 	 */
1031 	if (term->used)
1032 		return 0;
1033 
1034 	/*
1035 	 * Hardcoded terms should be already in, so nothing
1036 	 * to be done for them.
1037 	 */
1038 	if (parse_events__is_hardcoded_term(term))
1039 		return 0;
1040 
1041 	format = pmu_find_format(formats, term->config);
1042 	if (!format) {
1043 		if (verbose > 0)
1044 			printf("Invalid event/parameter '%s'\n", term->config);
1045 		if (err) {
1046 			char *pmu_term = pmu_formats_string(formats);
1047 
1048 			err->idx  = term->err_term;
1049 			err->str  = strdup("unknown term");
1050 			err->help = parse_events_formats_error_string(pmu_term);
1051 			free(pmu_term);
1052 		}
1053 		return -EINVAL;
1054 	}
1055 
1056 	switch (format->value) {
1057 	case PERF_PMU_FORMAT_VALUE_CONFIG:
1058 		vp = &attr->config;
1059 		break;
1060 	case PERF_PMU_FORMAT_VALUE_CONFIG1:
1061 		vp = &attr->config1;
1062 		break;
1063 	case PERF_PMU_FORMAT_VALUE_CONFIG2:
1064 		vp = &attr->config2;
1065 		break;
1066 	default:
1067 		return -EINVAL;
1068 	}
1069 
1070 	/*
1071 	 * Either directly use a numeric term, or try to translate string terms
1072 	 * using event parameters.
1073 	 */
1074 	if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
1075 		if (term->no_value &&
1076 		    bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) {
1077 			if (err) {
1078 				err->idx = term->err_val;
1079 				err->str = strdup("no value assigned for term");
1080 			}
1081 			return -EINVAL;
1082 		}
1083 
1084 		val = term->val.num;
1085 	} else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
1086 		if (strcmp(term->val.str, "?")) {
1087 			if (verbose > 0) {
1088 				pr_info("Invalid sysfs entry %s=%s\n",
1089 						term->config, term->val.str);
1090 			}
1091 			if (err) {
1092 				err->idx = term->err_val;
1093 				err->str = strdup("expected numeric value");
1094 			}
1095 			return -EINVAL;
1096 		}
1097 
1098 		if (pmu_resolve_param_term(term, head_terms, &val))
1099 			return -EINVAL;
1100 	} else
1101 		return -EINVAL;
1102 
1103 	max_val = pmu_format_max_value(format->bits);
1104 	if (val > max_val) {
1105 		if (err) {
1106 			err->idx = term->err_val;
1107 			if (asprintf(&err->str,
1108 				     "value too big for format, maximum is %llu",
1109 				     (unsigned long long)max_val) < 0)
1110 				err->str = strdup("value too big for format");
1111 			return -EINVAL;
1112 		}
1113 		/*
1114 		 * Assume we don't care if !err, in which case the value will be
1115 		 * silently truncated.
1116 		 */
1117 	}
1118 
1119 	pmu_format_value(format->bits, val, vp, zero);
1120 	return 0;
1121 }
1122 
1123 int perf_pmu__config_terms(struct list_head *formats,
1124 			   struct perf_event_attr *attr,
1125 			   struct list_head *head_terms,
1126 			   bool zero, struct parse_events_error *err)
1127 {
1128 	struct parse_events_term *term;
1129 
1130 	list_for_each_entry(term, head_terms, list) {
1131 		if (pmu_config_term(formats, attr, term, head_terms,
1132 				    zero, err))
1133 			return -EINVAL;
1134 	}
1135 
1136 	return 0;
1137 }
1138 
1139 /*
1140  * Configures event's 'attr' parameter based on the:
1141  * 1) users input - specified in terms parameter
1142  * 2) pmu format definitions - specified by pmu parameter
1143  */
1144 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
1145 		     struct list_head *head_terms,
1146 		     struct parse_events_error *err)
1147 {
1148 	bool zero = !!pmu->default_config;
1149 
1150 	attr->type = pmu->type;
1151 	return perf_pmu__config_terms(&pmu->format, attr, head_terms,
1152 				      zero, err);
1153 }
1154 
1155 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
1156 					     struct parse_events_term *term)
1157 {
1158 	struct perf_pmu_alias *alias;
1159 	char *name;
1160 
1161 	if (parse_events__is_hardcoded_term(term))
1162 		return NULL;
1163 
1164 	if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
1165 		if (term->val.num != 1)
1166 			return NULL;
1167 		if (pmu_find_format(&pmu->format, term->config))
1168 			return NULL;
1169 		name = term->config;
1170 	} else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
1171 		if (strcasecmp(term->config, "event"))
1172 			return NULL;
1173 		name = term->val.str;
1174 	} else {
1175 		return NULL;
1176 	}
1177 
1178 	list_for_each_entry(alias, &pmu->aliases, list) {
1179 		if (!strcasecmp(alias->name, name))
1180 			return alias;
1181 	}
1182 	return NULL;
1183 }
1184 
1185 
1186 static int check_info_data(struct perf_pmu_alias *alias,
1187 			   struct perf_pmu_info *info)
1188 {
1189 	/*
1190 	 * Only one term in event definition can
1191 	 * define unit, scale and snapshot, fail
1192 	 * if there's more than one.
1193 	 */
1194 	if ((info->unit && alias->unit[0]) ||
1195 	    (info->scale && alias->scale) ||
1196 	    (info->snapshot && alias->snapshot))
1197 		return -EINVAL;
1198 
1199 	if (alias->unit[0])
1200 		info->unit = alias->unit;
1201 
1202 	if (alias->scale)
1203 		info->scale = alias->scale;
1204 
1205 	if (alias->snapshot)
1206 		info->snapshot = alias->snapshot;
1207 
1208 	return 0;
1209 }
1210 
1211 /*
1212  * Find alias in the terms list and replace it with the terms
1213  * defined for the alias
1214  */
1215 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
1216 			  struct perf_pmu_info *info)
1217 {
1218 	struct parse_events_term *term, *h;
1219 	struct perf_pmu_alias *alias;
1220 	int ret;
1221 
1222 	info->per_pkg = false;
1223 
1224 	/*
1225 	 * Mark unit and scale as not set
1226 	 * (different from default values, see below)
1227 	 */
1228 	info->unit     = NULL;
1229 	info->scale    = 0.0;
1230 	info->snapshot = false;
1231 	info->metric_expr = NULL;
1232 	info->metric_name = NULL;
1233 
1234 	list_for_each_entry_safe(term, h, head_terms, list) {
1235 		alias = pmu_find_alias(pmu, term);
1236 		if (!alias)
1237 			continue;
1238 		ret = pmu_alias_terms(alias, &term->list);
1239 		if (ret)
1240 			return ret;
1241 
1242 		ret = check_info_data(alias, info);
1243 		if (ret)
1244 			return ret;
1245 
1246 		if (alias->per_pkg)
1247 			info->per_pkg = true;
1248 		info->metric_expr = alias->metric_expr;
1249 		info->metric_name = alias->metric_name;
1250 
1251 		list_del_init(&term->list);
1252 		free(term);
1253 	}
1254 
1255 	/*
1256 	 * if no unit or scale foundin aliases, then
1257 	 * set defaults as for evsel
1258 	 * unit cannot left to NULL
1259 	 */
1260 	if (info->unit == NULL)
1261 		info->unit   = "";
1262 
1263 	if (info->scale == 0.0)
1264 		info->scale  = 1.0;
1265 
1266 	return 0;
1267 }
1268 
1269 int perf_pmu__new_format(struct list_head *list, char *name,
1270 			 int config, unsigned long *bits)
1271 {
1272 	struct perf_pmu_format *format;
1273 
1274 	format = zalloc(sizeof(*format));
1275 	if (!format)
1276 		return -ENOMEM;
1277 
1278 	format->name = strdup(name);
1279 	format->value = config;
1280 	memcpy(format->bits, bits, sizeof(format->bits));
1281 
1282 	list_add_tail(&format->list, list);
1283 	return 0;
1284 }
1285 
1286 void perf_pmu__set_format(unsigned long *bits, long from, long to)
1287 {
1288 	long b;
1289 
1290 	if (!to)
1291 		to = from;
1292 
1293 	memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS));
1294 	for (b = from; b <= to; b++)
1295 		set_bit(b, bits);
1296 }
1297 
1298 static int sub_non_neg(int a, int b)
1299 {
1300 	if (b > a)
1301 		return 0;
1302 	return a - b;
1303 }
1304 
1305 static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
1306 			  struct perf_pmu_alias *alias)
1307 {
1308 	struct parse_events_term *term;
1309 	int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name);
1310 
1311 	list_for_each_entry(term, &alias->terms, list) {
1312 		if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
1313 			used += snprintf(buf + used, sub_non_neg(len, used),
1314 					",%s=%s", term->config,
1315 					term->val.str);
1316 	}
1317 
1318 	if (sub_non_neg(len, used) > 0) {
1319 		buf[used] = '/';
1320 		used++;
1321 	}
1322 	if (sub_non_neg(len, used) > 0) {
1323 		buf[used] = '\0';
1324 		used++;
1325 	} else
1326 		buf[len - 1] = '\0';
1327 
1328 	return buf;
1329 }
1330 
1331 static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
1332 			     struct perf_pmu_alias *alias)
1333 {
1334 	snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
1335 	return buf;
1336 }
1337 
1338 struct sevent {
1339 	char *name;
1340 	char *desc;
1341 	char *topic;
1342 	char *str;
1343 	char *pmu;
1344 	char *metric_expr;
1345 	char *metric_name;
1346 };
1347 
1348 static int cmp_sevent(const void *a, const void *b)
1349 {
1350 	const struct sevent *as = a;
1351 	const struct sevent *bs = b;
1352 
1353 	/* Put extra events last */
1354 	if (!!as->desc != !!bs->desc)
1355 		return !!as->desc - !!bs->desc;
1356 	if (as->topic && bs->topic) {
1357 		int n = strcmp(as->topic, bs->topic);
1358 
1359 		if (n)
1360 			return n;
1361 	}
1362 	return strcmp(as->name, bs->name);
1363 }
1364 
1365 static void wordwrap(char *s, int start, int max, int corr)
1366 {
1367 	int column = start;
1368 	int n;
1369 
1370 	while (*s) {
1371 		int wlen = strcspn(s, " \t");
1372 
1373 		if (column + wlen >= max && column > start) {
1374 			printf("\n%*s", start, "");
1375 			column = start + corr;
1376 		}
1377 		n = printf("%s%.*s", column > start ? " " : "", wlen, s);
1378 		if (n <= 0)
1379 			break;
1380 		s += wlen;
1381 		column += n;
1382 		s = skip_spaces(s);
1383 	}
1384 }
1385 
1386 void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
1387 			bool long_desc, bool details_flag)
1388 {
1389 	struct perf_pmu *pmu;
1390 	struct perf_pmu_alias *alias;
1391 	char buf[1024];
1392 	int printed = 0;
1393 	int len, j;
1394 	struct sevent *aliases;
1395 	int numdesc = 0;
1396 	int columns = pager_get_columns();
1397 	char *topic = NULL;
1398 
1399 	pmu = NULL;
1400 	len = 0;
1401 	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1402 		list_for_each_entry(alias, &pmu->aliases, list)
1403 			len++;
1404 		if (pmu->selectable)
1405 			len++;
1406 	}
1407 	aliases = zalloc(sizeof(struct sevent) * len);
1408 	if (!aliases)
1409 		goto out_enomem;
1410 	pmu = NULL;
1411 	j = 0;
1412 	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1413 		list_for_each_entry(alias, &pmu->aliases, list) {
1414 			char *name = alias->desc ? alias->name :
1415 				format_alias(buf, sizeof(buf), pmu, alias);
1416 			bool is_cpu = !strcmp(pmu->name, "cpu");
1417 
1418 			if (event_glob != NULL &&
1419 			    !(strglobmatch_nocase(name, event_glob) ||
1420 			      (!is_cpu && strglobmatch_nocase(alias->name,
1421 						       event_glob)) ||
1422 			      (alias->topic &&
1423 			       strglobmatch_nocase(alias->topic, event_glob))))
1424 				continue;
1425 
1426 			if (is_cpu && !name_only && !alias->desc)
1427 				name = format_alias_or(buf, sizeof(buf), pmu, alias);
1428 
1429 			aliases[j].name = name;
1430 			if (is_cpu && !name_only && !alias->desc)
1431 				aliases[j].name = format_alias_or(buf,
1432 								  sizeof(buf),
1433 								  pmu, alias);
1434 			aliases[j].name = strdup(aliases[j].name);
1435 			if (!aliases[j].name)
1436 				goto out_enomem;
1437 
1438 			aliases[j].desc = long_desc ? alias->long_desc :
1439 						alias->desc;
1440 			aliases[j].topic = alias->topic;
1441 			aliases[j].str = alias->str;
1442 			aliases[j].pmu = pmu->name;
1443 			aliases[j].metric_expr = alias->metric_expr;
1444 			aliases[j].metric_name = alias->metric_name;
1445 			j++;
1446 		}
1447 		if (pmu->selectable &&
1448 		    (event_glob == NULL || strglobmatch(pmu->name, event_glob))) {
1449 			char *s;
1450 			if (asprintf(&s, "%s//", pmu->name) < 0)
1451 				goto out_enomem;
1452 			aliases[j].name = s;
1453 			j++;
1454 		}
1455 	}
1456 	len = j;
1457 	qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
1458 	for (j = 0; j < len; j++) {
1459 		/* Skip duplicates */
1460 		if (j > 0 && !strcmp(aliases[j].name, aliases[j - 1].name))
1461 			continue;
1462 		if (name_only) {
1463 			printf("%s ", aliases[j].name);
1464 			continue;
1465 		}
1466 		if (aliases[j].desc && !quiet_flag) {
1467 			if (numdesc++ == 0)
1468 				printf("\n");
1469 			if (aliases[j].topic && (!topic ||
1470 					strcmp(topic, aliases[j].topic))) {
1471 				printf("%s%s:\n", topic ? "\n" : "",
1472 						aliases[j].topic);
1473 				topic = aliases[j].topic;
1474 			}
1475 			printf("  %-50s\n", aliases[j].name);
1476 			printf("%*s", 8, "[");
1477 			wordwrap(aliases[j].desc, 8, columns, 0);
1478 			printf("]\n");
1479 			if (details_flag) {
1480 				printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str);
1481 				if (aliases[j].metric_name)
1482 					printf(" MetricName: %s", aliases[j].metric_name);
1483 				if (aliases[j].metric_expr)
1484 					printf(" MetricExpr: %s", aliases[j].metric_expr);
1485 				putchar('\n');
1486 			}
1487 		} else
1488 			printf("  %-50s [Kernel PMU event]\n", aliases[j].name);
1489 		printed++;
1490 	}
1491 	if (printed && pager_in_use())
1492 		printf("\n");
1493 out_free:
1494 	for (j = 0; j < len; j++)
1495 		zfree(&aliases[j].name);
1496 	zfree(&aliases);
1497 	return;
1498 
1499 out_enomem:
1500 	printf("FATAL: not enough memory to print PMU events\n");
1501 	if (aliases)
1502 		goto out_free;
1503 }
1504 
1505 bool pmu_have_event(const char *pname, const char *name)
1506 {
1507 	struct perf_pmu *pmu;
1508 	struct perf_pmu_alias *alias;
1509 
1510 	pmu = NULL;
1511 	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1512 		if (strcmp(pname, pmu->name))
1513 			continue;
1514 		list_for_each_entry(alias, &pmu->aliases, list)
1515 			if (!strcmp(alias->name, name))
1516 				return true;
1517 	}
1518 	return false;
1519 }
1520 
1521 static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
1522 {
1523 	struct stat st;
1524 	char path[PATH_MAX];
1525 	const char *sysfs;
1526 
1527 	sysfs = sysfs__mountpoint();
1528 	if (!sysfs)
1529 		return NULL;
1530 
1531 	snprintf(path, PATH_MAX,
1532 		 "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
1533 
1534 	if (stat(path, &st) < 0)
1535 		return NULL;
1536 
1537 	return fopen(path, "r");
1538 }
1539 
1540 int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
1541 			...)
1542 {
1543 	va_list args;
1544 	FILE *file;
1545 	int ret = EOF;
1546 
1547 	va_start(args, fmt);
1548 	file = perf_pmu__open_file(pmu, name);
1549 	if (file) {
1550 		ret = vfscanf(file, fmt, args);
1551 		fclose(file);
1552 	}
1553 	va_end(args);
1554 	return ret;
1555 }
1556