Skip to content

Commit 8d4b6d3

Browse files
captain5050acmel
authored andcommitted
perf pmu: Lazily load sysfs aliases
Don't load sysfs aliases for a PMU when the PMU is first created, defer until an alias needs to be found. For the pmu-scan benchmark, average core PMU scanning is reduced by 30.8%, and average PMU scanning by 12.6%. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Gaosheng Cui <cuigaosheng1@huawei.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jing Zhang <renyu.zj@linux.alibaba.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Garry <john.g.garry@oracle.com> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Cc: Rob Herring <robh@kernel.org> Link: https://lore.kernel.org/r/20230824041330.266337-17-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent 7b723db commit 8d4b6d3

3 files changed

Lines changed: 46 additions & 39 deletions

File tree

tools/perf/tests/pmu-events.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ static int __test_core_pmu_event_aliases(char *pmu_name, int *count)
547547
pmu->events_table = table;
548548
pmu_add_cpu_aliases_table(pmu, table);
549549
pmu->cpu_aliases_added = true;
550+
pmu->sysfs_aliases_loaded = true;
550551

551552
res = pmu_events_table__find_event(table, pmu, "bp_l1_btb_correct", NULL, NULL);
552553
if (res != 0) {
@@ -588,6 +589,7 @@ static int __test_uncore_pmu_event_aliases(struct perf_pmu_test_pmu *test_pmu)
588589
pmu->events_table = events_table;
589590
pmu_add_cpu_aliases_table(pmu, events_table);
590591
pmu->cpu_aliases_added = true;
592+
pmu->sysfs_aliases_loaded = true;
591593
pmu_add_sys_aliases(pmu);
592594

593595
/* Count how many aliases we generated */

tools/perf/util/pmu.c

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ struct perf_pmu_format {
115115
bool loaded;
116116
};
117117

118+
static int pmu_aliases_parse(struct perf_pmu *pmu);
119+
118120
static struct perf_pmu_format *perf_pmu__new_format(struct list_head *list, char *name)
119121
{
120122
struct perf_pmu_format *format;
@@ -420,10 +422,15 @@ static void perf_pmu__del_aliases(struct perf_pmu *pmu)
420422
}
421423
}
422424

423-
static struct perf_pmu_alias *perf_pmu__find_alias(const struct perf_pmu *pmu, const char *name)
425+
static struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu,
426+
const char *name,
427+
bool load)
424428
{
425429
struct perf_pmu_alias *alias;
426430

431+
if (load && !pmu->sysfs_aliases_loaded)
432+
pmu_aliases_parse(pmu);
433+
427434
list_for_each_entry(alias, &pmu->aliases, list) {
428435
if (!strcasecmp(alias->name, name))
429436
return alias;
@@ -505,7 +512,7 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name,
505512
const char *long_desc = NULL, *topic = NULL, *unit = NULL, *pmu_name = NULL;
506513
bool deprecated = false, perpkg = false;
507514

508-
if (perf_pmu__find_alias(pmu, name)) {
515+
if (perf_pmu__find_alias(pmu, name, /*load=*/ false)) {
509516
/* Alias was already created/loaded. */
510517
return 0;
511518
}
@@ -611,18 +618,33 @@ static inline bool pmu_alias_info_file(char *name)
611618
}
612619

613620
/*
614-
* Process all the sysfs attributes located under the directory
615-
* specified in 'dir' parameter.
621+
* Reading the pmu event aliases definition, which should be located at:
622+
* /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
616623
*/
617-
static int pmu_aliases_parse(struct perf_pmu *pmu, int dirfd)
624+
static int pmu_aliases_parse(struct perf_pmu *pmu)
618625
{
626+
char path[PATH_MAX];
619627
struct dirent *evt_ent;
620628
DIR *event_dir;
621-
int fd;
629+
size_t len;
630+
int fd, dir_fd;
622631

623-
event_dir = fdopendir(dirfd);
624-
if (!event_dir)
632+
len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));
633+
if (!len)
634+
return 0;
635+
scnprintf(path + len, sizeof(path) - len, "%s/events", pmu->name);
636+
637+
dir_fd = open(path, O_DIRECTORY);
638+
if (dir_fd == -1) {
639+
pmu->sysfs_aliases_loaded = true;
640+
return 0;
641+
}
642+
643+
event_dir = fdopendir(dir_fd);
644+
if (!event_dir){
645+
close (dir_fd);
625646
return -EINVAL;
647+
}
626648

627649
while ((evt_ent = readdir(event_dir))) {
628650
char *name = evt_ent->d_name;
@@ -637,7 +659,7 @@ static int pmu_aliases_parse(struct perf_pmu *pmu, int dirfd)
637659
if (pmu_alias_info_file(name))
638660
continue;
639661

640-
fd = openat(dirfd, name, O_RDONLY);
662+
fd = openat(dir_fd, name, O_RDONLY);
641663
if (fd == -1) {
642664
pr_debug("Cannot open %s\n", name);
643665
continue;
@@ -655,25 +677,8 @@ static int pmu_aliases_parse(struct perf_pmu *pmu, int dirfd)
655677
}
656678

657679
closedir(event_dir);
658-
return 0;
659-
}
660-
661-
/*
662-
* Reading the pmu event aliases definition, which should be located at:
663-
* /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
664-
*/
665-
static int pmu_aliases(struct perf_pmu *pmu, int dirfd, const char *name)
666-
{
667-
int fd;
668-
669-
fd = perf_pmu__pathname_fd(dirfd, name, "events", O_DIRECTORY);
670-
if (fd < 0)
671-
return 0;
672-
673-
/* it'll close the fd */
674-
if (pmu_aliases_parse(pmu, fd))
675-
return -1;
676-
680+
close (dir_fd);
681+
pmu->sysfs_aliases_loaded = true;
677682
return 0;
678683
}
679684

@@ -1017,13 +1022,6 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char
10171022
free(pmu);
10181023
return NULL;
10191024
}
1020-
/*
1021-
* Check the aliases first to avoid unnecessary work.
1022-
*/
1023-
if (pmu_aliases(pmu, dirfd, name)) {
1024-
free(pmu);
1025-
return NULL;
1026-
}
10271025
pmu->is_core = is_pmu_core(name);
10281026
pmu->cpus = pmu_cpumask(dirfd, name, pmu->is_core);
10291027

