xref: /linux/tools/perf/util/pmus.c (revision 473f6c8f437b049f8ec015d57cd59bb983b1d85c)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/list.h>
3 #include <linux/list_sort.h>
4 #include <linux/string.h>
5 #include <linux/zalloc.h>
6 #include <api/io_dir.h>
7 #include <subcmd/pager.h>
8 #include <sys/types.h>
9 #include <ctype.h>
10 #include <pthread.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include "cpumap.h"
14 #include "debug.h"
15 #include "drm_pmu.h"
16 #include "evsel.h"
17 #include "pmus.h"
18 #include "pmu.h"
19 #include "hwmon_pmu.h"
20 #include "tool_pmu.h"
21 #include "print-events.h"
22 #include "strbuf.h"
23 #include "string2.h"
24 
25 /*
26  * core_pmus:  A PMU belongs to core_pmus if it's name is "cpu" or it's sysfs
27  *             directory contains "cpus" file. All PMUs belonging to core_pmus
28  *             must have pmu->is_core=1. If there are more than one PMU in
29  *             this list, perf interprets it as a heterogeneous platform.
30  *             (FWIW, certain ARM platforms having heterogeneous cores uses
31  *             homogeneous PMU, and thus they are treated as homogeneous
32  *             platform by perf because core_pmus will have only one entry)
33  * other_pmus: All other PMUs which are not part of core_pmus list. It doesn't
34  *             matter whether PMU is present per SMT-thread or outside of the
35  *             core in the hw. For e.g., an instance of AMD ibs_fetch// and
36  *             ibs_op// PMUs is present in each hw SMT thread, however they
37  *             are captured under other_pmus. PMUs belonging to other_pmus
38  *             must have pmu->is_core=0 but pmu->is_uncore could be 0 or 1.
39  */
40 static LIST_HEAD(core_pmus);
41 static LIST_HEAD(other_pmus);
42 enum perf_tool_pmu_type {
43 	PERF_TOOL_PMU_TYPE_PE_CORE,
44 	PERF_TOOL_PMU_TYPE_PE_OTHER,
45 	PERF_TOOL_PMU_TYPE_TOOL,
46 	PERF_TOOL_PMU_TYPE_HWMON,
47 	PERF_TOOL_PMU_TYPE_DRM,
48 
49 #define PERF_TOOL_PMU_TYPE_PE_CORE_MASK (1 << PERF_TOOL_PMU_TYPE_PE_CORE)
50 #define PERF_TOOL_PMU_TYPE_PE_OTHER_MASK (1 << PERF_TOOL_PMU_TYPE_PE_OTHER)
51 #define PERF_TOOL_PMU_TYPE_TOOL_MASK (1 << PERF_TOOL_PMU_TYPE_TOOL)
52 #define PERF_TOOL_PMU_TYPE_HWMON_MASK (1 << PERF_TOOL_PMU_TYPE_HWMON)
53 #define PERF_TOOL_PMU_TYPE_DRM_MASK (1 << PERF_TOOL_PMU_TYPE_DRM)
54 
55 #define PERF_TOOL_PMU_TYPE_ALL_MASK (PERF_TOOL_PMU_TYPE_PE_CORE_MASK |	\
56 					PERF_TOOL_PMU_TYPE_PE_OTHER_MASK | \
57 					PERF_TOOL_PMU_TYPE_TOOL_MASK |	\
58 					PERF_TOOL_PMU_TYPE_HWMON_MASK | \
59 					PERF_TOOL_PMU_TYPE_DRM_MASK)
60 };
61 static unsigned int read_pmu_types;
62 
63 static void pmu_read_sysfs(unsigned int to_read_pmus);
64 
65 size_t pmu_name_len_no_suffix(const char *str)
66 {
67 	int orig_len, len;
68 	bool has_hex_digits = false;
69 
70 	orig_len = len = strlen(str);
71 
72 	/* Count trailing digits. */
73 	while (len > 0 && isxdigit(str[len - 1])) {
74 		if (!isdigit(str[len - 1]))
75 			has_hex_digits = true;
76 		len--;
77 	}
78 
79 	if (len > 0 && len != orig_len && str[len - 1] == '_') {
80 		/*
81 		 * There is a '_{num}' suffix. For decimal suffixes any length
82 		 * will do, for hexadecimal ensure more than 2 hex digits so
83 		 * that S390's cpum_cf PMU doesn't match.
84 		 */
85 		if (!has_hex_digits || (orig_len - len) > 2)
86 			return len - 1;
87 	}
88 	/* Use the full length. */
89 	return orig_len;
90 }
91 
92 int pmu_name_cmp(const char *lhs_pmu_name, const char *rhs_pmu_name)
93 {
94 	unsigned long long lhs_num = 0, rhs_num = 0;
95 	size_t lhs_pmu_name_len = pmu_name_len_no_suffix(lhs_pmu_name);
96 	size_t rhs_pmu_name_len = pmu_name_len_no_suffix(rhs_pmu_name);
97 	int ret = strncmp(lhs_pmu_name, rhs_pmu_name,
98 			lhs_pmu_name_len < rhs_pmu_name_len ? lhs_pmu_name_len : rhs_pmu_name_len);
99 
100 	if (lhs_pmu_name_len != rhs_pmu_name_len || ret != 0 || lhs_pmu_name_len == 0)
101 		return ret;
102 
103 	if (lhs_pmu_name_len + 1 < strlen(lhs_pmu_name))
104 		lhs_num = strtoull(&lhs_pmu_name[lhs_pmu_name_len + 1], NULL, 16);
105 	if (rhs_pmu_name_len + 1 < strlen(rhs_pmu_name))
106 		rhs_num = strtoull(&rhs_pmu_name[rhs_pmu_name_len + 1], NULL, 16);
107 
108 	return lhs_num < rhs_num ? -1 : (lhs_num > rhs_num ? 1 : 0);
109 }
110 
111 void perf_pmus__destroy(void)
112 {
113 	struct perf_pmu *pmu, *tmp;
114 
115 	list_for_each_entry_safe(pmu, tmp, &core_pmus, list) {
116 		list_del(&pmu->list);
117 
118 		perf_pmu__delete(pmu);
119 	}
120 	list_for_each_entry_safe(pmu, tmp, &other_pmus, list) {
121 		list_del(&pmu->list);
122 
123 		perf_pmu__delete(pmu);
124 	}
125 	read_pmu_types = 0;
126 }
127 
128 static struct perf_pmu *pmu_find(const char *name)
129 {
130 	struct perf_pmu *pmu;
131 
132 	list_for_each_entry(pmu, &core_pmus, list) {
133 		if (!strcmp(pmu->name, name) ||
134 		    (pmu->alias_name && !strcmp(pmu->alias_name, name)))
135 			return pmu;
136 	}
137 	list_for_each_entry(pmu, &other_pmus, list) {
138 		if (!strcmp(pmu->name, name) ||
139 		    (pmu->alias_name && !strcmp(pmu->alias_name, name)))
140 			return pmu;
141 	}
142 
143 	return NULL;
144 }
145 
146 struct perf_pmu *perf_pmus__find(const char *name)
147 {
148 	struct perf_pmu *pmu;
149 	int dirfd;
150 	bool core_pmu;
151 	unsigned int to_read_pmus = 0;
152 
153 	if (!strcmp(name, "default_core"))
154 		return perf_pmus__find_core_pmu();
155 	/*
156 	 * Once PMU is loaded it stays in the list,
157 	 * so we keep us from multiple reading/parsing
158 	 * the pmu format definitions.
159 	 */
160 	pmu = pmu_find(name);
161 	if (pmu)
162 		return pmu;
163 
164 	if (read_pmu_types == PERF_TOOL_PMU_TYPE_ALL_MASK)
165 		return NULL;
166 
167 	core_pmu = is_pmu_core(name);
168 	if (core_pmu && (read_pmu_types & PERF_TOOL_PMU_TYPE_PE_CORE_MASK))
169 		return NULL;
170 
171 	dirfd = perf_pmu__event_source_devices_fd();
172 	pmu = perf_pmu__lookup(core_pmu ? &core_pmus : &other_pmus, dirfd, name,
173 			       /*eager_load=*/false);
174 	close(dirfd);
175 
176 	if (pmu)
177 		return pmu;
178 
179 	/* Looking up an individual perf event PMU failed, check if a tool PMU should be read. */
180 	if (!strncmp(name, "hwmon_", 6))
181 		to_read_pmus |= PERF_TOOL_PMU_TYPE_HWMON_MASK;
182 	else if (!strncmp(name, "drm_", 4))
183 		to_read_pmus |= PERF_TOOL_PMU_TYPE_DRM_MASK;
184 	else if (!strcmp(name, "tool"))
185 		to_read_pmus |= PERF_TOOL_PMU_TYPE_TOOL_MASK;
186 
187 	if (to_read_pmus) {
188 		pmu_read_sysfs(to_read_pmus);
189 		pmu = pmu_find(name);
190 		if (pmu)
191 			return pmu;
192 	}
193 	/* Read all necessary PMUs from sysfs and see if the PMU is found. */
194 	to_read_pmus = PERF_TOOL_PMU_TYPE_PE_CORE_MASK;
195 	if (!core_pmu)
196 		to_read_pmus |= PERF_TOOL_PMU_TYPE_PE_OTHER_MASK;
197 	pmu_read_sysfs(to_read_pmus);
198 	return pmu_find(name);
199 }
200 
201 static struct perf_pmu *perf_pmu__find2(int dirfd, const char *name)
202 {
203 	struct perf_pmu *pmu;
204 	bool core_pmu;
205 
206 	/*
207 	 * Once PMU is loaded it stays in the list,
208 	 * so we keep us from multiple reading/parsing
209 	 * the pmu format definitions.
210 	 */
211 	pmu = pmu_find(name);
212 	if (pmu)
213 		return pmu;
214 
215 	if (read_pmu_types == PERF_TOOL_PMU_TYPE_ALL_MASK)
216 		return NULL;
217 
218 	core_pmu = is_pmu_core(name);
219 	if (core_pmu && (read_pmu_types & PERF_TOOL_PMU_TYPE_PE_CORE_MASK))
220 		return NULL;
221 
222 	return perf_pmu__lookup(core_pmu ? &core_pmus : &other_pmus, dirfd, name,
223 				/*eager_load=*/false);
224 }
225 
226 static int pmus_cmp(void *priv __maybe_unused,
227 		    const struct list_head *lhs, const struct list_head *rhs)
228 {
229 	struct perf_pmu *lhs_pmu = container_of(lhs, struct perf_pmu, list);
230 	struct perf_pmu *rhs_pmu = container_of(rhs, struct perf_pmu, list);
231 
232 	return pmu_name_cmp(lhs_pmu->name ?: "", rhs_pmu->name ?: "");
233 }
234 
235 /* Add all pmus in sysfs to pmu list: */
236 static void pmu_read_sysfs(unsigned int to_read_types)
237 {
238 	struct perf_pmu *tool_pmu;
239 
240 	if ((read_pmu_types & to_read_types) == to_read_types) {
241 		/* All requested PMU types have been read. */
242 		return;
243 	}
244 
245 	if (to_read_types & (PERF_TOOL_PMU_TYPE_PE_CORE_MASK | PERF_TOOL_PMU_TYPE_PE_OTHER_MASK)) {
246 		int fd = perf_pmu__event_source_devices_fd();
247 		struct io_dir dir;
248 		struct io_dirent64 *dent;
249 		bool core_only = (to_read_types & PERF_TOOL_PMU_TYPE_PE_OTHER_MASK) == 0;
250 
251 		if (fd < 0)
252 			goto skip_pe_pmus;
253 
254 		io_dir__init(&dir, fd);
255 
256 		while ((dent = io_dir__readdir(&dir)) != NULL) {
257 			if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
258 				continue;
259 			if (core_only && !is_pmu_core(dent->d_name))
260 				continue;
261 			/* add to static LIST_HEAD(core_pmus) or LIST_HEAD(other_pmus): */
262 			perf_pmu__find2(fd, dent->d_name);
263 		}
264 
265 		close(fd);
266 	}
267 skip_pe_pmus:
268 	if ((to_read_types & PERF_TOOL_PMU_TYPE_PE_CORE_MASK) && list_empty(&core_pmus)) {
269 		if (!perf_pmu__create_placeholder_core_pmu(&core_pmus))
270 			pr_err("Failure to set up any core PMUs\n");
271 	}
272 	list_sort(NULL, &core_pmus, pmus_cmp);
273 
274 	if ((to_read_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) != 0 &&
275 	    (read_pmu_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) == 0) {
276 		tool_pmu = tool_pmu__new();
277 		if (tool_pmu)
278 			list_add_tail(&tool_pmu->list, &other_pmus);
279 	}
280 	if ((to_read_types & PERF_TOOL_PMU_TYPE_HWMON_MASK) != 0 &&
281 	    (read_pmu_types & PERF_TOOL_PMU_TYPE_HWMON_MASK) == 0)
282 		perf_pmus__read_hwmon_pmus(&other_pmus);
283 
284 	if ((to_read_types & PERF_TOOL_PMU_TYPE_DRM_MASK) != 0 &&
285 	    (read_pmu_types & PERF_TOOL_PMU_TYPE_DRM_MASK) == 0)
286 		perf_pmus__read_drm_pmus(&other_pmus);
287 
288 	list_sort(NULL, &other_pmus, pmus_cmp);
289 
290 	read_pmu_types |= to_read_types;
291 }
292 
293 static struct perf_pmu *__perf_pmus__find_by_type(unsigned int type)
294 {
295 	struct perf_pmu *pmu;
296 
297 	list_for_each_entry(pmu, &core_pmus, list) {
298 		if (pmu->type == type)
299 			return pmu;
300 	}
301 
302 	list_for_each_entry(pmu, &other_pmus, list) {
303 		if (pmu->type == type)
304 			return pmu;
305 	}
306 	return NULL;
307 }
308 
309 struct perf_pmu *perf_pmus__find_by_type(unsigned int type)
310 {
311 	unsigned int to_read_pmus;
312 	struct perf_pmu *pmu = __perf_pmus__find_by_type(type);
313 
314 	if (pmu || (read_pmu_types == PERF_TOOL_PMU_TYPE_ALL_MASK))
315 		return pmu;
316 
317 	if (type >= PERF_PMU_TYPE_PE_START && type <= PERF_PMU_TYPE_PE_END) {
318 		to_read_pmus = PERF_TOOL_PMU_TYPE_PE_CORE_MASK |
319 			PERF_TOOL_PMU_TYPE_PE_OTHER_MASK;
320 	} else if (type >= PERF_PMU_TYPE_DRM_START && type <= PERF_PMU_TYPE_DRM_END) {
321 		to_read_pmus = PERF_TOOL_PMU_TYPE_DRM_MASK;
322 	} else if (type >= PERF_PMU_TYPE_HWMON_START && type <= PERF_PMU_TYPE_HWMON_END) {
323 		to_read_pmus = PERF_TOOL_PMU_TYPE_HWMON_MASK;
324 	} else {
325 		to_read_pmus = PERF_TOOL_PMU_TYPE_TOOL_MASK;
326 	}
327 	pmu_read_sysfs(to_read_pmus);
328 	pmu = __perf_pmus__find_by_type(type);
329 	return pmu;
330 }
331 
332 /*
333  * pmu iterator: If pmu is NULL, we start at the begin, otherwise return the
334  * next pmu. Returns NULL on end.
335  */
336 struct perf_pmu *perf_pmus__scan(struct perf_pmu *pmu)
337 {
338 	bool use_core_pmus = !pmu || pmu->is_core;
339 
340 	if (!pmu) {
341 		pmu_read_sysfs(PERF_TOOL_PMU_TYPE_ALL_MASK);
342 		pmu = list_prepare_entry(pmu, &core_pmus, list);
343 	}
344 	if (use_core_pmus) {
345 		list_for_each_entry_continue(pmu, &core_pmus, list)
346 			return pmu;
347 
348 		pmu = NULL;
349 		pmu = list_prepare_entry(pmu, &other_pmus, list);
350 	}
351 	list_for_each_entry_continue(pmu, &other_pmus, list)
352 		return pmu;
353 	return NULL;
354 }
355 
356 struct perf_pmu *perf_pmus__scan_core(struct perf_pmu *pmu)
357 {
358 	if (!pmu) {
359 		pmu_read_sysfs(PERF_TOOL_PMU_TYPE_PE_CORE_MASK);
360 		return list_first_entry_or_null(&core_pmus, typeof(*pmu), list);
361 	}
362 	list_for_each_entry_continue(pmu, &core_pmus, list)
363 		return pmu;
364 
365 	return NULL;
366 }
367 
368 struct perf_pmu *perf_pmus__scan_for_event(struct perf_pmu *pmu, const char *event)
369 {
370 	bool use_core_pmus = !pmu || pmu->is_core;
371 
372 	if (!pmu) {
373 		/* Hwmon filename values that aren't used. */
374 		enum hwmon_type type;
375 		int number;
376 		/*
377 		 * Core PMUs, other sysfs PMUs and tool PMU can take all event
378 		 * types or aren't wother optimizing for.
379 		 */
380 		unsigned int to_read_pmus =  PERF_TOOL_PMU_TYPE_PE_CORE_MASK |
381 			PERF_TOOL_PMU_TYPE_PE_OTHER_MASK |
382 			PERF_TOOL_PMU_TYPE_TOOL_MASK;
383 
384 		/* Could the event be a hwmon event? */
385 		if (parse_hwmon_filename(event, &type, &number, /*item=*/NULL, /*alarm=*/NULL))
386 			to_read_pmus |= PERF_TOOL_PMU_TYPE_HWMON_MASK;
387 
388 		/* Could the event be a DRM event? */
389 		if (strlen(event) > 4 && strncmp("drm-", event, 4) == 0)
390 			to_read_pmus |= PERF_TOOL_PMU_TYPE_DRM_MASK;
391 
392 		pmu_read_sysfs(to_read_pmus);
393 		pmu = list_prepare_entry(pmu, &core_pmus, list);
394 	}
395 	if (use_core_pmus) {
396 		list_for_each_entry_continue(pmu, &core_pmus, list)
397 			return pmu;
398 
399 		pmu = NULL;
400 		pmu = list_prepare_entry(pmu, &other_pmus, list);
401 	}
402 	list_for_each_entry_continue(pmu, &other_pmus, list)
403 		return pmu;
404 	return NULL;
405 }
406 
407 struct perf_pmu *perf_pmus__scan_matching_wildcard(struct perf_pmu *pmu, const char *wildcard)
408 {
409 	bool use_core_pmus = !pmu || pmu->is_core;
410 
411 	if (!pmu) {
412 		/*
413 		 * Core PMUs, other sysfs PMUs and tool PMU can have any name or
414 		 * aren't worth optimizing for.
415 		 */
416 		unsigned int to_read_pmus =  PERF_TOOL_PMU_TYPE_PE_CORE_MASK |
417 			PERF_TOOL_PMU_TYPE_PE_OTHER_MASK |
418 			PERF_TOOL_PMU_TYPE_TOOL_MASK;
419 
420 		/*
421 		 * Hwmon PMUs have an alias from a sysfs name like hwmon0,
422 		 * hwmon1, etc. or have a name of hwmon_<name>. They therefore
423 		 * can only have a wildcard match if the wildcard begins with
424 		 * "hwmon". Similarly drm PMUs must start "drm_", avoid reading
425 		 * such events unless the PMU could match.
426 		 */
427 		if (strisglob(wildcard)) {
428 			to_read_pmus |= PERF_TOOL_PMU_TYPE_HWMON_MASK |
429 				PERF_TOOL_PMU_TYPE_DRM_MASK;
430 		} else if (strlen(wildcard) >= 4 && strncmp("drm_", wildcard, 4) == 0) {
431 			to_read_pmus |= PERF_TOOL_PMU_TYPE_DRM_MASK;
432 		} else if (strlen(wildcard) >= 5 && strncmp("hwmon", wildcard, 5) == 0) {
433 			to_read_pmus |= PERF_TOOL_PMU_TYPE_HWMON_MASK;
434 		}
435 
436 		pmu_read_sysfs(to_read_pmus);
437 		pmu = list_prepare_entry(pmu, &core_pmus, list);
438 	}
439 	if (use_core_pmus) {
440 		list_for_each_entry_continue(pmu, &core_pmus, list) {
441 			if (perf_pmu__wildcard_match(pmu, wildcard))
442 				return pmu;
443 		}
444 		pmu = NULL;
445 		pmu = list_prepare_entry(pmu, &other_pmus, list);
446 	}
447 	list_for_each_entry_continue(pmu, &other_pmus, list) {
448 		if (perf_pmu__wildcard_match(pmu, wildcard))
449 			return pmu;
450 	}
451 	return NULL;
452 }
453 
454 static struct perf_pmu *perf_pmus__scan_skip_duplicates(struct perf_pmu *pmu)
455 {
456 	bool use_core_pmus = !pmu || pmu->is_core;
457 	int last_pmu_name_len = 0;
458 	const char *last_pmu_name = (pmu && pmu->name) ? pmu->name : "";
459 
460 	if (!pmu) {
461 		pmu_read_sysfs(PERF_TOOL_PMU_TYPE_ALL_MASK);
462 		pmu = list_prepare_entry(pmu, &core_pmus, list);
463 	} else
464 		last_pmu_name_len = pmu_name_len_no_suffix(pmu->name ?: "");
465 
466 	if (use_core_pmus) {
467 		list_for_each_entry_continue(pmu, &core_pmus, list) {
468 			int pmu_name_len = pmu_name_len_no_suffix(pmu->name ?: "");
469 
470 			if (last_pmu_name_len == pmu_name_len &&
471 			    !strncmp(last_pmu_name, pmu->name ?: "", pmu_name_len))
472 				continue;
473 
474 			return pmu;
475 		}
476 		pmu = NULL;
477 		pmu = list_prepare_entry(pmu, &other_pmus, list);
478 	}
479 	list_for_each_entry_continue(pmu, &other_pmus, list) {
480 		int pmu_name_len = pmu_name_len_no_suffix(pmu->name ?: "");
481 
482 		if (last_pmu_name_len == pmu_name_len &&
483 		    !strncmp(last_pmu_name, pmu->name ?: "", pmu_name_len))
484 			continue;
485 
486 		return pmu;
487 	}
488 	return NULL;
489 }
490 
491 struct perf_pmu *perf_pmus__scan_for_uncore_id(struct perf_pmu *pmu, const char *compat)
492 {
493 	if (!pmu) {
494 		/* Only uncore PMUs can have identifiers. */
495 		unsigned int to_read_pmus = PERF_TOOL_PMU_TYPE_PE_OTHER_MASK;
496 
497 		pmu_read_sysfs(to_read_pmus);
498 		pmu = list_prepare_entry(pmu, &other_pmus, list);
499 	}
500 	list_for_each_entry_continue(pmu, &other_pmus, list) {
501 		if (pmu->id && pmu_uncore_identifier_match(compat, pmu->id))
502 			return pmu;
503 	}
504 	return NULL;
505 }
506 
507 const struct perf_pmu *perf_pmus__pmu_for_pmu_filter(const char *str)
508 {
509 	struct perf_pmu *pmu = NULL;
510 
511 	while ((pmu = perf_pmus__scan(pmu)) != NULL) {
512 		if (!strcmp(pmu->name, str))
513 			return pmu;
514 		/* Ignore "uncore_" prefix. */
515 		if (!strncmp(pmu->name, "uncore_", 7)) {
516 			if (!strcmp(pmu->name + 7, str))
517 				return pmu;
518 		}
519 		/* Ignore "cpu_" prefix on Intel hybrid PMUs. */
520 		if (!strncmp(pmu->name, "cpu_", 4)) {
521 			if (!strcmp(pmu->name + 4, str))
522 				return pmu;
523 		}
524 	}
525 	return NULL;
526 }
527 
528 /** Struct for ordering events as output in perf list. */
529 struct sevent {
530 	/** PMU for event. */
531 	const struct perf_pmu *pmu;
532 	const char *name;
533 	const char* alias;
534 	const char *scale_unit;
535 	const char *desc;
536 	const char *long_desc;
537 	const char *encoding_desc;
538 	const char *topic;
539 	const char *pmu_name;
540 	const char *event_type_desc;
541 	bool deprecated;
542 };
543 
544 static int cmp_sevent(const void *a, const void *b)
545 {
546 	const struct sevent *as = a;
547 	const struct sevent *bs = b;
548 	bool a_iscpu, b_iscpu;
549 	int ret;
550 
551 	/* Put extra events last. */
552 	if (!!as->desc != !!bs->desc)
553 		return !!as->desc - !!bs->desc;
554 
555 	/* Order by topics. */
556 	ret = strcmp(as->topic ?: "", bs->topic ?: "");
557 	if (ret)
558 		return ret;
559 
560 	/* Order CPU core events to be first */
561 	a_iscpu = as->pmu ? as->pmu->is_core : true;
562 	b_iscpu = bs->pmu ? bs->pmu->is_core : true;
563 	if (a_iscpu != b_iscpu)
564 		return a_iscpu ? -1 : 1;
565 
566 	/* Order by PMU name. */
567 	if (as->pmu != bs->pmu) {
568 		ret = strcmp(as->pmu_name ?: "", bs->pmu_name ?: "");
569 		if (ret)
570 			return ret;
571 	}
572 
573 	/* Order by event name. */
574 	return strcmp(as->name, bs->name);
575 }
576 
577 static bool pmu_alias_is_duplicate(struct sevent *a, struct sevent *b)
578 {
579 	/* Different names -> never duplicates */
580 	if (strcmp(a->name ?: "//", b->name ?: "//"))
581 		return false;
582 
583 	/* Don't remove duplicates for different PMUs */
584 	return strcmp(a->pmu_name, b->pmu_name) == 0;
585 }
586 
587 struct events_callback_state {
588 	struct sevent *aliases;
589 	size_t aliases_len;
590 	size_t index;
591 };
592 
593 static int perf_pmus__print_pmu_events__callback(void *vstate,
594 						struct pmu_event_info *info)
595 {
596 	struct events_callback_state *state = vstate;
597 	struct sevent *s;
598 
599 	if (state->index >= state->aliases_len) {
600 		pr_err("Unexpected event %s/%s/\n", info->pmu->name, info->name);
601 		return 1;
602 	}
603 	assert(info->pmu != NULL || info->name != NULL);
604 	s = &state->aliases[state->index];
605 	s->pmu = info->pmu;
606 #define COPY_STR(str) s->str = info->str ? strdup(info->str) : NULL
607 	COPY_STR(name);
608 	COPY_STR(alias);
609 	COPY_STR(scale_unit);
610 	COPY_STR(desc);
611 	COPY_STR(long_desc);
612 	COPY_STR(encoding_desc);
613 	COPY_STR(topic);
614 	COPY_STR(pmu_name);
615 	COPY_STR(event_type_desc);
616 #undef COPY_STR
617 	s->deprecated = info->deprecated;
618 	state->index++;
619 	return 0;
620 }
621 
622 void perf_pmus__print_pmu_events(const struct print_callbacks *print_cb, void *print_state)
623 {
624 	struct perf_pmu *pmu;
625 	int printed = 0;
626 	int len;
627 	struct sevent *aliases;
628 	struct events_callback_state state;
629 	bool skip_duplicate_pmus = print_cb->skip_duplicate_pmus(print_state);
630 	struct perf_pmu *(*scan_fn)(struct perf_pmu *);
631 
632 	if (skip_duplicate_pmus)
633 		scan_fn = perf_pmus__scan_skip_duplicates;
634 	else
635 		scan_fn = perf_pmus__scan;
636 
637 	pmu = NULL;
638 	len = 0;
639 	while ((pmu = scan_fn(pmu)) != NULL)
640 		len += perf_pmu__num_events(pmu);
641 
642 	aliases = calloc(len, sizeof(struct sevent));
643 	if (!aliases) {
644 		pr_err("FATAL: not enough memory to print PMU events\n");
645 		return;
646 	}
647 	pmu = NULL;
648 	state = (struct events_callback_state) {
649 		.aliases = aliases,
650 		.aliases_len = len,
651 		.index = 0,
652 	};
653 	while ((pmu = scan_fn(pmu)) != NULL) {
654 		perf_pmu__for_each_event(pmu, skip_duplicate_pmus, &state,
655 					 perf_pmus__print_pmu_events__callback);
656 	}
657 	qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
658 	for (int j = 0; j < len; j++) {
659 		/* Skip duplicates */
660 		if (j < len - 1 && pmu_alias_is_duplicate(&aliases[j], &aliases[j + 1]))
661 			goto free;
662 
663 		print_cb->print_event(print_state,
664 				aliases[j].topic,
665 				aliases[j].pmu_name,
666 				aliases[j].pmu->type,
667 				aliases[j].name,
668 				aliases[j].alias,
669 				aliases[j].scale_unit,
670 				aliases[j].deprecated,
671 				aliases[j].event_type_desc,
672 				aliases[j].desc,
673 				aliases[j].long_desc,
674 				aliases[j].encoding_desc);
675 free:
676 		zfree(&aliases[j].name);
677 		zfree(&aliases[j].alias);
678 		zfree(&aliases[j].scale_unit);
679 		zfree(&aliases[j].desc);
680 		zfree(&aliases[j].long_desc);
681 		zfree(&aliases[j].encoding_desc);
682 		zfree(&aliases[j].topic);
683 		zfree(&aliases[j].pmu_name);
684 		zfree(&aliases[j].event_type_desc);
685 	}
686 	if (printed && pager_in_use())
687 		printf("\n");
688 
689 	zfree(&aliases);
690 }
691 
692 struct build_format_string_args {
693 	struct strbuf short_string;
694 	struct strbuf long_string;
695 	int num_formats;
696 };
697 
698 static int build_format_string(void *state, const char *name, int config,
699 			       const unsigned long *bits)
700 {
701 	struct build_format_string_args *args = state;
702 	unsigned int num_bits;
703 	int ret1, ret2 = 0;
704 
705 	(void)config;
706 	args->num_formats++;
707 	if (args->num_formats > 1) {
708 		strbuf_addch(&args->long_string, ',');
709 		if (args->num_formats < 4)
710 			strbuf_addch(&args->short_string, ',');
711 	}
712 	num_bits = bits ? bitmap_weight(bits, PERF_PMU_FORMAT_BITS) : 0;
713 	if (num_bits <= 1) {
714 		ret1 = strbuf_addf(&args->long_string, "%s", name);
715 		if (args->num_formats < 4)
716 			ret2 = strbuf_addf(&args->short_string, "%s", name);
717 	} else if (num_bits > 8) {
718 		ret1 = strbuf_addf(&args->long_string, "%s=0..0x%llx", name,
719 				   ULLONG_MAX >> (64 - num_bits));
720 		if (args->num_formats < 4) {
721 			ret2 = strbuf_addf(&args->short_string, "%s=0..0x%llx", name,
722 					   ULLONG_MAX >> (64 - num_bits));
723 		}
724 	} else {
725 		ret1 = strbuf_addf(&args->long_string, "%s=0..%llu", name,
726 				  ULLONG_MAX >> (64 - num_bits));
727 		if (args->num_formats < 4) {
728 			ret2 = strbuf_addf(&args->short_string, "%s=0..%llu", name,
729 					   ULLONG_MAX >> (64 - num_bits));
730 		}
731 	}
732 	return ret1 < 0 ? ret1 : (ret2 < 0 ? ret2 : 0);
733 }
734 
735 void perf_pmus__print_raw_pmu_events(const struct print_callbacks *print_cb, void *print_state)
736 {
737 	bool skip_duplicate_pmus = print_cb->skip_duplicate_pmus(print_state);
738 	struct perf_pmu *(*scan_fn)(struct perf_pmu *);
739 	struct perf_pmu *pmu = NULL;
740 
741 	if (skip_duplicate_pmus)
742 		scan_fn = perf_pmus__scan_skip_duplicates;
743 	else
744 		scan_fn = perf_pmus__scan;
745 
746 	while ((pmu = scan_fn(pmu)) != NULL) {
747 		struct build_format_string_args format_args = {
748 			.short_string = STRBUF_INIT,
749 			.long_string = STRBUF_INIT,
750 			.num_formats = 0,
751 		};
752 		int len = pmu_name_len_no_suffix(pmu->name);
753 		const char *desc = "(see 'man perf-list' or 'man perf-record' on how to encode it)";
754 
755 		if (!pmu->is_core)
756 			desc = NULL;
757 
758 		strbuf_addf(&format_args.short_string, "%.*s/", len, pmu->name);
759 		strbuf_addf(&format_args.long_string, "%.*s/", len, pmu->name);
760 		perf_pmu__for_each_format(pmu, &format_args, build_format_string);
761 
762 		if (format_args.num_formats > 3)
763 			strbuf_addf(&format_args.short_string, ",.../modifier");
764 		else
765 			strbuf_addf(&format_args.short_string, "/modifier");
766 
767 		strbuf_addf(&format_args.long_string, "/modifier");
768 		print_cb->print_event(print_state,
769 				/*topic=*/NULL,
770 				/*pmu_name=*/NULL,
771 				pmu->type,
772 				format_args.short_string.buf,
773 				/*event_alias=*/NULL,
774 				/*scale_unit=*/NULL,
775 				/*deprecated=*/false,
776 				"Raw event descriptor",
777 				desc,
778 				/*long_desc=*/NULL,
779 				format_args.long_string.buf);
780 
781 		strbuf_release(&format_args.short_string);
782 		strbuf_release(&format_args.long_string);
783 	}
784 }
785 
786 bool perf_pmus__have_event(const char *pname, const char *name)
787 {
788 	struct perf_pmu *pmu = perf_pmus__find(pname);
789 
790 	return pmu && perf_pmu__have_event(pmu, name);
791 }
792 
793 int perf_pmus__num_core_pmus(void)
794 {
795 	static int count;
796 
797 	if (!count) {
798 		struct perf_pmu *pmu = NULL;
799 
800 		while ((pmu = perf_pmus__scan_core(pmu)) != NULL)
801 			count++;
802 	}
803 	return count;
804 }
805 
806 static bool __perf_pmus__supports_extended_type(void)
807 {
808 	struct perf_pmu *pmu = NULL;
809 
810 	if (perf_pmus__num_core_pmus() <= 1)
811 		return false;
812 
813 	while ((pmu = perf_pmus__scan_core(pmu)) != NULL) {
814 		if (!is_event_supported(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES | ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT)))
815 			return false;
816 	}
817 
818 	return true;
819 }
820 
821 static bool perf_pmus__do_support_extended_type;
822 
823 static void perf_pmus__init_supports_extended_type(void)
824 {
825 	perf_pmus__do_support_extended_type = __perf_pmus__supports_extended_type();
826 }
827 
828 bool perf_pmus__supports_extended_type(void)
829 {
830 	static pthread_once_t extended_type_once = PTHREAD_ONCE_INIT;
831 
832 	pthread_once(&extended_type_once, perf_pmus__init_supports_extended_type);
833 
834 	return perf_pmus__do_support_extended_type;
835 }
836 
837 struct perf_pmu *perf_pmus__find_by_attr(const struct perf_event_attr *attr)
838 {
839 	struct perf_pmu *pmu = perf_pmus__find_by_type(attr->type);
840 	u32 type = attr->type;
841 	bool legacy_core_type = type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE;
842 
843 	if (!pmu && legacy_core_type && perf_pmus__supports_extended_type()) {
844 		type = attr->config >> PERF_PMU_TYPE_SHIFT;
845 
846 		pmu = perf_pmus__find_by_type(type);
847 	}
848 	if (!pmu && (legacy_core_type || type == PERF_TYPE_RAW)) {
849 		/*
850 		 * For legacy events, if there was no extended type info then
851 		 * assume the PMU is the first core PMU.
852 		 *
853 		 * On architectures like ARM there is no sysfs PMU with type
854 		 * PERF_TYPE_RAW, assume the RAW events are going to be handled
855 		 * by the first core PMU.
856 		 */
857 		pmu = perf_pmus__find_core_pmu();
858 	}
859 	return pmu;
860 }
861 
862 struct perf_pmu *evsel__find_pmu(const struct evsel *evsel)
863 {
864 	struct perf_pmu *pmu = evsel->pmu;
865 
866 	if (pmu)
867 		return pmu;
868 
869 	pmu = perf_pmus__find_by_attr(&evsel->core.attr);
870 	((struct evsel *)evsel)->pmu = pmu;
871 	return pmu;
872 }
873 
874 struct perf_pmu *perf_pmus__find_core_pmu(void)
875 {
876 	return perf_pmus__scan_core(NULL);
877 }
878 
879 struct perf_pmu *perf_pmus__add_test_pmu(int test_sysfs_dirfd, const char *name)
880 {
881 	/*
882 	 * Some PMU functions read from the sysfs mount point, so care is
883 	 * needed, hence passing the eager_load flag to load things like the
884 	 * format files.
885 	 */
886 	return perf_pmu__lookup(&other_pmus, test_sysfs_dirfd, name, /*eager_load=*/true);
887 }
888 
889 struct perf_pmu *perf_pmus__add_test_hwmon_pmu(const char *hwmon_dir,
890 					       const char *sysfs_name,
891 					       const char *name)
892 {
893 	return hwmon_pmu__new(&other_pmus, hwmon_dir, sysfs_name, name);
894 }
895 
896 struct perf_pmu *perf_pmus__fake_pmu(void)
897 {
898 	static struct perf_pmu fake = {
899 		.name = "fake",
900 		.type = PERF_PMU_TYPE_FAKE,
901 		.format = LIST_HEAD_INIT(fake.format),
902 	};
903 
904 	return &fake;
905 }
906