aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/pmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/pmu.c')
-rw-r--r--tools/perf/util/pmu.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index ac16a9db1fb5..1c4d7b4e4fb5 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -470,17 +470,36 @@ static void pmu_read_sysfs(void)
470 closedir(dir); 470 closedir(dir);
471} 471}
472 472
473static struct cpu_map *__pmu_cpumask(const char *path)
474{
475 FILE *file;
476 struct cpu_map *cpus;
477
478 file = fopen(path, "r");
479 if (!file)
480 return NULL;
481
482 cpus = cpu_map__read(file);
483 fclose(file);
484 return cpus;
485}
486
487/*
488 * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64)
489 * may have a "cpus" file.
490 */
491#define CPUS_TEMPLATE_UNCORE "%s/bus/event_source/devices/%s/cpumask"
492#define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus"
493
473static struct cpu_map *pmu_cpumask(const char *name) 494static struct cpu_map *pmu_cpumask(const char *name)
474{ 495{
475 struct stat st;
476 char path[PATH_MAX]; 496 char path[PATH_MAX];
477 FILE *file;
478 struct cpu_map *cpus; 497 struct cpu_map *cpus;
479 const char *sysfs = sysfs__mountpoint(); 498 const char *sysfs = sysfs__mountpoint();
480 const char *templates[] = { 499 const char *templates[] = {
481 "%s/bus/event_source/devices/%s/cpumask", 500 CPUS_TEMPLATE_UNCORE,
482 "%s/bus/event_source/devices/%s/cpus", 501 CPUS_TEMPLATE_CPU,
483 NULL 502 NULL
484 }; 503 };
485 const char **template; 504 const char **template;
486 505
@@ -489,20 +508,25 @@ static struct cpu_map *pmu_cpumask(const char *name)
489 508
490 for (template = templates; *template; template++) { 509 for (template = templates; *template; template++) {
491 snprintf(path, PATH_MAX, *template, sysfs, name); 510 snprintf(path, PATH_MAX, *template, sysfs, name);
492 if (stat(path, &st) == 0) 511 cpus = __pmu_cpumask(path);
493 break; 512 if (cpus)
513 return cpus;
494 } 514 }
495 515
496 if (!*template) 516 return NULL;
497 return NULL; 517}
498 518
499 file = fopen(path, "r"); 519static bool pmu_is_uncore(const char *name)
500 if (!file) 520{
501 return NULL; 521 char path[PATH_MAX];
522 struct cpu_map *cpus;
523 const char *sysfs = sysfs__mountpoint();
502 524
503 cpus = cpu_map__read(file); 525 snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name);
504 fclose(file); 526 cpus = __pmu_cpumask(path);
505 return cpus; 527 cpu_map__put(cpus);
528
529 return !!cpus;
506} 530}
507 531
508/* 532/*
@@ -617,6 +641,8 @@ static struct perf_pmu *pmu_lookup(const char *name)
617 641
618 pmu->cpus = pmu_cpumask(name); 642 pmu->cpus = pmu_cpumask(name);
619 643
644 pmu->is_uncore = pmu_is_uncore(name);
645
620 INIT_LIST_HEAD(&pmu->format); 646 INIT_LIST_HEAD(&pmu->format);
621 INIT_LIST_HEAD(&pmu->aliases); 647 INIT_LIST_HEAD(&pmu->aliases);
622 list_splice(&format, &pmu->format); 648 list_splice(&format, &pmu->format);