mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 07:01:57 +00:00
perf session: Make read_build_id routines look at the host_machine too
The changes made to support host and guest machines in a session, that started when the 'perf kvm' tool was introduced ended up introducing a bug where the host_machine was not having its DSOs traversed for build-id processing. Fix it by moving some methods to the right classes and considering the host_machine when processing build-ids. Reported-by: Tom Zanussi <tzanussi@gmail.com> Reported-by: Stephane Eranian <eranian@google.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
f6e1467d83
commit
f869097e88
@ -221,29 +221,38 @@ static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int machine__write_buildid_table(struct machine *self, int fd)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
u16 kmisc = PERF_RECORD_MISC_KERNEL,
|
||||||
|
umisc = PERF_RECORD_MISC_USER;
|
||||||
|
|
||||||
|
if (!machine__is_host(self)) {
|
||||||
|
kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
|
||||||
|
umisc = PERF_RECORD_MISC_GUEST_USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = __dsos__write_buildid_table(&self->kernel_dsos, self->pid,
|
||||||
|
kmisc, fd);
|
||||||
|
if (err == 0)
|
||||||
|
err = __dsos__write_buildid_table(&self->user_dsos,
|
||||||
|
self->pid, umisc, fd);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int dsos__write_buildid_table(struct perf_header *header, int fd)
|
static int dsos__write_buildid_table(struct perf_header *header, int fd)
|
||||||
{
|
{
|
||||||
struct perf_session *session = container_of(header,
|
struct perf_session *session = container_of(header,
|
||||||
struct perf_session, header);
|
struct perf_session, header);
|
||||||
struct rb_node *nd;
|
struct rb_node *nd;
|
||||||
int err = 0;
|
int err = machine__write_buildid_table(&session->host_machine, fd);
|
||||||
u16 kmisc, umisc;
|
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
|
for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
|
||||||
struct machine *pos = rb_entry(nd, struct machine, rb_node);
|
struct machine *pos = rb_entry(nd, struct machine, rb_node);
|
||||||
if (machine__is_host(pos)) {
|
err = machine__write_buildid_table(pos, fd);
|
||||||
kmisc = PERF_RECORD_MISC_KERNEL;
|
|
||||||
umisc = PERF_RECORD_MISC_USER;
|
|
||||||
} else {
|
|
||||||
kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
|
|
||||||
umisc = PERF_RECORD_MISC_GUEST_USER;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = __dsos__write_buildid_table(&pos->kernel_dsos, pos->pid,
|
|
||||||
kmisc, fd);
|
|
||||||
if (err == 0)
|
|
||||||
err = __dsos__write_buildid_table(&pos->user_dsos,
|
|
||||||
pos->pid, umisc, fd);
|
|
||||||
if (err)
|
if (err)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -363,12 +372,17 @@ static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsos__cache_build_ids(struct perf_header *self)
|
static int machine__cache_build_ids(struct machine *self, const char *debugdir)
|
||||||
|
{
|
||||||
|
int ret = __dsos__cache_build_ids(&self->kernel_dsos, debugdir);
|
||||||
|
ret |= __dsos__cache_build_ids(&self->user_dsos, debugdir);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int perf_session__cache_build_ids(struct perf_session *self)
|
||||||
{
|
{
|
||||||
struct perf_session *session = container_of(self,
|
|
||||||
struct perf_session, header);
|
|
||||||
struct rb_node *nd;
|
struct rb_node *nd;
|
||||||
int ret = 0;
|
int ret;
|
||||||
char debugdir[PATH_MAX];
|
char debugdir[PATH_MAX];
|
||||||
|
|
||||||
snprintf(debugdir, sizeof(debugdir), "%s/%s", getenv("HOME"),
|
snprintf(debugdir, sizeof(debugdir), "%s/%s", getenv("HOME"),
|
||||||
@ -377,25 +391,30 @@ static int dsos__cache_build_ids(struct perf_header *self)
|
|||||||
if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
|
if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
|
ret = machine__cache_build_ids(&self->host_machine, debugdir);
|
||||||
|
|
||||||
|
for (nd = rb_first(&self->machines); nd; nd = rb_next(nd)) {
|
||||||
struct machine *pos = rb_entry(nd, struct machine, rb_node);
|
struct machine *pos = rb_entry(nd, struct machine, rb_node);
|
||||||
ret |= __dsos__cache_build_ids(&pos->kernel_dsos, debugdir);
|
ret |= machine__cache_build_ids(pos, debugdir);
|
||||||
ret |= __dsos__cache_build_ids(&pos->user_dsos, debugdir);
|
|
||||||
}
|
}
|
||||||
return ret ? -1 : 0;
|
return ret ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dsos__read_build_ids(struct perf_header *self, bool with_hits)
|
static bool machine__read_build_ids(struct machine *self, bool with_hits)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = __dsos__read_build_ids(&self->kernel_dsos, with_hits);
|
||||||
struct perf_session *session = container_of(self,
|
ret |= __dsos__read_build_ids(&self->user_dsos, with_hits);
|
||||||
struct perf_session, header);
|
return ret;
|
||||||
struct rb_node *nd;
|
}
|
||||||
|
|
||||||
for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
|
static bool perf_session__read_build_ids(struct perf_session *self, bool with_hits)
|
||||||
|
{
|
||||||
|
struct rb_node *nd;
|
||||||
|
bool ret = machine__read_build_ids(&self->host_machine, with_hits);
|
||||||
|
|
||||||
|
for (nd = rb_first(&self->machines); nd; nd = rb_next(nd)) {
|
||||||
struct machine *pos = rb_entry(nd, struct machine, rb_node);
|
struct machine *pos = rb_entry(nd, struct machine, rb_node);
|
||||||
ret |= __dsos__read_build_ids(&pos->kernel_dsos, with_hits);
|
ret |= machine__read_build_ids(pos, with_hits);
|
||||||
ret |= __dsos__read_build_ids(&pos->user_dsos, with_hits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -404,12 +423,14 @@ static bool dsos__read_build_ids(struct perf_header *self, bool with_hits)
|
|||||||
static int perf_header__adds_write(struct perf_header *self, int fd)
|
static int perf_header__adds_write(struct perf_header *self, int fd)
|
||||||
{
|
{
|
||||||
int nr_sections;
|
int nr_sections;
|
||||||
|
struct perf_session *session;
|
||||||
struct perf_file_section *feat_sec;
|
struct perf_file_section *feat_sec;
|
||||||
int sec_size;
|
int sec_size;
|
||||||
u64 sec_start;
|
u64 sec_start;
|
||||||
int idx = 0, err;
|
int idx = 0, err;
|
||||||
|
|
||||||
if (dsos__read_build_ids(self, true))
|
session = container_of(self, struct perf_session, header);
|
||||||
|
if (perf_session__read_build_ids(session, true))
|
||||||
perf_header__set_feat(self, HEADER_BUILD_ID);
|
perf_header__set_feat(self, HEADER_BUILD_ID);
|
||||||
|
|
||||||
nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
|
nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
|
||||||
@ -450,7 +471,7 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
|
|||||||
}
|
}
|
||||||
buildid_sec->size = lseek(fd, 0, SEEK_CUR) -
|
buildid_sec->size = lseek(fd, 0, SEEK_CUR) -
|
||||||
buildid_sec->offset;
|
buildid_sec->offset;
|
||||||
dsos__cache_build_ids(self);
|
perf_session__cache_build_ids(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
lseek(fd, sec_start, SEEK_SET);
|
lseek(fd, sec_start, SEEK_SET);
|
||||||
@ -490,7 +511,6 @@ int perf_header__write(struct perf_header *self, int fd, bool at_exit)
|
|||||||
|
|
||||||
lseek(fd, sizeof(f_header), SEEK_SET);
|
lseek(fd, sizeof(f_header), SEEK_SET);
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < self->attrs; i++) {
|
for (i = 0; i < self->attrs; i++) {
|
||||||
attr = self->attr[i];
|
attr = self->attr[i];
|
||||||
|
|
||||||
|
@ -895,3 +895,10 @@ size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
|
|||||||
__dsos__fprintf(&self->host_machine.user_dsos, fp) +
|
__dsos__fprintf(&self->host_machine.user_dsos, fp) +
|
||||||
machines__fprintf_dsos(&self->machines, fp);
|
machines__fprintf_dsos(&self->machines, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
|
||||||
|
bool with_hits)
|
||||||
|
{
|
||||||
|
size_t ret = machine__fprintf_dsos_buildid(&self->host_machine, fp, with_hits);
|
||||||
|
return ret + machines__fprintf_dsos_buildid(&self->machines, fp, with_hits);
|
||||||
|
}
|
||||||
|
@ -132,12 +132,8 @@ void perf_session__process_machines(struct perf_session *self,
|
|||||||
|
|
||||||
size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp);
|
size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp);
|
||||||
|
|
||||||
static inline
|
size_t perf_session__fprintf_dsos_buildid(struct perf_session *self,
|
||||||
size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
|
FILE *fp, bool with_hits);
|
||||||
bool with_hits)
|
|
||||||
{
|
|
||||||
return machines__fprintf_dsos_buildid(&self->machines, fp, with_hits);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
size_t perf_session__fprintf_nr_events(struct perf_session *self, FILE *fp)
|
size_t perf_session__fprintf_nr_events(struct perf_session *self, FILE *fp)
|
||||||
|
@ -1937,6 +1937,12 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits)
|
||||||
|
{
|
||||||
|
return __dsos__fprintf_buildid(&self->kernel_dsos, fp, with_hits) +
|
||||||
|
__dsos__fprintf_buildid(&self->user_dsos, fp, with_hits);
|
||||||
|
}
|
||||||
|
|
||||||
size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits)
|
size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits)
|
||||||
{
|
{
|
||||||
struct rb_node *nd;
|
struct rb_node *nd;
|
||||||
@ -1944,8 +1950,7 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_
|
|||||||
|
|
||||||
for (nd = rb_first(self); nd; nd = rb_next(nd)) {
|
for (nd = rb_first(self); nd; nd = rb_next(nd)) {
|
||||||
struct machine *pos = rb_entry(nd, struct machine, rb_node);
|
struct machine *pos = rb_entry(nd, struct machine, rb_node);
|
||||||
ret += __dsos__fprintf_buildid(&pos->kernel_dsos, fp, with_hits);
|
ret += machine__fprintf_dsos_buildid(pos, fp, with_hits);
|
||||||
ret += __dsos__fprintf_buildid(&pos->user_dsos, fp, with_hits);
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -170,6 +170,7 @@ int machine__load_vmlinux_path(struct machine *self, enum map_type type,
|
|||||||
|
|
||||||
size_t __dsos__fprintf(struct list_head *head, FILE *fp);
|
size_t __dsos__fprintf(struct list_head *head, FILE *fp);
|
||||||
|
|
||||||
|
size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits);
|
||||||
size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp);
|
size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp);
|
||||||
size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits);
|
size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user