@@ -1438,7 +1436,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
14381436
return NULL;
14391437
}
14401438

1441-
alias = perf_pmu__find_alias(pmu, name);
1439+
alias = perf_pmu__find_alias(pmu, name, /*load=*/ true);
14421440
if (alias || pmu->cpu_aliases_added)
14431441
return alias;
14441442

@@ -1447,7 +1445,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
14471445
pmu_events_table__find_event(pmu->events_table, pmu, name,
14481446
pmu_add_cpu_aliases_map_callback,
14491447
pmu) == 0) {
1450-
alias = perf_pmu__find_alias(pmu, name);
1448+
alias = perf_pmu__find_alias(pmu, name, /*load=*/ false);
14511449
}
14521450
return alias;
14531451
}
@@ -1620,7 +1618,7 @@ bool perf_pmu__auto_merge_stats(const struct perf_pmu *pmu)
16201618

16211619
bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name)
16221620
{
1623-
if (perf_pmu__find_alias(pmu, name) != NULL)
1621+
if (perf_pmu__find_alias(pmu, name, /*load=*/ true) != NULL)
16241622
return true;
16251623
if (pmu->cpu_aliases_added || !pmu->events_table)
16261624
return false;
@@ -1629,7 +1627,12 @@ bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name)
16291627

16301628
size_t perf_pmu__num_events(struct perf_pmu *pmu)
16311629
{
1632-
size_t nr = pmu->sysfs_aliases;
1630+
size_t nr;
1631+
1632+
if (!pmu->sysfs_aliases_loaded)
1633+
pmu_aliases_parse(pmu);
1634+
1635+
nr = pmu->sysfs_aliases;
16331636

16341637
if (pmu->cpu_aliases_added)
16351638
nr += pmu->loaded_json_aliases;

tools/perf/util/pmu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ struct perf_pmu {
122122
uint32_t sysfs_aliases;
123123
/** @sysfs_aliases: Number of json event aliases loaded. */
124124
uint32_t loaded_json_aliases;
125+
/** @sysfs_aliases_loaded: Are sysfs aliases loaded from disk? */
126+
bool sysfs_aliases_loaded;
125127
/**
126128
* @cpu_aliases_added: Have all json events table entries for the PMU
127129
* been added?

0 commit comments

Comments
 (0)