brintos

brintos / linux-shallow public Read only

0
0
Text · 52.8 KiB · 61bdda0 Raw
2290 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <linux/list.h>3#include <linux/compiler.h>4#include <linux/string.h>5#include <linux/zalloc.h>6#include <linux/ctype.h>7#include <sys/types.h>8#include <fcntl.h>9#include <sys/stat.h>10#include <unistd.h>11#include <stdio.h>12#include <stdbool.h>13#include <dirent.h>14#include <api/fs/fs.h>15#include <locale.h>16#include <fnmatch.h>17#include <math.h>18#include "debug.h"19#include "evsel.h"20#include "pmu.h"21#include "pmus.h"22#include <util/pmu-bison.h>23#include <util/pmu-flex.h>24#include "parse-events.h"25#include "print-events.h"26#include "header.h"27#include "string2.h"28#include "strbuf.h"29#include "fncache.h"30#include "util/evsel_config.h"31#include <regex.h>32 33#define UNIT_MAX_LEN	31 /* max length for event unit name */34 35enum event_source {36	/* An event loaded from /sys/devices/<pmu>/events. */37	EVENT_SRC_SYSFS,38	/* An event loaded from a CPUID matched json file. */39	EVENT_SRC_CPU_JSON,40	/*41	 * An event loaded from a /sys/devices/<pmu>/identifier matched json42	 * file.43	 */44	EVENT_SRC_SYS_JSON,45};46 47/**48 * struct perf_pmu_alias - An event either read from sysfs or builtin in49 * pmu-events.c, created by parsing the pmu-events json files.50 */51struct perf_pmu_alias {52	/** @name: Name of the event like "mem-loads". */53	char *name;54	/** @desc: Optional short description of the event. */55	char *desc;56	/** @long_desc: Optional long description. */57	char *long_desc;58	/**59	 * @topic: Optional topic such as cache or pipeline, particularly for60	 * json events.61	 */62	char *topic;63	/** @terms: Owned list of the original parsed parameters. */64	struct parse_events_terms terms;65	/** @list: List element of struct perf_pmu aliases. */66	struct list_head list;67	/**68	 * @pmu_name: The name copied from the json struct pmu_event. This can69	 * differ from the PMU name as it won't have suffixes.70	 */71	char *pmu_name;72	/** @unit: Units for the event, such as bytes or cache lines. */73	char unit[UNIT_MAX_LEN+1];74	/** @scale: Value to scale read counter values by. */75	double scale;76	/**77	 * @per_pkg: Does the file78	 * <sysfs>/bus/event_source/devices/<pmu_name>/events/<name>.per-pkg or79	 * equivalent json value exist and have the value 1.80	 */81	bool per_pkg;82	/**83	 * @snapshot: Does the file84	 * <sysfs>/bus/event_source/devices/<pmu_name>/events/<name>.snapshot85	 * exist and have the value 1.86	 */87	bool snapshot;88	/**89	 * @deprecated: Is the event hidden and so not shown in perf list by90	 * default.91	 */92	bool deprecated;93	/** @from_sysfs: Was the alias from sysfs or a json event? */94	bool from_sysfs;95	/** @info_loaded: Have the scale, unit and other values been read from disk? */96	bool info_loaded;97};98 99/**100 * struct perf_pmu_format - Values from a format file read from101 * <sysfs>/devices/cpu/format/ held in struct perf_pmu.102 *103 * For example, the contents of <sysfs>/devices/cpu/format/event may be104 * "config:0-7" and will be represented here as name="event",105 * value=PERF_PMU_FORMAT_VALUE_CONFIG and bits 0 to 7 will be set.106 */107struct perf_pmu_format {108	/** @list: Element on list within struct perf_pmu. */109	struct list_head list;110	/** @bits: Which config bits are set by this format value. */111	DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);112	/** @name: The modifier/file name. */113	char *name;114	/**115	 * @value : Which config value the format relates to. Supported values116	 * are from PERF_PMU_FORMAT_VALUE_CONFIG to117	 * PERF_PMU_FORMAT_VALUE_CONFIG_END.118	 */119	u16 value;120	/** @loaded: Has the contents been loaded/parsed. */121	bool loaded;122};123 124static int pmu_aliases_parse(struct perf_pmu *pmu);125 126static struct perf_pmu_format *perf_pmu__new_format(struct list_head *list, char *name)127{128	struct perf_pmu_format *format;129 130	format = zalloc(sizeof(*format));131	if (!format)132		return NULL;133 134	format->name = strdup(name);135	if (!format->name) {136		free(format);137		return NULL;138	}139	list_add_tail(&format->list, list);140	return format;141}142 143/* Called at the end of parsing a format. */144void perf_pmu_format__set_value(void *vformat, int config, unsigned long *bits)145{146	struct perf_pmu_format *format = vformat;147 148	format->value = config;149	memcpy(format->bits, bits, sizeof(format->bits));150}151 152static void __perf_pmu_format__load(struct perf_pmu_format *format, FILE *file)153{154	void *scanner;155	int ret;156 157	ret = perf_pmu_lex_init(&scanner);158	if (ret)159		return;160 161	perf_pmu_set_in(file, scanner);162	ret = perf_pmu_parse(format, scanner);163	perf_pmu_lex_destroy(scanner);164	format->loaded = true;165}166 167static void perf_pmu_format__load(const struct perf_pmu *pmu, struct perf_pmu_format *format)168{169	char path[PATH_MAX];170	FILE *file = NULL;171 172	if (format->loaded)173		return;174 175	if (!perf_pmu__pathname_scnprintf(path, sizeof(path), pmu->name, "format"))176		return;177 178	assert(strlen(path) + strlen(format->name) + 2 < sizeof(path));179	strcat(path, "/");180	strcat(path, format->name);181 182	file = fopen(path, "r");183	if (!file)184		return;185	__perf_pmu_format__load(format, file);186	fclose(file);187}188 189/*190 * Parse & process all the sysfs attributes located under191 * the directory specified in 'dir' parameter.192 */193static int perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd, bool eager_load)194{195	struct dirent *evt_ent;196	DIR *format_dir;197	int ret = 0;198 199	format_dir = fdopendir(dirfd);200	if (!format_dir)201		return -EINVAL;202 203	while ((evt_ent = readdir(format_dir)) != NULL) {204		struct perf_pmu_format *format;205		char *name = evt_ent->d_name;206 207		if (!strcmp(name, ".") || !strcmp(name, ".."))208			continue;209 210		format = perf_pmu__new_format(&pmu->format, name);211		if (!format) {212			ret = -ENOMEM;213			break;214		}215 216		if (eager_load) {217			FILE *file;218			int fd = openat(dirfd, name, O_RDONLY);219 220			if (fd < 0) {221				ret = -errno;222				break;223			}224			file = fdopen(fd, "r");225			if (!file) {226				close(fd);227				break;228			}229			__perf_pmu_format__load(format, file);230			fclose(file);231		}232	}233 234	closedir(format_dir);235	return ret;236}237 238/*239 * Reading/parsing the default pmu format definition, which should be240 * located at:241 * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.242 */243static int pmu_format(struct perf_pmu *pmu, int dirfd, const char *name, bool eager_load)244{245	int fd;246 247	fd = perf_pmu__pathname_fd(dirfd, name, "format", O_DIRECTORY);248	if (fd < 0)249		return 0;250 251	/* it'll close the fd */252	if (perf_pmu__format_parse(pmu, fd, eager_load))253		return -1;254 255	return 0;256}257 258int perf_pmu__convert_scale(const char *scale, char **end, double *sval)259{260	char *lc;261	int ret = 0;262 263	/*264	 * save current locale265	 */266	lc = setlocale(LC_NUMERIC, NULL);267 268	/*269	 * The lc string may be allocated in static storage,270	 * so get a dynamic copy to make it survive setlocale271	 * call below.272	 */273	lc = strdup(lc);274	if (!lc) {275		ret = -ENOMEM;276		goto out;277	}278 279	/*280	 * force to C locale to ensure kernel281	 * scale string is converted correctly.282	 * kernel uses default C locale.283	 */284	setlocale(LC_NUMERIC, "C");285 286	*sval = strtod(scale, end);287 288out:289	/* restore locale */290	setlocale(LC_NUMERIC, lc);291	free(lc);292	return ret;293}294 295static int perf_pmu__parse_scale(struct perf_pmu *pmu, struct perf_pmu_alias *alias)296{297	struct stat st;298	ssize_t sret;299	size_t len;300	char scale[128];301	int fd, ret = -1;302	char path[PATH_MAX];303 304	len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));305	if (!len)306		return 0;307	scnprintf(path + len, sizeof(path) - len, "%s/events/%s.scale", pmu->name, alias->name);308 309	fd = open(path, O_RDONLY);310	if (fd == -1)311		return -1;312 313	if (fstat(fd, &st) < 0)314		goto error;315 316	sret = read(fd, scale, sizeof(scale)-1);317	if (sret < 0)318		goto error;319 320	if (scale[sret - 1] == '\n')321		scale[sret - 1] = '\0';322	else323		scale[sret] = '\0';324 325	ret = perf_pmu__convert_scale(scale, NULL, &alias->scale);326error:327	close(fd);328	return ret;329}330 331static int perf_pmu__parse_unit(struct perf_pmu *pmu, struct perf_pmu_alias *alias)332{333	char path[PATH_MAX];334	size_t len;335	ssize_t sret;336	int fd;337 338 339	len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));340	if (!len)341		return 0;342	scnprintf(path + len, sizeof(path) - len, "%s/events/%s.unit", pmu->name, alias->name);343 344	fd = open(path, O_RDONLY);345	if (fd == -1)346		return -1;347 348	sret = read(fd, alias->unit, UNIT_MAX_LEN);349	if (sret < 0)350		goto error;351 352	close(fd);353 354	if (alias->unit[sret - 1] == '\n')355		alias->unit[sret - 1] = '\0';356	else357		alias->unit[sret] = '\0';358 359	return 0;360error:361	close(fd);362	alias->unit[0] = '\0';363	return -1;364}365 366static bool perf_pmu__parse_event_source_bool(const char *pmu_name, const char *event_name,367					      const char *suffix)368{369	char path[PATH_MAX];370	size_t len;371	int fd;372 373	len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));374	if (!len)375		return false;376 377	scnprintf(path + len, sizeof(path) - len, "%s/events/%s.%s", pmu_name, event_name, suffix);378 379	fd = open(path, O_RDONLY);380	if (fd == -1)381		return false;382 383#ifndef NDEBUG384	{385		char buf[8];386 387		len = read(fd, buf, sizeof(buf));388		assert(len == 1 || len == 2);389		assert(buf[0] == '1');390	}391#endif392 393	close(fd);394	return true;395}396 397static void perf_pmu__parse_per_pkg(struct perf_pmu *pmu, struct perf_pmu_alias *alias)398{399	alias->per_pkg = perf_pmu__parse_event_source_bool(pmu->name, alias->name, "per-pkg");400}401 402static void perf_pmu__parse_snapshot(struct perf_pmu *pmu, struct perf_pmu_alias *alias)403{404	alias->snapshot = perf_pmu__parse_event_source_bool(pmu->name, alias->name, "snapshot");405}406 407/* Delete an alias entry. */408static void perf_pmu_free_alias(struct perf_pmu_alias *newalias)409{410	zfree(&newalias->name);411	zfree(&newalias->desc);412	zfree(&newalias->long_desc);413	zfree(&newalias->topic);414	zfree(&newalias->pmu_name);415	parse_events_terms__exit(&newalias->terms);416	free(newalias);417}418 419static void perf_pmu__del_aliases(struct perf_pmu *pmu)420{421	struct perf_pmu_alias *alias, *tmp;422 423	list_for_each_entry_safe(alias, tmp, &pmu->aliases, list) {424		list_del(&alias->list);425		perf_pmu_free_alias(alias);426	}427}428 429static struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu,430						   const char *name,431						   bool load)432{433	struct perf_pmu_alias *alias;434 435	if (load && !pmu->sysfs_aliases_loaded) {436		bool has_sysfs_event;437		char event_file_name[FILENAME_MAX + 8];438 439		/*440		 * Test if alias/event 'name' exists in the PMU's sysfs/events441		 * directory. If not skip parsing the sysfs aliases. Sysfs event442		 * name must be all lower or all upper case.443		 */444		scnprintf(event_file_name, sizeof(event_file_name), "events/%s", name);445		for (size_t i = 7, n = 7 + strlen(name); i < n; i++)446			event_file_name[i] = tolower(event_file_name[i]);447 448		has_sysfs_event = perf_pmu__file_exists(pmu, event_file_name);449		if (!has_sysfs_event) {450			for (size_t i = 7, n = 7 + strlen(name); i < n; i++)451				event_file_name[i] = toupper(event_file_name[i]);452 453			has_sysfs_event = perf_pmu__file_exists(pmu, event_file_name);454		}455		if (has_sysfs_event)456			pmu_aliases_parse(pmu);457 458	}459	list_for_each_entry(alias, &pmu->aliases, list) {460		if (!strcasecmp(alias->name, name))461			return alias;462	}463	return NULL;464}465 466static bool assign_str(const char *name, const char *field, char **old_str,467				const char *new_str)468{469	if (!*old_str && new_str) {470		*old_str = strdup(new_str);471		return true;472	}473 474	if (!new_str || !strcasecmp(*old_str, new_str))475		return false; /* Nothing to update. */476 477	pr_debug("alias %s differs in field '%s' ('%s' != '%s')\n",478		name, field, *old_str, new_str);479	zfree(old_str);480	*old_str = strdup(new_str);481	return true;482}483 484static void read_alias_info(struct perf_pmu *pmu, struct perf_pmu_alias *alias)485{486	if (!alias->from_sysfs || alias->info_loaded)487		return;488 489	/*490	 * load unit name and scale if available491	 */492	perf_pmu__parse_unit(pmu, alias);493	perf_pmu__parse_scale(pmu, alias);494	perf_pmu__parse_per_pkg(pmu, alias);495	perf_pmu__parse_snapshot(pmu, alias);496}497 498struct update_alias_data {499	struct perf_pmu *pmu;500	struct perf_pmu_alias *alias;501};502 503static int update_alias(const struct pmu_event *pe,504			const struct pmu_events_table *table __maybe_unused,505			void *vdata)506{507	struct update_alias_data *data = vdata;508	int ret = 0;509 510	read_alias_info(data->pmu, data->alias);511	assign_str(pe->name, "desc", &data->alias->desc, pe->desc);512	assign_str(pe->name, "long_desc", &data->alias->long_desc, pe->long_desc);513	assign_str(pe->name, "topic", &data->alias->topic, pe->topic);514	data->alias->per_pkg = pe->perpkg;515	if (pe->event) {516		parse_events_terms__exit(&data->alias->terms);517		ret = parse_events_terms(&data->alias->terms, pe->event, /*input=*/NULL);518	}519	if (!ret && pe->unit) {520		char *unit;521 522		ret = perf_pmu__convert_scale(pe->unit, &unit, &data->alias->scale);523		if (!ret)524			snprintf(data->alias->unit, sizeof(data->alias->unit), "%s", unit);525	}526	return ret;527}528 529static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name,530				const char *desc, const char *val, FILE *val_fd,531			        const struct pmu_event *pe, enum event_source src)532{533	struct perf_pmu_alias *alias;534	int ret;535	const char *long_desc = NULL, *topic = NULL, *unit = NULL, *pmu_name = NULL;536	bool deprecated = false, perpkg = false;537 538	if (perf_pmu__find_alias(pmu, name, /*load=*/ false)) {539		/* Alias was already created/loaded. */540		return 0;541	}542 543	if (pe) {544		long_desc = pe->long_desc;545		topic = pe->topic;546		unit = pe->unit;547		perpkg = pe->perpkg;548		deprecated = pe->deprecated;549		if (pe->pmu && strcmp(pe->pmu, "default_core"))550			pmu_name = pe->pmu;551	}552 553	alias = zalloc(sizeof(*alias));554	if (!alias)555		return -ENOMEM;556 557	parse_events_terms__init(&alias->terms);558	alias->scale = 1.0;559	alias->unit[0] = '\0';560	alias->per_pkg = perpkg;561	alias->snapshot = false;562	alias->deprecated = deprecated;563 564	ret = parse_events_terms(&alias->terms, val, val_fd);565	if (ret) {566		pr_err("Cannot parse alias %s: %d\n", val, ret);567		free(alias);568		return ret;569	}570 571	alias->name = strdup(name);572	alias->desc = desc ? strdup(desc) : NULL;573	alias->long_desc = long_desc ? strdup(long_desc) :574				desc ? strdup(desc) : NULL;575	alias->topic = topic ? strdup(topic) : NULL;576	alias->pmu_name = pmu_name ? strdup(pmu_name) : NULL;577	if (unit) {578		if (perf_pmu__convert_scale(unit, (char **)&unit, &alias->scale) < 0) {579			perf_pmu_free_alias(alias);580			return -1;581		}582		snprintf(alias->unit, sizeof(alias->unit), "%s", unit);583	}584	switch (src) {585	default:586	case EVENT_SRC_SYSFS:587		alias->from_sysfs = true;588		if (pmu->events_table) {589			/* Update an event from sysfs with json data. */590			struct update_alias_data data = {591				.pmu = pmu,592				.alias = alias,593			};594			if (pmu_events_table__find_event(pmu->events_table, pmu, name,595							 update_alias, &data) == 0)596				pmu->cpu_json_aliases++;597		}598		pmu->sysfs_aliases++;599		break;600	case  EVENT_SRC_CPU_JSON:601		pmu->cpu_json_aliases++;602		break;603	case  EVENT_SRC_SYS_JSON:604		pmu->sys_json_aliases++;605		break;606 607	}608	list_add_tail(&alias->list, &pmu->aliases);609	return 0;610}611 612static inline bool pmu_alias_info_file(const char *name)613{614	size_t len;615 616	len = strlen(name);617	if (len > 5 && !strcmp(name + len - 5, ".unit"))618		return true;619	if (len > 6 && !strcmp(name + len - 6, ".scale"))620		return true;621	if (len > 8 && !strcmp(name + len - 8, ".per-pkg"))622		return true;623	if (len > 9 && !strcmp(name + len - 9, ".snapshot"))624		return true;625 626	return false;627}628 629/*630 * Reading the pmu event aliases definition, which should be located at:631 * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.632 */633static int __pmu_aliases_parse(struct perf_pmu *pmu, int events_dir_fd)634{635	struct dirent *evt_ent;636	DIR *event_dir;637 638	event_dir = fdopendir(events_dir_fd);639	if (!event_dir)640		return -EINVAL;641 642	while ((evt_ent = readdir(event_dir))) {643		char *name = evt_ent->d_name;644		int fd;645		FILE *file;646 647		if (!strcmp(name, ".") || !strcmp(name, ".."))648			continue;649 650		/*651		 * skip info files parsed in perf_pmu__new_alias()652		 */653		if (pmu_alias_info_file(name))654			continue;655 656		fd = openat(events_dir_fd, name, O_RDONLY);657		if (fd == -1) {658			pr_debug("Cannot open %s\n", name);659			continue;660		}661		file = fdopen(fd, "r");662		if (!file) {663			close(fd);664			continue;665		}666 667		if (perf_pmu__new_alias(pmu, name, /*desc=*/ NULL,668					/*val=*/ NULL, file, /*pe=*/ NULL,669					EVENT_SRC_SYSFS) < 0)670			pr_debug("Cannot set up %s\n", name);671		fclose(file);672	}673 674	closedir(event_dir);675	pmu->sysfs_aliases_loaded = true;676	return 0;677}678 679static int pmu_aliases_parse(struct perf_pmu *pmu)680{681	char path[PATH_MAX];682	size_t len;683	int events_dir_fd, ret;684 685	if (pmu->sysfs_aliases_loaded)686		return 0;687 688	len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));689	if (!len)690		return 0;691	scnprintf(path + len, sizeof(path) - len, "%s/events", pmu->name);692 693	events_dir_fd = open(path, O_DIRECTORY);694	if (events_dir_fd == -1) {695		pmu->sysfs_aliases_loaded = true;696		return 0;697	}698	ret = __pmu_aliases_parse(pmu, events_dir_fd);699	close(events_dir_fd);700	return ret;701}702 703static int pmu_aliases_parse_eager(struct perf_pmu *pmu, int sysfs_fd)704{705	char path[FILENAME_MAX + 7];706	int ret, events_dir_fd;707 708	scnprintf(path, sizeof(path), "%s/events", pmu->name);709	events_dir_fd = openat(sysfs_fd, path, O_DIRECTORY, 0);710	if (events_dir_fd == -1) {711		pmu->sysfs_aliases_loaded = true;712		return 0;713	}714	ret = __pmu_aliases_parse(pmu, events_dir_fd);715	close(events_dir_fd);716	return ret;717}718 719static int pmu_alias_terms(struct perf_pmu_alias *alias, int err_loc, struct list_head *terms)720{721	struct parse_events_term *term, *cloned;722	struct parse_events_terms clone_terms;723 724	parse_events_terms__init(&clone_terms);725	list_for_each_entry(term, &alias->terms.terms, list) {726		int ret = parse_events_term__clone(&cloned, term);727 728		if (ret) {729			parse_events_terms__exit(&clone_terms);730			return ret;731		}732		/*733		 * Weak terms don't override command line options,734		 * which we don't want for implicit terms in aliases.735		 */736		cloned->weak = true;737		cloned->err_term = cloned->err_val = err_loc;738		list_add_tail(&cloned->list, &clone_terms.terms);739	}740	list_splice_init(&clone_terms.terms, terms);741	parse_events_terms__exit(&clone_terms);742	return 0;743}744 745/*746 * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64)747 * may have a "cpus" file.748 */749static struct perf_cpu_map *pmu_cpumask(int dirfd, const char *name, bool is_core)750{751	struct perf_cpu_map *cpus;752	const char *templates[] = {753		"cpumask",754		"cpus",755		NULL756	};757	const char **template;758	char pmu_name[PATH_MAX];759	struct perf_pmu pmu = {.name = pmu_name};760	FILE *file;761 762	strlcpy(pmu_name, name, sizeof(pmu_name));763	for (template = templates; *template; template++) {764		file = perf_pmu__open_file_at(&pmu, dirfd, *template);765		if (!file)766			continue;767		cpus = perf_cpu_map__read(file);768		fclose(file);769		if (cpus)770			return cpus;771	}772 773	/* Nothing found, for core PMUs assume this means all CPUs. */774	return is_core ? perf_cpu_map__get(cpu_map__online()) : NULL;775}776 777static bool pmu_is_uncore(int dirfd, const char *name)778{779	int fd;780 781	fd = perf_pmu__pathname_fd(dirfd, name, "cpumask", O_PATH);782	if (fd < 0)783		return false;784 785	close(fd);786	return true;787}788 789static char *pmu_id(const char *name)790{791	char path[PATH_MAX], *str;792	size_t len;793 794	perf_pmu__pathname_scnprintf(path, sizeof(path), name, "identifier");795 796	if (filename__read_str(path, &str, &len) < 0)797		return NULL;798 799	str[len - 1] = 0; /* remove line feed */800 801	return str;802}803 804/**805 * is_sysfs_pmu_core() - PMU CORE devices have different name other than cpu in806 *         sysfs on some platforms like ARM or Intel hybrid. Looking for807 *         possible the cpus file in sysfs files to identify whether this is a808 *         core device.809 * @name: The PMU name such as "cpu_atom".810 */811static int is_sysfs_pmu_core(const char *name)812{813	char path[PATH_MAX];814 815	if (!perf_pmu__pathname_scnprintf(path, sizeof(path), name, "cpus"))816		return 0;817	return file_available(path);818}819 820char *perf_pmu__getcpuid(struct perf_pmu *pmu)821{822	char *cpuid;823	static bool printed;824 825	cpuid = getenv("PERF_CPUID");826	if (cpuid)827		cpuid = strdup(cpuid);828	if (!cpuid)829		cpuid = get_cpuid_str(pmu);830	if (!cpuid)831		return NULL;832 833	if (!printed) {834		pr_debug("Using CPUID %s\n", cpuid);835		printed = true;836	}837	return cpuid;838}839 840__weak const struct pmu_metrics_table *pmu_metrics_table__find(void)841{842	return perf_pmu__find_metrics_table(NULL);843}844 845/**846 * Return the length of the PMU name not including the suffix for uncore PMUs.847 *848 * We want to deduplicate many similar uncore PMUs by stripping their suffixes,849 * but there are never going to be too many core PMUs and the suffixes might be850 * interesting. "arm_cortex_a53" vs "arm_cortex_a57" or "cpum_cf" for example.851 *852 * @skip_duplicate_pmus: False in verbose mode so all uncore PMUs are visible853 */854static size_t pmu_deduped_name_len(const struct perf_pmu *pmu, const char *name,855				   bool skip_duplicate_pmus)856{857	return skip_duplicate_pmus && !pmu->is_core858		? pmu_name_len_no_suffix(name)859		: strlen(name);860}861 862/**863 * perf_pmu__match_ignoring_suffix - Does the pmu_name match tok ignoring any864 *                                   trailing suffix? The Suffix must be in form865 *                                   tok_{digits}, or tok{digits}.866 * @pmu_name: The pmu_name with possible suffix.867 * @tok: The possible match to pmu_name without suffix.868 */869static bool perf_pmu__match_ignoring_suffix(const char *pmu_name, const char *tok)870{871	const char *p, *suffix;872	bool has_hex = false;873 874	if (strncmp(pmu_name, tok, strlen(tok)))875		return false;876 877	suffix = p = pmu_name + strlen(tok);878	if (*p == 0)879		return true;880 881	if (*p == '_') {882		++p;883		++suffix;884	}885 886	/* Ensure we end in a number */887	while (1) {888		if (!isxdigit(*p))889			return false;890		if (!has_hex)891			has_hex = !isdigit(*p);892		if (*(++p) == 0)893			break;894	}895 896	if (has_hex)897		return (p - suffix) > 2;898 899	return true;900}901 902/**903 * pmu_uncore_alias_match - does name match the PMU name?904 * @pmu_name: the json struct pmu_event name. This may lack a suffix (which905 *            matches) or be of the form "socket,pmuname" which will match906 *            "socketX_pmunameY".907 * @name: a real full PMU name as from sysfs.908 */909static bool pmu_uncore_alias_match(const char *pmu_name, const char *name)910{911	char *tmp = NULL, *tok, *str;912	bool res;913 914	if (strchr(pmu_name, ',') == NULL)915		return perf_pmu__match_ignoring_suffix(name, pmu_name);916 917	str = strdup(pmu_name);918	if (!str)919		return false;920 921	/*922	 * uncore alias may be from different PMU with common prefix923	 */924	tok = strtok_r(str, ",", &tmp);925	if (strncmp(pmu_name, tok, strlen(tok))) {926		res = false;927		goto out;928	}929 930	/*931	 * Match more complex aliases where the alias name is a comma-delimited932	 * list of tokens, orderly contained in the matching PMU name.933	 *934	 * Example: For alias "socket,pmuname" and PMU "socketX_pmunameY", we935	 *	    match "socket" in "socketX_pmunameY" and then "pmuname" in936	 *	    "pmunameY".937	 */938	while (1) {939		char *next_tok = strtok_r(NULL, ",", &tmp);940 941		name = strstr(name, tok);942		if (!name ||943		    (!next_tok && !perf_pmu__match_ignoring_suffix(name, tok))) {944			res = false;945			goto out;946		}947		if (!next_tok)948			break;949		tok = next_tok;950		name += strlen(tok);951	}952 953	res = true;954out:955	free(str);956	return res;957}958 959bool pmu_uncore_identifier_match(const char *compat, const char *id)960{961	regex_t re;962	regmatch_t pmatch[1];963	int match;964 965	if (regcomp(&re, compat, REG_EXTENDED) != 0) {966		/* Warn unable to generate match particular string. */967		pr_info("Invalid regular expression %s\n", compat);968		return false;969	}970 971	match = !regexec(&re, id, 1, pmatch, 0);972	if (match) {973		/* Ensure a full match. */974		match = pmatch[0].rm_so == 0 && (size_t)pmatch[0].rm_eo == strlen(id);975	}976	regfree(&re);977 978	return match;979}980 981static int pmu_add_cpu_aliases_map_callback(const struct pmu_event *pe,982					const struct pmu_events_table *table __maybe_unused,983					void *vdata)984{985	struct perf_pmu *pmu = vdata;986 987	perf_pmu__new_alias(pmu, pe->name, pe->desc, pe->event, /*val_fd=*/ NULL,988			    pe, EVENT_SRC_CPU_JSON);989	return 0;990}991 992/*993 * From the pmu_events_table, find the events that correspond to the given994 * PMU and add them to the list 'head'.995 */996void pmu_add_cpu_aliases_table(struct perf_pmu *pmu, const struct pmu_events_table *table)997{998	pmu_events_table__for_each_event(table, pmu, pmu_add_cpu_aliases_map_callback, pmu);999}1000 1001static void pmu_add_cpu_aliases(struct perf_pmu *pmu)1002{1003	if (!pmu->events_table)1004		return;1005 1006	if (pmu->cpu_aliases_added)1007		return;1008 1009	pmu_add_cpu_aliases_table(pmu, pmu->events_table);1010	pmu->cpu_aliases_added = true;1011}1012 1013static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe,1014				       const struct pmu_events_table *table __maybe_unused,1015				       void *vdata)1016{1017	struct perf_pmu *pmu = vdata;1018 1019	if (!pe->compat || !pe->pmu)1020		return 0;1021 1022	if (pmu_uncore_alias_match(pe->pmu, pmu->name) &&1023	    pmu_uncore_identifier_match(pe->compat, pmu->id)) {1024		perf_pmu__new_alias(pmu,1025				pe->name,1026				pe->desc,1027				pe->event,1028				/*val_fd=*/ NULL,1029				pe,1030				EVENT_SRC_SYS_JSON);1031	}1032 1033	return 0;1034}1035 1036void pmu_add_sys_aliases(struct perf_pmu *pmu)1037{1038	if (!pmu->id)1039		return;1040 1041	pmu_for_each_sys_event(pmu_add_sys_aliases_iter_fn, pmu);1042}1043 1044static char *pmu_find_alias_name(struct perf_pmu *pmu, int dirfd)1045{1046	FILE *file = perf_pmu__open_file_at(pmu, dirfd, "alias");1047	char *line = NULL;1048	size_t line_len = 0;1049	ssize_t ret;1050 1051	if (!file)1052		return NULL;1053 1054	ret = getline(&line, &line_len, file);1055	if (ret < 0) {1056		fclose(file);1057		return NULL;1058	}1059	/* Remove trailing newline. */1060	if (ret > 0 && line[ret - 1] == '\n')1061		line[--ret] = '\0';1062 1063	fclose(file);1064	return line;1065}1066 1067static int pmu_max_precise(int dirfd, struct perf_pmu *pmu)1068{1069	int max_precise = -1;1070 1071	perf_pmu__scan_file_at(pmu, dirfd, "caps/max_precise", "%d", &max_precise);1072	return max_precise;1073}1074 1075void __weak1076perf_pmu__arch_init(struct perf_pmu *pmu)1077{1078	if (pmu->is_core)1079		pmu->mem_events = perf_mem_events;1080}1081 1082struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char *name,1083				  bool eager_load)1084{1085	struct perf_pmu *pmu;1086	__u32 type;1087 1088	pmu = zalloc(sizeof(*pmu));1089	if (!pmu)1090		return NULL;1091 1092	pmu->name = strdup(name);1093	if (!pmu->name)1094		goto err;1095 1096	/*1097	 * Read type early to fail fast if a lookup name isn't a PMU. Ensure1098	 * that type value is successfully assigned (return 1).1099	 */1100	if (perf_pmu__scan_file_at(pmu, dirfd, "type", "%u", &type) != 1)1101		goto err;1102 1103	INIT_LIST_HEAD(&pmu->format);1104	INIT_LIST_HEAD(&pmu->aliases);1105	INIT_LIST_HEAD(&pmu->caps);1106 1107	/*1108	 * The pmu data we store & need consists of the pmu1109	 * type value and format definitions. Load both right1110	 * now.1111	 */1112	if (pmu_format(pmu, dirfd, name, eager_load))1113		goto err;1114 1115	pmu->is_core = is_pmu_core(name);1116	pmu->cpus = pmu_cpumask(dirfd, name, pmu->is_core);1117 1118	pmu->type = type;1119	pmu->is_uncore = pmu_is_uncore(dirfd, name);1120	if (pmu->is_uncore)1121		pmu->id = pmu_id(name);1122	pmu->max_precise = pmu_max_precise(dirfd, pmu);1123	pmu->alias_name = pmu_find_alias_name(pmu, dirfd);1124	pmu->events_table = perf_pmu__find_events_table(pmu);1125	/*1126	 * Load the sys json events/aliases when loading the PMU as each event1127	 * may have a different compat regular expression. We therefore can't1128	 * know the number of sys json events/aliases without computing the1129	 * regular expressions for them all.1130	 */1131	pmu_add_sys_aliases(pmu);1132	list_add_tail(&pmu->list, pmus);1133 1134	perf_pmu__arch_init(pmu);1135 1136	if (eager_load)1137		pmu_aliases_parse_eager(pmu, dirfd);1138 1139	return pmu;1140err:1141	zfree(&pmu->name);1142	free(pmu);1143	return NULL;1144}1145 1146/* Creates the PMU when sysfs scanning fails. */1147struct perf_pmu *perf_pmu__create_placeholder_core_pmu(struct list_head *core_pmus)1148{1149	struct perf_pmu *pmu = zalloc(sizeof(*pmu));1150 1151	if (!pmu)1152		return NULL;1153 1154	pmu->name = strdup("cpu");1155	if (!pmu->name) {1156		free(pmu);1157		return NULL;1158	}1159 1160	pmu->is_core = true;1161	pmu->type = PERF_TYPE_RAW;1162	pmu->cpus = cpu_map__online();1163 1164	INIT_LIST_HEAD(&pmu->format);1165	INIT_LIST_HEAD(&pmu->aliases);1166	INIT_LIST_HEAD(&pmu->caps);1167	list_add_tail(&pmu->list, core_pmus);1168	return pmu;1169}1170 1171static bool perf_pmu__is_fake(const struct perf_pmu *pmu)1172{1173	return pmu->type == PERF_PMU_TYPE_FAKE;1174}1175 1176void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu)1177{1178	struct perf_pmu_format *format;1179 1180	if (pmu->formats_checked)1181		return;1182 1183	pmu->formats_checked = true;1184 1185	/* fake pmu doesn't have format list */1186	if (perf_pmu__is_fake(pmu))1187		return;1188 1189	list_for_each_entry(format, &pmu->format, list) {1190		perf_pmu_format__load(pmu, format);1191		if (format->value >= PERF_PMU_FORMAT_VALUE_CONFIG_END) {1192			pr_warning("WARNING: '%s' format '%s' requires 'perf_event_attr::config%d'"1193				   "which is not supported by this version of perf!\n",1194				   pmu->name, format->name, format->value);1195			return;1196		}1197	}1198}1199 1200bool evsel__is_aux_event(const struct evsel *evsel)1201{1202	struct perf_pmu *pmu;1203 1204	if (evsel->needs_auxtrace_mmap)1205		return true;1206 1207	pmu = evsel__find_pmu(evsel);1208	return pmu && pmu->auxtrace;1209}1210 1211/*1212 * Set @config_name to @val as long as the user hasn't already set or cleared it1213 * by passing a config term on the command line.1214 *1215 * @val is the value to put into the bits specified by @config_name rather than1216 * the bit pattern. It is shifted into position by this function, so to set1217 * something to true, pass 1 for val rather than a pre shifted value.1218 */1219#define field_prep(_mask, _val) (((_val) << (ffsll(_mask) - 1)) & (_mask))1220void evsel__set_config_if_unset(struct perf_pmu *pmu, struct evsel *evsel,1221				const char *config_name, u64 val)1222{1223	u64 user_bits = 0, bits;1224	struct evsel_config_term *term = evsel__get_config_term(evsel, CFG_CHG);1225 1226	if (term)1227		user_bits = term->val.cfg_chg;1228 1229	bits = perf_pmu__format_bits(pmu, config_name);1230 1231	/* Do nothing if the user changed the value */1232	if (bits & user_bits)1233		return;1234 1235	/* Otherwise replace it */1236	evsel->core.attr.config &= ~bits;1237	evsel->core.attr.config |= field_prep(bits, val);1238}1239 1240static struct perf_pmu_format *1241pmu_find_format(const struct list_head *formats, const char *name)1242{1243	struct perf_pmu_format *format;1244 1245	list_for_each_entry(format, formats, list)1246		if (!strcmp(format->name, name))1247			return format;1248 1249	return NULL;1250}1251 1252__u64 perf_pmu__format_bits(struct perf_pmu *pmu, const char *name)1253{1254	struct perf_pmu_format *format = pmu_find_format(&pmu->format, name);1255	__u64 bits = 0;1256	int fbit;1257 1258	if (!format)1259		return 0;1260 1261	for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS)1262		bits |= 1ULL << fbit;1263 1264	return bits;1265}1266 1267int perf_pmu__format_type(struct perf_pmu *pmu, const char *name)1268{1269	struct perf_pmu_format *format = pmu_find_format(&pmu->format, name);1270 1271	if (!format)1272		return -1;1273 1274	perf_pmu_format__load(pmu, format);1275	return format->value;1276}1277 1278/*1279 * Sets value based on the format definition (format parameter)1280 * and unformatted value (value parameter).1281 */1282static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,1283			     bool zero)1284{1285	unsigned long fbit, vbit;1286 1287	for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {1288 1289		if (!test_bit(fbit, format))1290			continue;1291 1292		if (value & (1llu << vbit++))1293			*v |= (1llu << fbit);1294		else if (zero)1295			*v &= ~(1llu << fbit);1296	}1297}1298 1299static __u64 pmu_format_max_value(const unsigned long *format)1300{1301	int w;1302 1303	w = bitmap_weight(format, PERF_PMU_FORMAT_BITS);1304	if (!w)1305		return 0;1306	if (w < 64)1307		return (1ULL << w) - 1;1308	return -1;1309}1310 1311/*1312 * Term is a string term, and might be a param-term. Try to look up it's value1313 * in the remaining terms.1314 * - We have a term like "base-or-format-term=param-term",1315 * - We need to find the value supplied for "param-term" (with param-term named1316 *   in a config string) later on in the term list.1317 */1318static int pmu_resolve_param_term(struct parse_events_term *term,1319				  struct parse_events_terms *head_terms,1320				  __u64 *value)1321{1322	struct parse_events_term *t;1323 1324	list_for_each_entry(t, &head_terms->terms, list) {1325		if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM &&1326		    t->config && !strcmp(t->config, term->config)) {1327			t->used = true;1328			*value = t->val.num;1329			return 0;1330		}1331	}1332 1333	if (verbose > 0)1334		printf("Required parameter '%s' not specified\n", term->config);1335 1336	return -1;1337}1338 1339static char *pmu_formats_string(const struct list_head *formats)1340{1341	struct perf_pmu_format *format;1342	char *str = NULL;1343	struct strbuf buf = STRBUF_INIT;1344	unsigned int i = 0;1345 1346	if (!formats)1347		return NULL;1348 1349	/* sysfs exported terms */1350	list_for_each_entry(format, formats, list)1351		if (strbuf_addf(&buf, i++ ? ",%s" : "%s", format->name) < 0)1352			goto error;1353 1354	str = strbuf_detach(&buf, NULL);1355error:1356	strbuf_release(&buf);1357 1358	return str;1359}1360 1361/*1362 * Setup one of config[12] attr members based on the1363 * user input data - term parameter.1364 */1365static int pmu_config_term(const struct perf_pmu *pmu,1366			   struct perf_event_attr *attr,1367			   struct parse_events_term *term,1368			   struct parse_events_terms *head_terms,1369			   bool zero, struct parse_events_error *err)1370{1371	struct perf_pmu_format *format;1372	__u64 *vp;1373	__u64 val, max_val;1374 1375	/*1376	 * If this is a parameter we've already used for parameterized-eval,1377	 * skip it in normal eval.1378	 */1379	if (term->used)1380		return 0;1381 1382	/*1383	 * Hardcoded terms should be already in, so nothing1384	 * to be done for them.1385	 */1386	if (parse_events__is_hardcoded_term(term))1387		return 0;1388 1389	format = pmu_find_format(&pmu->format, term->config);1390	if (!format) {1391		char *pmu_term = pmu_formats_string(&pmu->format);1392		char *unknown_term;1393		char *help_msg;1394 1395		if (asprintf(&unknown_term,1396				"unknown term '%s' for pmu '%s'",1397				term->config, pmu->name) < 0)1398			unknown_term = NULL;1399		help_msg = parse_events_formats_error_string(pmu_term);1400		if (err) {1401			parse_events_error__handle(err, term->err_term,1402						   unknown_term,1403						   help_msg);1404		} else {1405			pr_debug("%s (%s)\n", unknown_term, help_msg);1406			free(unknown_term);1407		}1408		free(pmu_term);1409		return -EINVAL;1410	}1411	perf_pmu_format__load(pmu, format);1412	switch (format->value) {1413	case PERF_PMU_FORMAT_VALUE_CONFIG:1414		vp = &attr->config;1415		break;1416	case PERF_PMU_FORMAT_VALUE_CONFIG1:1417		vp = &attr->config1;1418		break;1419	case PERF_PMU_FORMAT_VALUE_CONFIG2:1420		vp = &attr->config2;1421		break;1422	case PERF_PMU_FORMAT_VALUE_CONFIG3:1423		vp = &attr->config3;1424		break;1425	default:1426		return -EINVAL;1427	}1428 1429	/*1430	 * Either directly use a numeric term, or try to translate string terms1431	 * using event parameters.1432	 */1433	if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {1434		if (term->no_value &&1435		    bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) {1436			if (err) {1437				parse_events_error__handle(err, term->err_val,1438					   strdup("no value assigned for term"),1439					   NULL);1440			}1441			return -EINVAL;1442		}1443 1444		val = term->val.num;1445	} else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {1446		if (strcmp(term->val.str, "?")) {1447			if (verbose > 0) {1448				pr_info("Invalid sysfs entry %s=%s\n",1449						term->config, term->val.str);1450			}1451			if (err) {1452				parse_events_error__handle(err, term->err_val,1453					strdup("expected numeric value"),1454					NULL);1455			}1456			return -EINVAL;1457		}1458 1459		if (pmu_resolve_param_term(term, head_terms, &val))1460			return -EINVAL;1461	} else1462		return -EINVAL;1463 1464	max_val = pmu_format_max_value(format->bits);1465	if (val > max_val) {1466		if (err) {1467			char *err_str;1468 1469			parse_events_error__handle(err, term->err_val,1470				asprintf(&err_str,1471				    "value too big for format (%s), maximum is %llu",1472				    format->name, (unsigned long long)max_val) < 01473				    ? strdup("value too big for format")1474				    : err_str,1475				    NULL);1476			return -EINVAL;1477		}1478		/*1479		 * Assume we don't care if !err, in which case the value will be1480		 * silently truncated.1481		 */1482	}1483 1484	pmu_format_value(format->bits, val, vp, zero);1485	return 0;1486}1487 1488int perf_pmu__config_terms(const struct perf_pmu *pmu,1489			   struct perf_event_attr *attr,1490			   struct parse_events_terms *terms,1491			   bool zero, struct parse_events_error *err)1492{1493	struct parse_events_term *term;1494 1495	list_for_each_entry(term, &terms->terms, list) {1496		if (pmu_config_term(pmu, attr, term, terms, zero, err))1497			return -EINVAL;1498	}1499 1500	return 0;1501}1502 1503/*1504 * Configures event's 'attr' parameter based on the:1505 * 1) users input - specified in terms parameter1506 * 2) pmu format definitions - specified by pmu parameter1507 */1508int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,1509		     struct parse_events_terms *head_terms,1510		     struct parse_events_error *err)1511{1512	bool zero = !!pmu->perf_event_attr_init_default;1513 1514	/* Fake PMU doesn't have proper terms so nothing to configure in attr. */1515	if (perf_pmu__is_fake(pmu))1516		return 0;1517 1518	return perf_pmu__config_terms(pmu, attr, head_terms, zero, err);1519}1520 1521static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,1522					     struct parse_events_term *term)1523{1524	struct perf_pmu_alias *alias;1525	const char *name;1526 1527	if (parse_events__is_hardcoded_term(term))1528		return NULL;1529 1530	if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {1531		if (!term->no_value)1532			return NULL;1533		if (pmu_find_format(&pmu->format, term->config))1534			return NULL;1535		name = term->config;1536 1537	} else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {1538		if (strcasecmp(term->config, "event"))1539			return NULL;1540		name = term->val.str;1541	} else {1542		return NULL;1543	}1544 1545	alias = perf_pmu__find_alias(pmu, name, /*load=*/ true);1546	if (alias || pmu->cpu_aliases_added)1547		return alias;1548 1549	/* Alias doesn't exist, try to get it from the json events. */1550	if (pmu->events_table &&1551	    pmu_events_table__find_event(pmu->events_table, pmu, name,1552				         pmu_add_cpu_aliases_map_callback,1553				         pmu) == 0) {1554		alias = perf_pmu__find_alias(pmu, name, /*load=*/ false);1555	}1556	return alias;1557}1558 1559 1560static int check_info_data(struct perf_pmu *pmu,1561			   struct perf_pmu_alias *alias,1562			   struct perf_pmu_info *info,1563			   struct parse_events_error *err,1564			   int column)1565{1566	read_alias_info(pmu, alias);1567	/*1568	 * Only one term in event definition can1569	 * define unit, scale and snapshot, fail1570	 * if there's more than one.1571	 */1572	if (info->unit && alias->unit[0]) {1573		parse_events_error__handle(err, column,1574					strdup("Attempt to set event's unit twice"),1575					NULL);1576		return -EINVAL;1577	}1578	if (info->scale && alias->scale) {1579		parse_events_error__handle(err, column,1580					strdup("Attempt to set event's scale twice"),1581					NULL);1582		return -EINVAL;1583	}1584	if (info->snapshot && alias->snapshot) {1585		parse_events_error__handle(err, column,1586					strdup("Attempt to set event snapshot twice"),1587					NULL);1588		return -EINVAL;1589	}1590 1591	if (alias->unit[0])1592		info->unit = alias->unit;1593 1594	if (alias->scale)1595		info->scale = alias->scale;1596 1597	if (alias->snapshot)1598		info->snapshot = alias->snapshot;1599 1600	return 0;1601}1602 1603/*1604 * Find alias in the terms list and replace it with the terms1605 * defined for the alias1606 */1607int perf_pmu__check_alias(struct perf_pmu *pmu, struct parse_events_terms *head_terms,1608			  struct perf_pmu_info *info, bool *rewrote_terms,1609			  struct parse_events_error *err)1610{1611	struct parse_events_term *term, *h;1612	struct perf_pmu_alias *alias;1613	int ret;1614 1615	*rewrote_terms = false;1616	info->per_pkg = false;1617 1618	/*1619	 * Mark unit and scale as not set1620	 * (different from default values, see below)1621	 */1622	info->unit     = NULL;1623	info->scale    = 0.0;1624	info->snapshot = false;1625 1626	/* Fake PMU doesn't rewrite terms. */1627	if (perf_pmu__is_fake(pmu))1628		goto out;1629 1630	list_for_each_entry_safe(term, h, &head_terms->terms, list) {1631		alias = pmu_find_alias(pmu, term);1632		if (!alias)1633			continue;1634		ret = pmu_alias_terms(alias, term->err_term, &term->list);1635		if (ret) {1636			parse_events_error__handle(err, term->err_term,1637						strdup("Failure to duplicate terms"),1638						NULL);1639			return ret;1640		}1641		*rewrote_terms = true;1642		ret = check_info_data(pmu, alias, info, err, term->err_term);1643		if (ret)1644			return ret;1645 1646		if (alias->per_pkg)1647			info->per_pkg = true;1648 1649		list_del_init(&term->list);1650		parse_events_term__delete(term);1651	}1652out:1653	/*1654	 * if no unit or scale found in aliases, then1655	 * set defaults as for evsel1656	 * unit cannot left to NULL1657	 */1658	if (info->unit == NULL)1659		info->unit   = "";1660 1661	if (info->scale == 0.0)1662		info->scale  = 1.0;1663 1664	return 0;1665}1666 1667struct find_event_args {1668	const char *event;1669	void *state;1670	pmu_event_callback cb;1671};1672 1673static int find_event_callback(void *state, struct pmu_event_info *info)1674{1675	struct find_event_args *args = state;1676 1677	if (!strcmp(args->event, info->name))1678		return args->cb(args->state, info);1679 1680	return 0;1681}1682 1683int perf_pmu__find_event(struct perf_pmu *pmu, const char *event, void *state, pmu_event_callback cb)1684{1685	struct find_event_args args = {1686		.event = event,1687		.state = state,1688		.cb = cb,1689	};1690 1691	/* Sub-optimal, but function is only used by tests. */1692	return perf_pmu__for_each_event(pmu, /*skip_duplicate_pmus=*/ false,1693					&args, find_event_callback);1694}1695 1696static void perf_pmu__del_formats(struct list_head *formats)1697{1698	struct perf_pmu_format *fmt, *tmp;1699 1700	list_for_each_entry_safe(fmt, tmp, formats, list) {1701		list_del(&fmt->list);1702		zfree(&fmt->name);1703		free(fmt);1704	}1705}1706 1707bool perf_pmu__has_format(const struct perf_pmu *pmu, const char *name)1708{1709	struct perf_pmu_format *format;1710 1711	list_for_each_entry(format, &pmu->format, list) {1712		if (!strcmp(format->name, name))1713			return true;1714	}1715	return false;1716}1717 1718int perf_pmu__for_each_format(struct perf_pmu *pmu, void *state, pmu_format_callback cb)1719{1720	static const char *const terms[] = {1721		"config=0..0xffffffffffffffff",1722		"config1=0..0xffffffffffffffff",1723		"config2=0..0xffffffffffffffff",1724		"config3=0..0xffffffffffffffff",1725		"name=string",1726		"period=number",1727		"freq=number",1728		"branch_type=(u|k|hv|any|...)",1729		"time",1730		"call-graph=(fp|dwarf|lbr)",1731		"stack-size=number",1732		"max-stack=number",1733		"nr=number",1734		"inherit",1735		"no-inherit",1736		"overwrite",1737		"no-overwrite",1738		"percore",1739		"aux-output",1740		"aux-sample-size=number",1741	};1742	struct perf_pmu_format *format;1743	int ret;1744 1745	/*1746	 * max-events and driver-config are missing above as are the internal1747	 * types user, metric-id, raw, legacy cache and hardware. Assert against1748	 * the enum parse_events__term_type so they are kept in sync.1749	 */1750	_Static_assert(ARRAY_SIZE(terms) == __PARSE_EVENTS__TERM_TYPE_NR - 6,1751		       "perf_pmu__for_each_format()'s terms must be kept in sync with enum parse_events__term_type");1752	list_for_each_entry(format, &pmu->format, list) {1753		perf_pmu_format__load(pmu, format);1754		ret = cb(state, format->name, (int)format->value, format->bits);1755		if (ret)1756			return ret;1757	}1758	if (!pmu->is_core)1759		return 0;1760 1761	for (size_t i = 0; i < ARRAY_SIZE(terms); i++) {1762		int config = PERF_PMU_FORMAT_VALUE_CONFIG;1763 1764		if (i < PERF_PMU_FORMAT_VALUE_CONFIG_END)1765			config = i;1766 1767		ret = cb(state, terms[i], config, /*bits=*/NULL);1768		if (ret)1769			return ret;1770	}1771	return 0;1772}1773 1774bool is_pmu_core(const char *name)1775{1776	return !strcmp(name, "cpu") || !strcmp(name, "cpum_cf") || is_sysfs_pmu_core(name);1777}1778 1779bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu)1780{1781	return pmu->is_core;1782}1783 1784bool perf_pmu__auto_merge_stats(const struct perf_pmu *pmu)1785{1786	return !pmu->is_core || perf_pmus__num_core_pmus() == 1;1787}1788 1789bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name)1790{1791	if (!name)1792		return false;1793	if (perf_pmu__find_alias(pmu, name, /*load=*/ true) != NULL)1794		return true;1795	if (pmu->cpu_aliases_added || !pmu->events_table)1796		return false;1797	return pmu_events_table__find_event(pmu->events_table, pmu, name, NULL, NULL) == 0;1798}1799 1800size_t perf_pmu__num_events(struct perf_pmu *pmu)1801{1802	size_t nr;1803 1804	pmu_aliases_parse(pmu);1805	nr = pmu->sysfs_aliases + pmu->sys_json_aliases;1806 1807	if (pmu->cpu_aliases_added)1808		 nr += pmu->cpu_json_aliases;1809	else if (pmu->events_table)1810		nr += pmu_events_table__num_events(pmu->events_table, pmu) - pmu->cpu_json_aliases;1811	else1812		assert(pmu->cpu_json_aliases == 0);1813 1814	return pmu->selectable ? nr + 1 : nr;1815}1816 1817static int sub_non_neg(int a, int b)1818{1819	if (b > a)1820		return 0;1821	return a - b;1822}1823 1824static char *format_alias(char *buf, int len, const struct perf_pmu *pmu,1825			  const struct perf_pmu_alias *alias, bool skip_duplicate_pmus)1826{1827	struct parse_events_term *term;1828	size_t pmu_name_len = pmu_deduped_name_len(pmu, pmu->name,1829						   skip_duplicate_pmus);1830	int used = snprintf(buf, len, "%.*s/%s", (int)pmu_name_len, pmu->name, alias->name);1831 1832	list_for_each_entry(term, &alias->terms.terms, list) {1833		if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)1834			used += snprintf(buf + used, sub_non_neg(len, used),1835					",%s=%s", term->config,1836					term->val.str);1837	}1838 1839	if (sub_non_neg(len, used) > 0) {1840		buf[used] = '/';1841		used++;1842	}1843	if (sub_non_neg(len, used) > 0) {1844		buf[used] = '\0';1845		used++;1846	} else1847		buf[len - 1] = '\0';1848 1849	return buf;1850}1851 1852int perf_pmu__for_each_event(struct perf_pmu *pmu, bool skip_duplicate_pmus,1853			     void *state, pmu_event_callback cb)1854{1855	char buf[1024];1856	struct perf_pmu_alias *event;1857	struct pmu_event_info info = {1858		.pmu = pmu,1859		.event_type_desc = "Kernel PMU event",1860	};1861	int ret = 0;1862	struct strbuf sb;1863 1864	strbuf_init(&sb, /*hint=*/ 0);1865	pmu_aliases_parse(pmu);1866	pmu_add_cpu_aliases(pmu);1867	list_for_each_entry(event, &pmu->aliases, list) {1868		size_t buf_used, pmu_name_len;1869 1870		info.pmu_name = event->pmu_name ?: pmu->name;1871		pmu_name_len = pmu_deduped_name_len(pmu, info.pmu_name,1872						    skip_duplicate_pmus);1873		info.alias = NULL;1874		if (event->desc) {1875			info.name = event->name;1876			buf_used = 0;1877		} else {1878			info.name = format_alias(buf, sizeof(buf), pmu, event,1879						 skip_duplicate_pmus);1880			if (pmu->is_core) {1881				info.alias = info.name;1882				info.name = event->name;1883			}1884			buf_used = strlen(buf) + 1;1885		}1886		info.scale_unit = NULL;1887		if (strlen(event->unit) || event->scale != 1.0) {1888			info.scale_unit = buf + buf_used;1889			buf_used += snprintf(buf + buf_used, sizeof(buf) - buf_used,1890					"%G%s", event->scale, event->unit) + 1;1891		}1892		info.desc = event->desc;1893		info.long_desc = event->long_desc;1894		info.encoding_desc = buf + buf_used;1895		parse_events_terms__to_strbuf(&event->terms, &sb);1896		buf_used += snprintf(buf + buf_used, sizeof(buf) - buf_used,1897				"%.*s/%s/", (int)pmu_name_len, info.pmu_name, sb.buf) + 1;1898		info.topic = event->topic;1899		info.str = sb.buf;1900		info.deprecated = event->deprecated;1901		ret = cb(state, &info);1902		if (ret)1903			goto out;1904		strbuf_setlen(&sb, /*len=*/ 0);1905	}1906	if (pmu->selectable) {1907		info.name = buf;1908		snprintf(buf, sizeof(buf), "%s//", pmu->name);1909		info.alias = NULL;1910		info.scale_unit = NULL;1911		info.desc = NULL;1912		info.long_desc = NULL;1913		info.encoding_desc = NULL;1914		info.topic = NULL;1915		info.pmu_name = pmu->name;1916		info.deprecated = false;1917		ret = cb(state, &info);1918	}1919out:1920	strbuf_release(&sb);1921	return ret;1922}1923 1924bool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name)1925{1926	return !strcmp(pmu->name, pmu_name) ||1927		(pmu->is_uncore && pmu_uncore_alias_match(pmu_name, pmu->name)) ||1928		/*1929		 * jevents and tests use default_core as a marker for any core1930		 * PMU as the PMU name varies across architectures.1931		 */1932	        (pmu->is_core && !strcmp(pmu_name, "default_core"));1933}1934 1935bool perf_pmu__is_software(const struct perf_pmu *pmu)1936{1937	const char *known_sw_pmus[] = {1938		"kprobe",1939		"msr",1940		"uprobe",1941	};1942 1943	if (pmu->is_core || pmu->is_uncore || pmu->auxtrace)1944		return false;1945	switch (pmu->type) {1946	case PERF_TYPE_HARDWARE:	return false;1947	case PERF_TYPE_SOFTWARE:	return true;1948	case PERF_TYPE_TRACEPOINT:	return true;1949	case PERF_TYPE_HW_CACHE:	return false;1950	case PERF_TYPE_RAW:		return false;1951	case PERF_TYPE_BREAKPOINT:	return true;1952	default: break;1953	}1954	for (size_t i = 0; i < ARRAY_SIZE(known_sw_pmus); i++) {1955		if (!strcmp(pmu->name, known_sw_pmus[i]))1956			return true;1957	}1958	return false;1959}1960 1961FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name)1962{1963	char path[PATH_MAX];1964 1965	if (!perf_pmu__pathname_scnprintf(path, sizeof(path), pmu->name, name) ||1966	    !file_available(path))1967		return NULL;1968 1969	return fopen(path, "r");1970}1971 1972FILE *perf_pmu__open_file_at(const struct perf_pmu *pmu, int dirfd, const char *name)1973{1974	int fd;1975 1976	fd = perf_pmu__pathname_fd(dirfd, pmu->name, name, O_RDONLY);1977	if (fd < 0)1978		return NULL;1979 1980	return fdopen(fd, "r");1981}1982 1983int perf_pmu__scan_file(const struct perf_pmu *pmu, const char *name, const char *fmt,1984			...)1985{1986	va_list args;1987	FILE *file;1988	int ret = EOF;1989 1990	va_start(args, fmt);1991	file = perf_pmu__open_file(pmu, name);1992	if (file) {1993		ret = vfscanf(file, fmt, args);1994		fclose(file);1995	}1996	va_end(args);1997	return ret;1998}1999 2000int perf_pmu__scan_file_at(const struct perf_pmu *pmu, int dirfd, const char *name,2001			   const char *fmt, ...)2002{2003	va_list args;2004	FILE *file;2005	int ret = EOF;2006 2007	va_start(args, fmt);2008	file = perf_pmu__open_file_at(pmu, dirfd, name);2009	if (file) {2010		ret = vfscanf(file, fmt, args);2011		fclose(file);2012	}2013	va_end(args);2014	return ret;2015}2016 2017bool perf_pmu__file_exists(const struct perf_pmu *pmu, const char *name)2018{2019	char path[PATH_MAX];2020 2021	if (!perf_pmu__pathname_scnprintf(path, sizeof(path), pmu->name, name))2022		return false;2023 2024	return file_available(path);2025}2026 2027static int perf_pmu__new_caps(struct list_head *list, char *name, char *value)2028{2029	struct perf_pmu_caps *caps = zalloc(sizeof(*caps));2030 2031	if (!caps)2032		return -ENOMEM;2033 2034	caps->name = strdup(name);2035	if (!caps->name)2036		goto free_caps;2037	caps->value = strndup(value, strlen(value) - 1);2038	if (!caps->value)2039		goto free_name;2040	list_add_tail(&caps->list, list);2041	return 0;2042 2043free_name:2044	zfree(&caps->name);2045free_caps:2046	free(caps);2047 2048	return -ENOMEM;2049}2050 2051static void perf_pmu__del_caps(struct perf_pmu *pmu)2052{2053	struct perf_pmu_caps *caps, *tmp;2054 2055	list_for_each_entry_safe(caps, tmp, &pmu->caps, list) {2056		list_del(&caps->list);2057		zfree(&caps->name);2058		zfree(&caps->value);2059		free(caps);2060	}2061}2062 2063/*2064 * Reading/parsing the given pmu capabilities, which should be located at:2065 * /sys/bus/event_source/devices/<dev>/caps as sysfs group attributes.2066 * Return the number of capabilities2067 */2068int perf_pmu__caps_parse(struct perf_pmu *pmu)2069{2070	struct stat st;2071	char caps_path[PATH_MAX];2072	DIR *caps_dir;2073	struct dirent *evt_ent;2074	int caps_fd;2075 2076	if (pmu->caps_initialized)2077		return pmu->nr_caps;2078 2079	pmu->nr_caps = 0;2080 2081	if (!perf_pmu__pathname_scnprintf(caps_path, sizeof(caps_path), pmu->name, "caps"))2082		return -1;2083 2084	if (stat(caps_path, &st) < 0) {2085		pmu->caps_initialized = true;2086		return 0;	/* no error if caps does not exist */2087	}2088 2089	caps_dir = opendir(caps_path);2090	if (!caps_dir)2091		return -EINVAL;2092 2093	caps_fd = dirfd(caps_dir);2094 2095	while ((evt_ent = readdir(caps_dir)) != NULL) {2096		char *name = evt_ent->d_name;2097		char value[128];2098		FILE *file;2099		int fd;2100 2101		if (!strcmp(name, ".") || !strcmp(name, ".."))2102			continue;2103 2104		fd = openat(caps_fd, name, O_RDONLY);2105		if (fd == -1)2106			continue;2107		file = fdopen(fd, "r");2108		if (!file) {2109			close(fd);2110			continue;2111		}2112 2113		if (!fgets(value, sizeof(value), file) ||2114		    (perf_pmu__new_caps(&pmu->caps, name, value) < 0)) {2115			fclose(file);2116			continue;2117		}2118 2119		pmu->nr_caps++;2120		fclose(file);2121	}2122 2123	closedir(caps_dir);2124 2125	pmu->caps_initialized = true;2126	return pmu->nr_caps;2127}2128 2129static void perf_pmu__compute_config_masks(struct perf_pmu *pmu)2130{2131	struct perf_pmu_format *format;2132 2133	if (pmu->config_masks_computed)2134		return;2135 2136	list_for_each_entry(format, &pmu->format, list)	{2137		unsigned int i;2138		__u64 *mask;2139 2140		if (format->value >= PERF_PMU_FORMAT_VALUE_CONFIG_END)2141			continue;2142 2143		pmu->config_masks_present = true;2144		mask = &pmu->config_masks[format->value];2145 2146		for_each_set_bit(i, format->bits, PERF_PMU_FORMAT_BITS)2147			*mask |= 1ULL << i;2148	}2149	pmu->config_masks_computed = true;2150}2151 2152void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,2153				   const char *name, int config_num,2154				   const char *config_name)2155{2156	__u64 bits;2157	char buf[100];2158 2159	perf_pmu__compute_config_masks(pmu);2160 2161	/*2162	 * Kernel doesn't export any valid format bits.2163	 */2164	if (!pmu->config_masks_present)2165		return;2166 2167	bits = config & ~pmu->config_masks[config_num];2168	if (bits == 0)2169		return;2170 2171	bitmap_scnprintf((unsigned long *)&bits, sizeof(bits) * 8, buf, sizeof(buf));2172 2173	pr_warning("WARNING: event '%s' not valid (bits %s of %s "2174		   "'%llx' not supported by kernel)!\n",2175		   name ?: "N/A", buf, config_name, config);2176}2177 2178bool perf_pmu__match(const struct perf_pmu *pmu, const char *tok)2179{2180	const char *name = pmu->name;2181	bool need_fnmatch = strisglob(tok);2182 2183	if (!strncmp(tok, "uncore_", 7))2184		tok += 7;2185	if (!strncmp(name, "uncore_", 7))2186		name += 7;2187 2188	if (perf_pmu__match_ignoring_suffix(name, tok) ||2189	    (need_fnmatch && !fnmatch(tok, name, 0)))2190		return true;2191 2192	name = pmu->alias_name;2193	if (!name)2194		return false;2195 2196	if (!strncmp(name, "uncore_", 7))2197		name += 7;2198 2199	return perf_pmu__match_ignoring_suffix(name, tok) ||2200		(need_fnmatch && !fnmatch(tok, name, 0));2201}2202 2203double __weak perf_pmu__cpu_slots_per_cycle(void)2204{2205	return NAN;2206}2207 2208int perf_pmu__event_source_devices_scnprintf(char *pathname, size_t size)2209{2210	const char *sysfs = sysfs__mountpoint();2211 2212	if (!sysfs)2213		return 0;2214	return scnprintf(pathname, size, "%s/bus/event_source/devices/", sysfs);2215}2216 2217int perf_pmu__event_source_devices_fd(void)2218{2219	char path[PATH_MAX];2220	const char *sysfs = sysfs__mountpoint();2221 2222	if (!sysfs)2223		return -1;2224 2225	scnprintf(path, sizeof(path), "%s/bus/event_source/devices/", sysfs);2226	return open(path, O_DIRECTORY);2227}2228 2229/*2230 * Fill 'buf' with the path to a file or folder in 'pmu_name' in2231 * sysfs. For example if pmu_name = "cs_etm" and 'filename' = "format"2232 * then pathname will be filled with2233 * "/sys/bus/event_source/devices/cs_etm/format"2234 *2235 * Return 0 if the sysfs mountpoint couldn't be found, if no characters were2236 * written or if the buffer size is exceeded.2237 */2238int perf_pmu__pathname_scnprintf(char *buf, size_t size,2239				 const char *pmu_name, const char *filename)2240{2241	size_t len;2242 2243	len = perf_pmu__event_source_devices_scnprintf(buf, size);2244	if (!len || (len + strlen(pmu_name) + strlen(filename) + 1)  >= size)2245		return 0;2246 2247	return scnprintf(buf + len, size - len, "%s/%s", pmu_name, filename);2248}2249 2250int perf_pmu__pathname_fd(int dirfd, const char *pmu_name, const char *filename, int flags)2251{2252	char path[PATH_MAX];2253 2254	scnprintf(path, sizeof(path), "%s/%s", pmu_name, filename);2255	return openat(dirfd, path, flags);2256}2257 2258void perf_pmu__delete(struct perf_pmu *pmu)2259{2260	perf_pmu__del_formats(&pmu->format);2261	perf_pmu__del_aliases(pmu);2262	perf_pmu__del_caps(pmu);2263 2264	perf_cpu_map__put(pmu->cpus);2265 2266	zfree(&pmu->name);2267	zfree(&pmu->alias_name);2268	zfree(&pmu->id);2269	free(pmu);2270}2271 2272const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config)2273{2274	struct perf_pmu_alias *event;2275 2276	if (!pmu)2277		return NULL;2278 2279	pmu_aliases_parse(pmu);2280	pmu_add_cpu_aliases(pmu);2281	list_for_each_entry(event, &pmu->aliases, list) {2282		struct perf_event_attr attr = {.config = 0,};2283		int ret = perf_pmu__config(pmu, &attr, &event->terms, NULL);2284 2285		if (ret == 0 && config == attr.config)2286			return event->name;2287	}2288	return NULL;2289}2290