Skip to content

Commit 7b6dd7a

Browse files
captain5050acmel
authored andcommitted
perf pmu: Assume sysfs events are always the same case
Perf event names aren't case sensitive. For sysfs events the entire directory of events is read then iterated comparing names in a case insensitive way, most often to see if an event is present. Consider: $ perf stat -e inst_retired.any true The event inst_retired.any may be present in any PMU, so every PMU's sysfs events are loaded and then searched with strcasecmp to see if any match. This event is only present on the cpu PMU as a JSON event so a lot of events were loaded from sysfs unnecessarily just to prove an event didn't exist there. This change avoids loading all the events by assuming sysfs event names are always either lower or uppercase. It uses file exists and only loads the events when the desired event is present. For the example above, the number of openat calls measured by 'perf trace' on a tigerlake laptop goes from 325 down to 255. The reduction will be larger for machines with many PMUs, particularly replicated uncore PMUs. Ensure pmu_aliases_parse() is called before all uses of the aliases list, but remove some "pmu->sysfs_aliases_loaded" tests as they are now part of the function. Reviewed-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Ian Rogers <irogers@google.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Bjorn Helgaas <bhelgaas@google.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: Jonathan Corbet <corbet@lwn.net> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Randy Dunlap <rdunlap@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Cc: Thomas Richter <tmricht@linux.ibm.com> Link: https://lore.kernel.org/r/20240502213507.2339733-7-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent 6debc5a commit 7b6dd7a

1 file changed

Lines changed: 26 additions & 5 deletions

File tree

tools/perf/util/pmu.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -425,9 +425,30 @@ static struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu,
425425
{
426426
struct perf_pmu_alias *alias;
427427

428-
if (load && !pmu->sysfs_aliases_loaded)
429-
pmu_aliases_parse(pmu);
428+
if (load && !pmu->sysfs_aliases_loaded) {
429+
bool has_sysfs_event;
430+
char event_file_name[FILENAME_MAX + 8];
430431

432+
/*
433+
* Test if alias/event 'name' exists in the PMU's sysfs/events
434+
* directory. If not skip parsing the sysfs aliases. Sysfs event
435+
* name must be all lower or all upper case.
436+
*/
437+
scnprintf(event_file_name, sizeof(event_file_name), "events/%s", name);
438+
for (size_t i = 7, n = 7 + strlen(name); i < n; i++)
439+
event_file_name[i] = tolower(event_file_name[i]);
440+
441+
has_sysfs_event = perf_pmu__file_exists(pmu, event_file_name);
442+
if (!has_sysfs_event) {
443+
for (size_t i = 7, n = 7 + strlen(name); i < n; i++)
444+
event_file_name[i] = toupper(event_file_name[i]);
445+
446+
has_sysfs_event = perf_pmu__file_exists(pmu, event_file_name);
447+
}
448+
if (has_sysfs_event)
449+
pmu_aliases_parse(pmu);
450+
451+
}
431452
list_for_each_entry(alias, &pmu->aliases, list) {
432453
if (!strcasecmp(alias->name, name))
433454
return alias;
@@ -1717,9 +1738,7 @@ size_t perf_pmu__num_events(struct perf_pmu *pmu)
17171738
{
17181739
size_t nr;
17191740

1720-
if (!pmu->sysfs_aliases_loaded)
1721-
pmu_aliases_parse(pmu);
1722-
1741+
pmu_aliases_parse(pmu);
17231742
nr = pmu->sysfs_aliases;
17241743

17251744
if (pmu->cpu_aliases_added)
@@ -1778,6 +1797,7 @@ int perf_pmu__for_each_event(struct perf_pmu *pmu, bool skip_duplicate_pmus,
17781797
struct strbuf sb;
17791798

17801799
strbuf_init(&sb, /*hint=*/ 0);
1800+
pmu_aliases_parse(pmu);
17811801
pmu_add_cpu_aliases(pmu);
17821802
list_for_each_entry(event, &pmu->aliases, list) {
17831803
size_t buf_used;
@@ -2193,6 +2213,7 @@ const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config)
21932213
if (!pmu)
21942214
return NULL;
21952215

2216+
pmu_aliases_parse(pmu);
21962217
pmu_add_cpu_aliases(pmu);
21972218
list_for_each_entry(event, &pmu->aliases, list) {
21982219
struct perf_event_attr attr = {.config = 0,};

0 commit comments

Comments
 (0)