From: Ian Rogers <irogers@google.com>
To: "Peter Zijlstra" <peterz@infradead.org>,
"Ingo Molnar" <mingo@redhat.com>,
"Arnaldo Carvalho de Melo" <acme@kernel.org>,
"Namhyung Kim" <namhyung@kernel.org>,
"Mark Rutland" <mark.rutland@arm.com>,
"Alexander Shishkin" <alexander.shishkin@linux.intel.com>,
"Jiri Olsa" <jolsa@kernel.org>, "Ian Rogers" <irogers@google.com>,
"Adrian Hunter" <adrian.hunter@intel.com>,
"James Clark" <james.clark@arm.com>,
"Athira Rajeev" <atrajeev@linux.vnet.ibm.com>,
"Colin Ian King" <colin.i.king@gmail.com>,
"Ahelenia Ziemiańska" <nabijaczleweli@nabijaczleweli.xyz>,
"Leo Yan" <leo.yan@linux.dev>, "Song Liu" <song@kernel.org>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Liam Howlett" <liam.howlett@oracle.com>,
"Ilkka Koskinen" <ilkka@os.amperecomputing.com>,
"Ben Gainey" <ben.gainey@arm.com>,
"K Prateek Nayak" <kprateek.nayak@amd.com>,
"Kan Liang" <kan.liang@linux.intel.com>,
"Yanteng Si" <siyanteng@loongson.cn>,
"Ravi Bangoria" <ravi.bangoria@amd.com>,
"Sun Haiyong" <sunhaiyong@loongson.cn>,
"Changbin Du" <changbin.du@huawei.com>,
"Masami Hiramatsu" <mhiramat@kernel.org>,
zhaimingbing <zhaimingbing@cmss.chinamobile.com>,
"Paran Lee" <p4ranlee@gmail.com>, "Li Dong" <lidong@vivo.com>,
elfring@users.sourceforge.net, "Andi Kleen" <ak@linux.intel.com>,
"Markus Elfring" <Markus.Elfring@web.de>,
"Chengen Du" <chengen.du@canonical.com>,
linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
bpf@vger.kernel.org
Subject: [PATCH v2 06/13] perf dsos: Switch more loops to dsos__for_each_dso
Date: Thu, 21 Mar 2024 09:02:53 -0700 [thread overview]
Message-ID: <20240321160300.1635121-7-irogers@google.com> (raw)
In-Reply-To: <20240321160300.1635121-1-irogers@google.com>
Switch loops within dsos.c, add a version that isn't locked. Switch
some unlocked loops to hold the read lock.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/util/build-id.c | 2 +-
tools/perf/util/dsos.c | 258 ++++++++++++++++++++++++-------------
tools/perf/util/dsos.h | 8 +-
tools/perf/util/machine.c | 8 +-
4 files changed, 174 insertions(+), 102 deletions(-)
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index a6d3c253f19f..864bc26b6b46 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -964,7 +964,7 @@ int perf_session__cache_build_ids(struct perf_session *session)
static bool machine__read_build_ids(struct machine *machine, bool with_hits)
{
- return __dsos__read_build_ids(&machine->dsos, with_hits);
+ return dsos__read_build_ids(&machine->dsos, with_hits);
}
bool perf_session__read_build_ids(struct perf_session *session, bool with_hits)
diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c
index f816927a21ff..b7fbfb877ae3 100644
--- a/tools/perf/util/dsos.c
+++ b/tools/perf/util/dsos.c
@@ -41,38 +41,65 @@ void dsos__exit(struct dsos *dsos)
exit_rwsem(&dsos->lock);
}
-bool __dsos__read_build_ids(struct dsos *dsos, bool with_hits)
+
+static int __dsos__for_each_dso(struct dsos *dsos,
+ int (*cb)(struct dso *dso, void *data),
+ void *data)
+{
+ struct dso *dso;
+
+ list_for_each_entry(dso, &dsos->head, node) {
+ int err;
+
+ err = cb(dso, data);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+struct dsos__read_build_ids_cb_args {
+ bool with_hits;
+ bool have_build_id;
+};
+
+static int dsos__read_build_ids_cb(struct dso *dso, void *data)
{
- struct list_head *head = &dsos->head;
- bool have_build_id = false;
- struct dso *pos;
+ struct dsos__read_build_ids_cb_args *args = data;
struct nscookie nsc;
- list_for_each_entry(pos, head, node) {
- if (with_hits && !pos->hit && !dso__is_vdso(pos))
- continue;
- if (pos->has_build_id) {
- have_build_id = true;
- continue;
- }
- nsinfo__mountns_enter(pos->nsinfo, &nsc);
- if (filename__read_build_id(pos->long_name, &pos->bid) > 0) {
- have_build_id = true;
- pos->has_build_id = true;
- } else if (errno == ENOENT && pos->nsinfo) {
- char *new_name = dso__filename_with_chroot(pos, pos->long_name);
-
- if (new_name && filename__read_build_id(new_name,
- &pos->bid) > 0) {
- have_build_id = true;
- pos->has_build_id = true;
- }
- free(new_name);
+ if (args->with_hits && !dso->hit && !dso__is_vdso(dso))
+ return 0;
+ if (dso->has_build_id) {
+ args->have_build_id = true;
+ return 0;
+ }
+ nsinfo__mountns_enter(dso->nsinfo, &nsc);
+ if (filename__read_build_id(dso->long_name, &dso->bid) > 0) {
+ args->have_build_id = true;
+ dso->has_build_id = true;
+ } else if (errno == ENOENT && dso->nsinfo) {
+ char *new_name = dso__filename_with_chroot(dso, dso->long_name);
+
+ if (new_name && filename__read_build_id(new_name, &dso->bid) > 0) {
+ args->have_build_id = true;
+ dso->has_build_id = true;
}
- nsinfo__mountns_exit(&nsc);
+ free(new_name);
}
+ nsinfo__mountns_exit(&nsc);
+ return 0;
+}
- return have_build_id;
+bool dsos__read_build_ids(struct dsos *dsos, bool with_hits)
+{
+ struct dsos__read_build_ids_cb_args args = {
+ .with_hits = with_hits,
+ .have_build_id = false,
+ };
+
+ dsos__for_each_dso(dsos, dsos__read_build_ids_cb, &args);
+ return args.have_build_id;
}
static int __dso__cmp_long_name(const char *long_name, struct dso_id *id, struct dso *b)
@@ -105,6 +132,7 @@ struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso
if (!name)
name = dso->long_name;
+
/*
* Find node with the matching name
*/
@@ -185,17 +213,40 @@ static struct dso *__dsos__findnew_by_longname_id(struct rb_root *root, const ch
return __dsos__findnew_link_by_longname_id(root, NULL, name, id);
}
+struct dsos__find_id_cb_args {
+ const char *name;
+ struct dso_id *id;
+ struct dso *res;
+};
+
+static int dsos__find_id_cb(struct dso *dso, void *data)
+{
+ struct dsos__find_id_cb_args *args = data;
+
+ if (__dso__cmp_short_name(args->name, args->id, dso) == 0) {
+ args->res = dso__get(dso);
+ return 1;
+ }
+ return 0;
+
+}
+
static struct dso *__dsos__find_id(struct dsos *dsos, const char *name, struct dso_id *id, bool cmp_short)
{
- struct dso *pos;
+ struct dso *res;
if (cmp_short) {
- list_for_each_entry(pos, &dsos->head, node)
- if (__dso__cmp_short_name(name, id, pos) == 0)
- return dso__get(pos);
- return NULL;
+ struct dsos__find_id_cb_args args = {
+ .name = name,
+ .id = id,
+ .res = NULL,
+ };
+
+ __dsos__for_each_dso(dsos, dsos__find_id_cb, &args);
+ return args.res;
}
- return __dsos__findnew_by_longname_id(&dsos->root, name, id);
+ res = __dsos__findnew_by_longname_id(&dsos->root, name, id);
+ return res;
}
struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
@@ -275,48 +326,74 @@ struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id
return dso;
}
-size_t __dsos__fprintf_buildid(struct dsos *dsos, FILE *fp,
- bool (skip)(struct dso *dso, int parm), int parm)
-{
- struct list_head *head = &dsos->head;
- struct dso *pos;
- size_t ret = 0;
+struct dsos__fprintf_buildid_cb_args {
+ FILE *fp;
+ bool (*skip)(struct dso *dso, int parm);
+ int parm;
+ size_t ret;
+};
- list_for_each_entry(pos, head, node) {
- char sbuild_id[SBUILD_ID_SIZE];
+static int dsos__fprintf_buildid_cb(struct dso *dso, void *data)
+{
+ struct dsos__fprintf_buildid_cb_args *args = data;
+ char sbuild_id[SBUILD_ID_SIZE];
- if (skip && skip(pos, parm))
- continue;
- build_id__sprintf(&pos->bid, sbuild_id);
- ret += fprintf(fp, "%-40s %s\n", sbuild_id, pos->long_name);
- }
- return ret;
+ if (args->skip && args->skip(dso, args->parm))
+ return 0;
+ build_id__sprintf(&dso->bid, sbuild_id);
+ args->ret += fprintf(args->fp, "%-40s %s\n", sbuild_id, dso->long_name);
+ return 0;
}
-size_t __dsos__fprintf(struct dsos *dsos, FILE *fp)
+size_t dsos__fprintf_buildid(struct dsos *dsos, FILE *fp,
+ bool (*skip)(struct dso *dso, int parm), int parm)
{
- struct list_head *head = &dsos->head;
- struct dso *pos;
- size_t ret = 0;
+ struct dsos__fprintf_buildid_cb_args args = {
+ .fp = fp,
+ .skip = skip,
+ .parm = parm,
+ .ret = 0,
+ };
+
+ dsos__for_each_dso(dsos, dsos__fprintf_buildid_cb, &args);
+ return args.ret;
+}
- list_for_each_entry(pos, head, node) {
- ret += dso__fprintf(pos, fp);
- }
+struct dsos__fprintf_cb_args {
+ FILE *fp;
+ size_t ret;
+};
- return ret;
+static int dsos__fprintf_cb(struct dso *dso, void *data)
+{
+ struct dsos__fprintf_cb_args *args = data;
+
+ args->ret += dso__fprintf(dso, args->fp);
+ return 0;
}
-int __dsos__hit_all(struct dsos *dsos)
+size_t dsos__fprintf(struct dsos *dsos, FILE *fp)
{
- struct list_head *head = &dsos->head;
- struct dso *pos;
+ struct dsos__fprintf_cb_args args = {
+ .fp = fp,
+ .ret = 0,
+ };
- list_for_each_entry(pos, head, node)
- pos->hit = true;
+ dsos__for_each_dso(dsos, dsos__fprintf_cb, &args);
+ return args.ret;
+}
+static int dsos__hit_all_cb(struct dso *dso, void *data __maybe_unused)
+{
+ dso->hit = true;
return 0;
}
+int dsos__hit_all(struct dsos *dsos)
+{
+ return dsos__for_each_dso(dsos, dsos__hit_all_cb, NULL);
+}
+
struct dso *dsos__findnew_module_dso(struct dsos *dsos,
struct machine *machine,
struct kmod_path *m,
@@ -342,49 +419,44 @@ struct dso *dsos__findnew_module_dso(struct dsos *dsos,
return dso;
}
-struct dso *dsos__find_kernel_dso(struct dsos *dsos)
+static int dsos__find_kernel_dso_cb(struct dso *dso, void *data)
{
- struct dso *dso, *res = NULL;
+ struct dso **res = data;
+ /*
+ * The cpumode passed to is_kernel_module is not the cpumode of *this*
+ * event. If we insist on passing correct cpumode to is_kernel_module,
+ * we should record the cpumode when we adding this dso to the linked
+ * list.
+ *
+ * However we don't really need passing correct cpumode. We know the
+ * correct cpumode must be kernel mode (if not, we should not link it
+ * onto kernel_dsos list).
+ *
+ * Therefore, we pass PERF_RECORD_MISC_CPUMODE_UNKNOWN.
+ * is_kernel_module() treats it as a kernel cpumode.
+ */
+ if (!dso->kernel ||
+ is_kernel_module(dso->long_name, PERF_RECORD_MISC_CPUMODE_UNKNOWN))
+ return 0;
- down_read(&dsos->lock);
- list_for_each_entry(dso, &dsos->head, node) {
- /*
- * The cpumode passed to is_kernel_module is not the cpumode of
- * *this* event. If we insist on passing correct cpumode to
- * is_kernel_module, we should record the cpumode when we adding
- * this dso to the linked list.
- *
- * However we don't really need passing correct cpumode. We
- * know the correct cpumode must be kernel mode (if not, we
- * should not link it onto kernel_dsos list).
- *
- * Therefore, we pass PERF_RECORD_MISC_CPUMODE_UNKNOWN.
- * is_kernel_module() treats it as a kernel cpumode.
- */
- if (!dso->kernel ||
- is_kernel_module(dso->long_name,
- PERF_RECORD_MISC_CPUMODE_UNKNOWN))
- continue;
+ *res = dso__get(dso);
+ return 1;
+}
- res = dso__get(dso);
- break;
- }
- up_read(&dsos->lock);
+struct dso *dsos__find_kernel_dso(struct dsos *dsos)
+{
+ struct dso *res = NULL;
+
+ dsos__for_each_dso(dsos, dsos__find_kernel_dso_cb, &res);
return res;
}
int dsos__for_each_dso(struct dsos *dsos, int (*cb)(struct dso *dso, void *data), void *data)
{
- struct dso *dso;
+ int err;
down_read(&dsos->lock);
- list_for_each_entry(dso, &dsos->head, node) {
- int err;
-
- err = cb(dso, data);
- if (err)
- return err;
- }
+ err = __dsos__for_each_dso(dsos, cb, data);
up_read(&dsos->lock);
- return 0;
+ return err;
}
diff --git a/tools/perf/util/dsos.h b/tools/perf/util/dsos.h
index 317a263f0e37..50bd51523475 100644
--- a/tools/perf/util/dsos.h
+++ b/tools/perf/util/dsos.h
@@ -33,16 +33,16 @@ struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short);
struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id *id);
-bool __dsos__read_build_ids(struct dsos *dsos, bool with_hits);
+bool dsos__read_build_ids(struct dsos *dsos, bool with_hits);
struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso *dso,
const char *name, struct dso_id *id);
-size_t __dsos__fprintf_buildid(struct dsos *dsos, FILE *fp,
+size_t dsos__fprintf_buildid(struct dsos *dsos, FILE *fp,
bool (skip)(struct dso *dso, int parm), int parm);
-size_t __dsos__fprintf(struct dsos *dsos, FILE *fp);
+size_t dsos__fprintf(struct dsos *dsos, FILE *fp);
-int __dsos__hit_all(struct dsos *dsos);
+int dsos__hit_all(struct dsos *dsos);
struct dso *dsos__findnew_module_dso(struct dsos *dsos, struct machine *machine,
struct kmod_path *m, const char *filename);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index bd153bc2c8da..97a0c21ba2a5 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -853,11 +853,11 @@ static struct map *machine__addnew_module_map(struct machine *machine, u64 start
size_t machines__fprintf_dsos(struct machines *machines, FILE *fp)
{
struct rb_node *nd;
- size_t ret = __dsos__fprintf(&machines->host.dsos, fp);
+ size_t ret = dsos__fprintf(&machines->host.dsos, fp);
for (nd = rb_first_cached(&machines->guests); nd; nd = rb_next(nd)) {
struct machine *pos = rb_entry(nd, struct machine, rb_node);
- ret += __dsos__fprintf(&pos->dsos, fp);
+ ret += dsos__fprintf(&pos->dsos, fp);
}
return ret;
@@ -866,7 +866,7 @@ size_t machines__fprintf_dsos(struct machines *machines, FILE *fp)
size_t machine__fprintf_dsos_buildid(struct machine *m, FILE *fp,
bool (skip)(struct dso *dso, int parm), int parm)
{
- return __dsos__fprintf_buildid(&m->dsos, fp, skip, parm);
+ return dsos__fprintf_buildid(&m->dsos, fp, skip, parm);
}
size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp,
@@ -3208,5 +3208,5 @@ bool machine__is_lock_function(struct machine *machine, u64 addr)
int machine__hit_all_dsos(struct machine *machine)
{
- return __dsos__hit_all(&machine->dsos);
+ return dsos__hit_all(&machine->dsos);
}
--
2.44.0.396.g6e790dbe36-goog
next prev parent reply other threads:[~2024-03-21 16:03 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-21 16:02 [PATCH v2 00/13] dso/dsos memory savings and clean up Ian Rogers
2024-03-21 16:02 ` [PATCH v2 01/13] perf dso: Reorder variables to save space in struct dso Ian Rogers
2024-03-21 20:28 ` Arnaldo Carvalho de Melo
2024-03-21 16:02 ` [PATCH v2 02/13] perf dsos: Attempt to better abstract dsos internals Ian Rogers
2024-03-21 16:02 ` [PATCH v2 03/13] perf dsos: Tidy reference counting and locking Ian Rogers
2024-03-21 16:02 ` [PATCH v2 04/13] perf dsos: Add dsos__for_each_dso Ian Rogers
2024-03-22 20:43 ` Namhyung Kim
2024-03-22 20:54 ` Namhyung Kim
2024-03-21 16:02 ` [PATCH v2 05/13] perf dso: Move dso functions out of dsos Ian Rogers
2024-03-21 16:02 ` Ian Rogers [this message]
2024-03-21 16:02 ` [PATCH v2 07/13] perf dsos: Switch backing storage to array from rbtree/list Ian Rogers
2024-03-21 16:02 ` [PATCH v2 08/13] perf dsos: Remove __dsos__addnew Ian Rogers
2024-03-21 16:02 ` [PATCH v2 09/13] perf dsos: Remove __dsos__findnew_link_by_longname_id Ian Rogers
2024-03-21 16:02 ` [PATCH v2 10/13] perf dsos: Switch hand code to bsearch Ian Rogers
2024-03-21 16:02 ` [PATCH v2 11/13] perf dso: Add reference count checking and accessor functions Ian Rogers
2024-03-21 16:02 ` [PATCH v2 12/13] perf dso: Reference counting related fixes Ian Rogers
2024-03-25 17:22 ` Markus Elfring
2024-03-21 16:03 ` [PATCH v2 13/13] perf dso: Use container_of to avoid a pointer in dso_data Ian Rogers
2024-03-25 21:03 ` [PATCH v2 00/13] dso/dsos memory savings and clean up Namhyung Kim
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=20240321160300.1635121-7-irogers@google.com \
--to=irogers@google.com \
--cc=Markus.Elfring@web.de \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=atrajeev@linux.vnet.ibm.com \
--cc=ben.gainey@arm.com \
--cc=bpf@vger.kernel.org \
--cc=changbin.du@huawei.com \
--cc=chengen.du@canonical.com \
--cc=colin.i.king@gmail.com \
--cc=elfring@users.sourceforge.net \
--cc=ilkka@os.amperecomputing.com \
--cc=james.clark@arm.com \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=kprateek.nayak@amd.com \
--cc=leo.yan@linux.dev \
--cc=liam.howlett@oracle.com \
--cc=lidong@vivo.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mhiramat@kernel.org \
--cc=mingo@redhat.com \
--cc=nabijaczleweli@nabijaczleweli.xyz \
--cc=namhyung@kernel.org \
--cc=ojeda@kernel.org \
--cc=p4ranlee@gmail.com \
--cc=peterz@infradead.org \
--cc=ravi.bangoria@amd.com \
--cc=siyanteng@loongson.cn \
--cc=song@kernel.org \
--cc=sunhaiyong@loongson.cn \
--cc=zhaimingbing@cmss.chinamobile.com \
/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