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