Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f869097e authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

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: default avatarTom Zanussi <tzanussi@gmail.com>
Reported-by: default avatarStephane 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent f6e1467d
Loading
Loading
Loading
Loading
+52 −32
Original line number Diff line number Diff line
@@ -221,29 +221,38 @@ static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
	return 0;
}

static int dsos__write_buildid_table(struct perf_header *header, int fd)
static int machine__write_buildid_table(struct machine *self, int fd)
{
	struct perf_session *session = container_of(header,
			struct perf_session, header);
	struct rb_node *nd;
	int err = 0;
	u16 kmisc, umisc;

	for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
		struct machine *pos = rb_entry(nd, struct machine, rb_node);
		if (machine__is_host(pos)) {
			kmisc = PERF_RECORD_MISC_KERNEL;
	int err;
	u16 kmisc = PERF_RECORD_MISC_KERNEL,
	    umisc = PERF_RECORD_MISC_USER;
		} else {

	if (!machine__is_host(self)) {
		kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
		umisc = PERF_RECORD_MISC_GUEST_USER;
	}

		err = __dsos__write_buildid_table(&pos->kernel_dsos, pos->pid,
	err = __dsos__write_buildid_table(&self->kernel_dsos, self->pid,
					  kmisc, fd);
	if (err == 0)
			err = __dsos__write_buildid_table(&pos->user_dsos,
							  pos->pid, umisc, fd);
		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)
{
	struct perf_session *session = container_of(header,
			struct perf_session, header);
	struct rb_node *nd;
	int err = machine__write_buildid_table(&session->host_machine, fd);

	if (err)
		return err;

	for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
		struct machine *pos = rb_entry(nd, struct machine, rb_node);
		err = machine__write_buildid_table(pos, fd);
		if (err)
			break;
	}
@@ -363,12 +372,17 @@ static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
	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;
	int ret = 0;
	int ret;
	char debugdir[PATH_MAX];

	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)
		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);
		ret |= __dsos__cache_build_ids(&pos->kernel_dsos, debugdir);
		ret |= __dsos__cache_build_ids(&pos->user_dsos, debugdir);
		ret |= machine__cache_build_ids(pos, debugdir);
	}
	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 = __dsos__read_build_ids(&self->kernel_dsos, with_hits);
	ret |= __dsos__read_build_ids(&self->user_dsos, with_hits);
	return ret;
}

static bool perf_session__read_build_ids(struct perf_session *self, bool with_hits)
{
	bool ret = false;
	struct perf_session *session = container_of(self,
			struct perf_session, header);
	struct rb_node *nd;
	bool ret = machine__read_build_ids(&self->host_machine, with_hits);

	for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
	for (nd = rb_first(&self->machines); nd; nd = rb_next(nd)) {
		struct machine *pos = rb_entry(nd, struct machine, rb_node);
		ret |= __dsos__read_build_ids(&pos->kernel_dsos, with_hits);
		ret |= __dsos__read_build_ids(&pos->user_dsos, with_hits);
		ret |= machine__read_build_ids(pos, with_hits);
	}

	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)
{
	int nr_sections;
	struct perf_session *session;
	struct perf_file_section *feat_sec;
	int sec_size;
	u64 sec_start;
	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);

	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->offset;
		dsos__cache_build_ids(self);
		perf_session__cache_build_ids(session);
	}

	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);


	for (i = 0; i < self->attrs; i++) {
		attr = self->attr[i];

+7 −0
Original line number Diff line number Diff line
@@ -895,3 +895,10 @@ size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
	       __dsos__fprintf(&self->host_machine.user_dsos, 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);
}
+2 −6
Original line number Diff line number Diff line
@@ -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);

static inline
size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
					  bool with_hits)
{
	return machines__fprintf_dsos_buildid(&self->machines, fp, with_hits);
}
size_t perf_session__fprintf_dsos_buildid(struct perf_session *self,
					  FILE *fp, bool with_hits);

static inline
size_t perf_session__fprintf_nr_events(struct perf_session *self, FILE *fp)
+7 −2
Original line number Diff line number Diff line
@@ -1937,6 +1937,12 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
	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)
{
	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)) {
		struct machine *pos = rb_entry(nd, struct machine, rb_node);
		ret += __dsos__fprintf_buildid(&pos->kernel_dsos, fp, with_hits);
		ret += __dsos__fprintf_buildid(&pos->user_dsos, fp, with_hits);
		ret += machine__fprintf_dsos_buildid(pos, fp, with_hits);
	}
	return ret;
}
+1 −0
Original line number Diff line number Diff line
@@ -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 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_buildid(struct rb_root *self, FILE *fp, bool with_hits);