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_
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)
{
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 */
perf_header__set_feat(&inject->session->header, HEADER_BUILD_ID);
dsos__for_each_with_build_id(dso, &machine->dsos.head) {
ret = synthesize_build_id(inject, dso, gs->machine_pid);
if (ret)
return ret;
}
return 0;
return dsos__for_each_dso(&gs->session->machines.host.dsos,
guest_session__add_build_ids_cb,
gs);
}
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
return write_padded(fd, name, name_len + 1, len);
}
static int machine__write_buildid_table(struct machine *machine,
struct feat_fd *fd)
struct machine__write_buildid_table_cb_args {
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 dso *pos;
u16 kmisc = PERF_RECORD_MISC_KERNEL,
umisc = PERF_RECORD_MISC_USER;
struct machine__write_buildid_table_cb_args *args = data;
const char *name;
size_t name_len;
bool in_kernel = false;
if (!machine__is_host(machine)) {
kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
umisc = PERF_RECORD_MISC_GUEST_USER;
}
if (!dso->has_build_id)
return 0;
dsos__for_each_with_build_id(pos, &machine->dsos.head) {
const char *name;
size_t name_len;
bool in_kernel = false;
if (!dso->hit && !dso__is_vdso(dso))
return 0;
if (!pos->hit && !dso__is_vdso(pos))
continue;
if (dso__is_vdso(dso)) {
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)) {
name = pos->short_name;
name_len = pos->short_name_len;
} 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 = dso->kernel || is_kernel_module(name, PERF_RECORD_MISC_CPUMODE_UNKNOWN);
return write_buildid(name, name_len, &dso->bid, args->machine->pid,
in_kernel ? args->kmisc : args->umisc, args->fd);
}
in_kernel = pos->kernel ||
is_kernel_module(name,
PERF_RECORD_MISC_CPUMODE_UNKNOWN);
err = write_buildid(name, name_len, &pos->bid, machine->pid,
in_kernel ? kmisc : umisc, fd);
if (err)
break;
static int machine__write_buildid_table(struct machine *machine, struct feat_fd *fd)
{
struct machine__write_buildid_table_cb_args args = {
.machine = machine,
.fd = fd,
.kmisc = PERF_RECORD_MISC_KERNEL,
.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,
......
......@@ -433,3 +433,19 @@ struct dso *dsos__find_kernel_dso(struct dsos *dsos)
up_read(&dsos->lock);
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 {
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__exit(struct dsos *dsos);
......@@ -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);
int dsos__for_each_dso(struct dsos *dsos, int (*cb)(struct dso *dso, void *data), void *data);
#endif /* __PERF_DSOS */
......@@ -1562,16 +1562,14 @@ int machine__create_kernel_maps(struct machine *machine)
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;
list_for_each_entry(dso, &machine->dsos.head, node) {
if (dso__is_kcore(dso))
return true;
}
return dso__is_kcore(dso) ? 1 : 0;
}
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,
......@@ -3137,16 +3135,28 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch
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)
{
struct dso *pos;
int err = 0;
struct machine__for_each_dso_cb_args args = {
.machine = machine,
.fn = fn,
.priv = priv,
};
list_for_each_entry(pos, &machine->dsos.head, node) {
if (fn(pos, machine, priv))
err = -1;
}
return err;
return dsos__for_each_dso(&machine->dsos, machine__for_each_dso_cb, &args);
}
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