From: Ian Rogers <irogers@google.com>
To: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
James Clark <james.clark@arm.com>,
Kan Liang <kan.liang@linux.intel.com>,
John Garry <john.g.garry@oracle.com>,
Kajol Jain <kjain@linux.ibm.com>,
Jing Zhang <renyu.zj@linux.alibaba.com>,
Ravi Bangoria <ravi.bangoria@amd.com>,
Rob Herring <robh@kernel.org>,
Gaosheng Cui <cuigaosheng1@huawei.com>,
linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v1 24/25] perf pmu: Lazily load sysfs aliases
Date: Wed, 23 Aug 2023 01:08:27 -0700 [thread overview]
Message-ID: <20230823080828.1460376-25-irogers@google.com> (raw)
In-Reply-To: <20230823080828.1460376-1-irogers@google.com>
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>
---
tools/perf/tests/pmu-events.c | 2 +
tools/perf/util/pmu.c | 81 ++++++++++++++++++-----------------
tools/perf/util/pmu.h | 2 +
3 files changed, 46 insertions(+), 39 deletions(-)
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
index 9ac893ae5f0d..3dc1ebee4d9f 100644
--- a/tools/perf/tests/pmu-events.c
+++ b/tools/perf/tests/pmu-events.c
@@ -547,6 +547,7 @@ static int __test_core_pmu_event_aliases(char *pmu_name, int *count)
pmu->events_table = table;
pmu_add_cpu_aliases_table(pmu, table);
pmu->cpu_aliases_added = true;
+ pmu->sysfs_aliases_loaded = true;
res = pmu_events_table__find_event(table, pmu, "bp_l1_btb_correct", NULL, NULL);
if (res != 0) {
@@ -588,6 +589,7 @@ static int __test_uncore_pmu_event_aliases(struct perf_pmu_test_pmu *test_pmu)
pmu->events_table = events_table;
pmu_add_cpu_aliases_table(pmu, events_table);
pmu->cpu_aliases_added = true;
+ pmu->sysfs_aliases_loaded = true;
pmu_add_sys_aliases(pmu);
/* Count how many aliases we generated */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index c547fe607f9f..fb437b50443f 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -115,6 +115,8 @@ struct perf_pmu_format {
bool loaded;
};
+static int pmu_aliases_parse(struct perf_pmu *pmu);
+
static struct perf_pmu_format *perf_pmu__new_format(struct list_head *list, char *name)
{
struct perf_pmu_format *format;
@@ -416,10 +418,15 @@ static void perf_pmu__del_aliases(struct perf_pmu *pmu)
}
}
-static struct perf_pmu_alias *perf_pmu__find_alias(const struct perf_pmu *pmu, const char *name)
+static struct perf_pmu_alias *perf_pmu__find_alias(struct perf_pmu *pmu,
+ const char *name,
+ bool load)
{
struct perf_pmu_alias *alias;
+ if (load && !pmu->sysfs_aliases_loaded)
+ pmu_aliases_parse(pmu);
+
list_for_each_entry(alias, &pmu->aliases, list) {
if (!strcasecmp(alias->name, name))
return alias;
@@ -501,7 +508,7 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name,
const char *long_desc = NULL, *topic = NULL, *unit = NULL, *pmu_name = NULL;
bool deprecated = false, perpkg = false;
- if (perf_pmu__find_alias(pmu, name)) {
+ if (perf_pmu__find_alias(pmu, name, /*load=*/ false)) {
/* Alias was already created/loaded. */
return 0;
}
@@ -607,18 +614,33 @@ static inline bool pmu_alias_info_file(char *name)
}
/*
- * Process all the sysfs attributes located under the directory
- * specified in 'dir' parameter.
+ * Reading the pmu event aliases definition, which should be located at:
+ * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
*/
-static int pmu_aliases_parse(struct perf_pmu *pmu, int dirfd)
+static int pmu_aliases_parse(struct perf_pmu *pmu)
{
+ char path[PATH_MAX];
struct dirent *evt_ent;
DIR *event_dir;
- int fd;
+ size_t len;
+ int fd, dir_fd;
- event_dir = fdopendir(dirfd);
- if (!event_dir)
+ len = perf_pmu__event_source_devices_scnprintf(path, sizeof(path));
+ if (!len)
+ return 0;
+ scnprintf(path + len, sizeof(path) - len, "%s/events", pmu->name);
+
+ dir_fd = open(path, O_DIRECTORY);
+ if (dir_fd == -1) {
+ pmu->sysfs_aliases_loaded = true;
+ return 0;
+ }
+
+ event_dir = fdopendir(dir_fd);
+ if (!event_dir){
+ close (dir_fd);
return -EINVAL;
+ }
while ((evt_ent = readdir(event_dir))) {
char *name = evt_ent->d_name;
@@ -633,7 +655,7 @@ static int pmu_aliases_parse(struct perf_pmu *pmu, int dirfd)
if (pmu_alias_info_file(name))
continue;
- fd = openat(dirfd, name, O_RDONLY);
+ fd = openat(dir_fd, name, O_RDONLY);
if (fd == -1) {
pr_debug("Cannot open %s\n", name);
continue;
@@ -651,25 +673,8 @@ static int pmu_aliases_parse(struct perf_pmu *pmu, int dirfd)
}
closedir(event_dir);
- return 0;
-}
-
-/*
- * Reading the pmu event aliases definition, which should be located at:
- * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
- */
-static int pmu_aliases(struct perf_pmu *pmu, int dirfd, const char *name)
-{
- int fd;
-
- fd = perf_pmu__pathname_fd(dirfd, name, "events", O_DIRECTORY);
- if (fd < 0)
- return 0;
-
- /* it'll close the fd */
- if (pmu_aliases_parse(pmu, fd))
- return -1;
-
+ close (dir_fd);
+ pmu->sysfs_aliases_loaded = true;
return 0;
}
@@ -1013,13 +1018,6 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char
free(pmu);
return NULL;
}
- /*
- * Check the aliases first to avoid unnecessary work.
- */
- if (pmu_aliases(pmu, dirfd, name)) {
- free(pmu);
- return NULL;
- }
pmu->is_core = is_pmu_core(name);
pmu->cpus = pmu_cpumask(dirfd, name, pmu->is_core);
@@ -1434,7 +1432,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
return NULL;
}
- alias = perf_pmu__find_alias(pmu, name);
+ alias = perf_pmu__find_alias(pmu, name, /*load=*/ true);
if (alias || pmu->cpu_aliases_added)
return alias;
@@ -1443,7 +1441,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
pmu_events_table__find_event(pmu->events_table, pmu, name,
pmu_add_cpu_aliases_map_callback,
pmu) == 0) {
- alias = perf_pmu__find_alias(pmu, name);
+ alias = perf_pmu__find_alias(pmu, name, /*load=*/ false);
}
return alias;
}
@@ -1616,7 +1614,7 @@ bool perf_pmu__auto_merge_stats(const struct perf_pmu *pmu)
bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name)
{
- if (perf_pmu__find_alias(pmu, name) != NULL)
+ if (perf_pmu__find_alias(pmu, name, /*load=*/ true) != NULL)
return true;
if (pmu->cpu_aliases_added || !pmu->events_table)
return false;
@@ -1625,7 +1623,12 @@ bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name)
size_t perf_pmu__num_events(struct perf_pmu *pmu)
{
- size_t nr = pmu->sysfs_aliases;
+ size_t nr;
+
+ if (!pmu->sysfs_aliases_loaded)
+ pmu_aliases_parse(pmu);
+
+ nr = pmu->sysfs_aliases;
if (pmu->cpu_aliases_added)
nr += pmu->loaded_json_aliases;
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 288d2908382a..bae0de3ed7a5 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -122,6 +122,8 @@ struct perf_pmu {
uint32_t sysfs_aliases;
/** @sysfs_aliases: Number of json event aliases loaded. */
uint32_t loaded_json_aliases;
+ /** @sysfs_aliases_loaded: Are sysfs aliases loaded from disk? */
+ bool sysfs_aliases_loaded;
/**
* @cpu_aliases_added: Have all json events table entries for the PMU
* been added?
--
2.42.0.rc1.204.g551eb34607-goog
next prev parent reply other threads:[~2023-08-23 8:22 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-23 8:08 [PATCH v1 00/25] Lazily load PMU data Ian Rogers
2023-08-23 8:08 ` [PATCH v1 01/25] perf script ibs: Remove unused include Ian Rogers
2023-08-23 8:08 ` [PATCH v1 02/25] perf pmu: Avoid a path name copy Ian Rogers
2023-08-23 8:08 ` [PATCH v1 03/25] perf pmu: Move perf_pmu__set_format to pmu.y Ian Rogers
2023-08-23 8:08 ` [PATCH v1 04/25] perf pmu: Reduce scope of perf_pmu_error Ian Rogers
2023-08-23 8:08 ` [PATCH v1 05/25] perf pmu: Avoid passing format list to perf_pmu__config_terms Ian Rogers
2023-08-23 8:08 ` [PATCH v1 06/25] perf pmu: Avoid passing format list to perf_pmu__format_type Ian Rogers
2023-08-23 8:08 ` [PATCH v1 07/25] perf pmu: Avoid passing format list to perf_pmu__format_bits Ian Rogers
2023-08-23 8:08 ` [PATCH v1 08/25] perf pmu: Pass PMU rather than aliases and format Ian Rogers
2023-08-23 8:08 ` [PATCH v1 09/25] perf pmu: Make the loading of formats lazy Ian Rogers
2023-08-23 11:54 ` Arnaldo Carvalho de Melo
2023-08-24 2:23 ` Ian Rogers
2023-08-23 8:08 ` [PATCH v1 10/25] perf pmu: Abstract alias/event struct Ian Rogers
2023-08-23 8:08 ` [PATCH v1 11/25] perf pmu-events: Add extra underscore to function names Ian Rogers
2023-08-23 8:08 ` [PATCH v1 12/25] perf jevents: Group events by PMU Ian Rogers
2023-08-23 8:08 ` [PATCH v1 13/25] perf parse-events: Improve error message for double setting Ian Rogers
2023-08-23 8:08 ` [PATCH v1 14/25] perf s390 s390_cpumcfdg_dump: Don't scan all PMUs Ian Rogers
2023-08-23 8:08 ` [PATCH v1 15/25] perf pmu-events: Reduce processed events by passing PMU Ian Rogers
2023-08-23 8:08 ` [PATCH v1 16/25] perf pmu-events: Add pmu_events_table__find_event Ian Rogers
2023-08-23 8:08 ` [PATCH v1 17/25] perf pmu: Parse sysfs events directly from a file Ian Rogers
2023-08-23 8:08 ` [PATCH v1 18/25] perf pmu: Prefer passing pmu to aliases list Ian Rogers
2023-08-23 8:08 ` [PATCH v1 19/25] perf pmu: Merge json events with sysfs at load time Ian Rogers
2023-08-23 8:08 ` [PATCH v1 20/25] perf pmu: Cache json events table Ian Rogers
2023-08-23 8:08 ` [PATCH v1 21/25] perf pmu: Lazily add json events Ian Rogers
2023-08-23 8:08 ` [PATCH v1 22/25] perf pmu: Scan type early to fail an invalid PMU quickly Ian Rogers
2023-08-23 8:08 ` [PATCH v1 23/25] perf pmu: Be lazy about loading event info files from sysfs Ian Rogers
2023-08-23 8:08 ` Ian Rogers [this message]
2023-08-23 8:08 ` [PATCH v1 25/25] perf jevents: Sort strings in the big C string to reduce faults Ian Rogers
2023-08-23 8:12 ` [PATCH v1 00/25] Lazily load PMU data Ian Rogers
2023-08-23 15:56 ` Arnaldo Carvalho de Melo
[not found] ` <CAP-5=fXYDMo6GgSaLuC3YMNr66yAXLMyZoAOMpdgmMb=xazCOw@mail.gmail.com>
2023-08-23 17:11 ` Arnaldo Carvalho de Melo
2023-08-23 17:40 ` Ian Rogers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230823080828.1460376-25-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=cuigaosheng1@huawei.com \
--cc=james.clark@arm.com \
--cc=john.g.garry@oracle.com \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=kjain@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=ravi.bangoria@amd.com \
--cc=renyu.zj@linux.alibaba.com \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®