Commit 73f3fea2 authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo

perf dsos: Introduce dsos__for_each_dso()

To better abstract the dsos internals, introduce dsos__for_each_dso that
does a callback on each dso.

This also means the read lock can be correctly held.
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Anne Macedo <retpolanne@posteo.net>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ben Gainey <ben.gainey@arm.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: Chengen Du <chengen.du@canonical.com>
Cc: Colin Ian King <colin.i.king@gmail.com>
Cc: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Li Dong <lidong@vivo.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Markus Elfring <Markus.Elfring@web.de>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paran Lee <p4ranlee@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Song Liu <song@kernel.org>
Cc: Sun Haiyong <sunhaiyong@loongson.cn>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Cc: Yanteng Si <siyanteng@loongson.cn>
Cc: Yicong Yang <yangyicong@hisilicon.com>
Cc: zhaimingbing <zhaimingbing@cmss.chinamobile.com>
Link: https://lore.kernel.org/r/20240410064214.2755936-4-irogers@google.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent f649ed80
...@@ -1187,23 +1187,28 @@ static int synthesize_build_id(struct perf_inject *inject, struct dso *dso, pid_ ...@@ -1187,23 +1187,28 @@ static int synthesize_build_id(struct perf_inject *inject, struct dso *dso, pid_
process_build_id, machine); process_build_id, machine);
} }
static int guest_session__add_build_ids_cb(struct dso *dso, void *data)
{
struct guest_session *gs = data;
struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session);
if (!dso->has_build_id)
return 0;
return synthesize_build_id(inject, dso, gs->machine_pid);
}
static int guest_session__add_build_ids(struct guest_session *gs) static int guest_session__add_build_ids(struct guest_session *gs)
{ {
struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session); struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session);
struct machine *machine = &gs->session->machines.host;
struct dso *dso;
int ret;
/* Build IDs will be put in the Build ID feature section */ /* Build IDs will be put in the Build ID feature section */
perf_header__set_feat(&inject->session->header, HEADER_BUILD_ID); perf_header__set_feat(&inject->session->header, HEADER_BUILD_ID);
dsos__for_each_with_build_id(dso, &machine->dsos.head) { return dsos__for_each_dso(&gs->session->machines.host.dsos,
ret = synthesize_build_id(inject, dso, gs->machine_pid); guest_session__add_build_ids_cb,
if (ret) gs);
return ret;
}
return 0;
} }
static int guest_session__ksymbol_event(struct perf_tool *tool, static int guest_session__ksymbol_event(struct perf_tool *tool,
......
...@@ -327,48 +327,56 @@ static int write_buildid(const char *name, size_t name_len, struct build_id *bid ...@@ -327,48 +327,56 @@ static int write_buildid(const char *name, size_t name_len, struct build_id *bid
return write_padded(fd, name, name_len + 1, len); return write_padded(fd, name, name_len + 1, len);
} }
static int machine__write_buildid_table(struct machine *machine, struct machine__write_buildid_table_cb_args {
struct feat_fd *fd) struct machine *machine;
struct feat_fd *fd;
u16 kmisc, umisc;
};
static int machine__write_buildid_table_cb(struct dso *dso, void *data)
{ {
int err = 0; struct machine__write_buildid_table_cb_args *args = data;
struct dso *pos; const char *name;
u16 kmisc = PERF_RECORD_MISC_KERNEL, size_t name_len;
umisc = PERF_RECORD_MISC_USER; bool in_kernel = false;
if (!machine__is_host(machine)) { if (!dso->has_build_id)
kmisc = PERF_RECORD_MISC_GUEST_KERNEL; return 0;
umisc = PERF_RECORD_MISC_GUEST_USER;
}
dsos__for_each_with_build_id(pos, &machine->dsos.head) { if (!dso->hit && !dso__is_vdso(dso))
const char *name; return 0;
size_t name_len;
bool in_kernel = false;
if (!pos->hit && !dso__is_vdso(pos)) if (dso__is_vdso(dso)) {
continue; name = dso->short_name;
name_len = dso->short_name_len;
} else if (dso__is_kcore(dso)) {
name = args->machine->mmap_name;
name_len = strlen(name);
} else {
name = dso->long_name;
name_len = dso->long_name_len;
}
if (dso__is_vdso(pos)) { in_kernel = dso->kernel || is_kernel_module(name, PERF_RECORD_MISC_CPUMODE_UNKNOWN);
name = pos->short_name; return write_buildid(name, name_len, &dso->bid, args->machine->pid,
name_len = pos->short_name_len; in_kernel ? args->kmisc : args->umisc, args->fd);
} else if (dso__is_kcore(pos)) { }
name = machine->mmap_name;
name_len = strlen(name);
} else {
name = pos->long_name;
name_len = pos->long_name_len;
}
in_kernel = pos->kernel || static int machine__write_buildid_table(struct machine *machine, struct feat_fd *fd)
is_kernel_module(name, {
PERF_RECORD_MISC_CPUMODE_UNKNOWN); struct machine__write_buildid_table_cb_args args = {
err = write_buildid(name, name_len, &pos->bid, machine->pid, .machine = machine,
in_kernel ? kmisc : umisc, fd); .fd = fd,
if (err) .kmisc = PERF_RECORD_MISC_KERNEL,
break; .umisc = PERF_RECORD_MISC_USER,
};
if (!machine__is_host(machine)) {
args.kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
args.umisc = PERF_RECORD_MISC_GUEST_USER;
} }
return err; return dsos__for_each_dso(&machine->dsos, machine__write_buildid_table_cb, &args);
} }
int perf_session__write_buildid_table(struct perf_session *session, int perf_session__write_buildid_table(struct perf_session *session,
......
...@@ -433,3 +433,19 @@ struct dso *dsos__find_kernel_dso(struct dsos *dsos) ...@@ -433,3 +433,19 @@ struct dso *dsos__find_kernel_dso(struct dsos *dsos)
up_read(&dsos->lock); up_read(&dsos->lock);
return res; return res;
} }
int dsos__for_each_dso(struct dsos *dsos, int (*cb)(struct dso *dso, void *data), void *data)
{
struct dso *dso;
down_read(&dsos->lock);
list_for_each_entry(dso, &dsos->head, node) {
int err;
err = cb(dso, data);
if (err)
return err;
}
up_read(&dsos->lock);
return 0;
}
...@@ -23,12 +23,6 @@ struct dsos { ...@@ -23,12 +23,6 @@ struct dsos {
struct rw_semaphore lock; struct rw_semaphore lock;
}; };
#define dsos__for_each_with_build_id(pos, head) \
list_for_each_entry(pos, head, node) \
if (!pos->has_build_id) \
continue; \
else
void dsos__init(struct dsos *dsos); void dsos__init(struct dsos *dsos);
void dsos__exit(struct dsos *dsos); void dsos__exit(struct dsos *dsos);
...@@ -55,4 +49,6 @@ struct dso *dsos__findnew_module_dso(struct dsos *dsos, struct machine *machine, ...@@ -55,4 +49,6 @@ struct dso *dsos__findnew_module_dso(struct dsos *dsos, struct machine *machine,
struct dso *dsos__find_kernel_dso(struct dsos *dsos); struct dso *dsos__find_kernel_dso(struct dsos *dsos);
int dsos__for_each_dso(struct dsos *dsos, int (*cb)(struct dso *dso, void *data), void *data);
#endif /* __PERF_DSOS */ #endif /* __PERF_DSOS */
...@@ -1562,16 +1562,14 @@ int machine__create_kernel_maps(struct machine *machine) ...@@ -1562,16 +1562,14 @@ int machine__create_kernel_maps(struct machine *machine)
return ret; return ret;
} }
static bool machine__uses_kcore(struct machine *machine) static int machine__uses_kcore_cb(struct dso *dso, void *data __maybe_unused)
{ {
struct dso *dso; return dso__is_kcore(dso) ? 1 : 0;
}
list_for_each_entry(dso, &machine->dsos.head, node) {
if (dso__is_kcore(dso))
return true;
}
return false; static bool machine__uses_kcore(struct machine *machine)
{
return dsos__for_each_dso(&machine->dsos, machine__uses_kcore_cb, NULL) != 0 ? true : false;
} }
static bool perf_event__is_extra_kernel_mmap(struct machine *machine, static bool perf_event__is_extra_kernel_mmap(struct machine *machine,
...@@ -3137,16 +3135,28 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch ...@@ -3137,16 +3135,28 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch
return sym->name; return sym->name;
} }
struct machine__for_each_dso_cb_args {
struct machine *machine;
machine__dso_t fn;
void *priv;
};
static int machine__for_each_dso_cb(struct dso *dso, void *data)
{
struct machine__for_each_dso_cb_args *args = data;
return args->fn(dso, args->machine, args->priv);
}
int machine__for_each_dso(struct machine *machine, machine__dso_t fn, void *priv) int machine__for_each_dso(struct machine *machine, machine__dso_t fn, void *priv)
{ {
struct dso *pos; struct machine__for_each_dso_cb_args args = {
int err = 0; .machine = machine,
.fn = fn,
.priv = priv,
};
list_for_each_entry(pos, &machine->dsos.head, node) { return dsos__for_each_dso(&machine->dsos, machine__for_each_dso_cb, &args);
if (fn(pos, machine, priv))
err = -1;
}
return err;
} }
int machine__for_each_kernel_map(struct machine *machine, machine__map_t fn, void *priv) int machine__for_each_kernel_map(struct machine *machine, machine__map_t fn, void *priv)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment