diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-19 12:41:23 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-19 12:45:08 -0400 |
commit | f869097e884d8cb65b2bb7831ca57b7dffb66fdd (patch) | |
tree | 4a12562d3121571b19d877b5ed2a1749caf1354e /tools/perf | |
parent | f6e1467d8303a397ce40bcfb5f72f97d3ebc768f (diff) |
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>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/util/header.c | 84 | ||||
-rw-r--r-- | tools/perf/util/session.c | 7 | ||||
-rw-r--r-- | tools/perf/util/session.h | 8 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 9 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 1 |
5 files changed, 69 insertions, 40 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 8847bec64c54..1f62435f96c2 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -221,29 +221,38 @@ static int __dsos__write_buildid_table(struct list_head *head, pid_t pid, | |||
221 | return 0; | 221 | return 0; |
222 | } | 222 | } |
223 | 223 | ||
224 | static int machine__write_buildid_table(struct machine *self, int fd) | ||
225 | { | ||
226 | int err; | ||
227 | u16 kmisc = PERF_RECORD_MISC_KERNEL, | ||
228 | umisc = PERF_RECORD_MISC_USER; | ||
229 | |||
230 | if (!machine__is_host(self)) { | ||
231 | kmisc = PERF_RECORD_MISC_GUEST_KERNEL; | ||
232 | umisc = PERF_RECORD_MISC_GUEST_USER; | ||
233 | } | ||
234 | |||
235 | err = __dsos__write_buildid_table(&self->kernel_dsos, self->pid, | ||
236 | kmisc, fd); | ||
237 | if (err == 0) | ||
238 | err = __dsos__write_buildid_table(&self->user_dsos, | ||
239 | self->pid, umisc, fd); | ||
240 | return err; | ||
241 | } | ||
242 | |||
224 | static int dsos__write_buildid_table(struct perf_header *header, int fd) | 243 | static int dsos__write_buildid_table(struct perf_header *header, int fd) |
225 | { | 244 | { |
226 | struct perf_session *session = container_of(header, | 245 | struct perf_session *session = container_of(header, |
227 | struct perf_session, header); | 246 | struct perf_session, header); |
228 | struct rb_node *nd; | 247 | struct rb_node *nd; |
229 | int err = 0; | 248 | int err = machine__write_buildid_table(&session->host_machine, fd); |
230 | u16 kmisc, umisc; | 249 | |
250 | if (err) | ||
251 | return err; | ||
231 | 252 | ||
232 | for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { | 253 | for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { |
233 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | 254 | struct machine *pos = rb_entry(nd, struct machine, rb_node); |
234 | if (machine__is_host(pos)) { | 255 | err = machine__write_buildid_table(pos, fd); |
235 | kmisc = PERF_RECORD_MISC_KERNEL; | ||
236 | umisc = PERF_RECORD_MISC_USER; | ||
237 | } else { | ||
238 | kmisc = PERF_RECORD_MISC_GUEST_KERNEL; | ||
239 | umisc = PERF_RECORD_MISC_GUEST_USER; | ||
240 | } | ||
241 | |||
242 | err = __dsos__write_buildid_table(&pos->kernel_dsos, pos->pid, | ||
243 | kmisc, fd); | ||
244 | if (err == 0) | ||
245 | err = __dsos__write_buildid_table(&pos->user_dsos, | ||
246 | pos->pid, umisc, fd); | ||
247 | if (err) | 256 | if (err) |
248 | break; | 257 | break; |
249 | } | 258 | } |
@@ -363,12 +372,17 @@ static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir) | |||
363 | return err; | 372 | return err; |
364 | } | 373 | } |
365 | 374 | ||
366 | static int dsos__cache_build_ids(struct perf_header *self) | 375 | static int machine__cache_build_ids(struct machine *self, const char *debugdir) |
376 | { | ||
377 | int ret = __dsos__cache_build_ids(&self->kernel_dsos, debugdir); | ||
378 | ret |= __dsos__cache_build_ids(&self->user_dsos, debugdir); | ||
379 | return ret; | ||
380 | } | ||
381 | |||
382 | static int perf_session__cache_build_ids(struct perf_session *self) | ||
367 | { | 383 | { |
368 | struct perf_session *session = container_of(self, | ||
369 | struct perf_session, header); | ||
370 | struct rb_node *nd; | 384 | struct rb_node *nd; |
371 | int ret = 0; | 385 | int ret; |
372 | char debugdir[PATH_MAX]; | 386 | char debugdir[PATH_MAX]; |
373 | 387 | ||
374 | snprintf(debugdir, sizeof(debugdir), "%s/%s", getenv("HOME"), | 388 | snprintf(debugdir, sizeof(debugdir), "%s/%s", getenv("HOME"), |
@@ -377,25 +391,30 @@ static int dsos__cache_build_ids(struct perf_header *self) | |||
377 | if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) | 391 | if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) |
378 | return -1; | 392 | return -1; |
379 | 393 | ||
380 | for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { | 394 | ret = machine__cache_build_ids(&self->host_machine, debugdir); |
395 | |||
396 | for (nd = rb_first(&self->machines); nd; nd = rb_next(nd)) { | ||
381 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | 397 | struct machine *pos = rb_entry(nd, struct machine, rb_node); |
382 | ret |= __dsos__cache_build_ids(&pos->kernel_dsos, debugdir); | 398 | ret |= machine__cache_build_ids(pos, debugdir); |
383 | ret |= __dsos__cache_build_ids(&pos->user_dsos, debugdir); | ||
384 | } | 399 | } |
385 | return ret ? -1 : 0; | 400 | return ret ? -1 : 0; |
386 | } | 401 | } |
387 | 402 | ||
388 | static bool dsos__read_build_ids(struct perf_header *self, bool with_hits) | 403 | static bool machine__read_build_ids(struct machine *self, bool with_hits) |
404 | { | ||
405 | bool ret = __dsos__read_build_ids(&self->kernel_dsos, with_hits); | ||
406 | ret |= __dsos__read_build_ids(&self->user_dsos, with_hits); | ||
407 | return ret; | ||
408 | } | ||
409 | |||
410 | static bool perf_session__read_build_ids(struct perf_session *self, bool with_hits) | ||
389 | { | 411 | { |
390 | bool ret = false; | ||
391 | struct perf_session *session = container_of(self, | ||
392 | struct perf_session, header); | ||
393 | struct rb_node *nd; | 412 | struct rb_node *nd; |
413 | bool ret = machine__read_build_ids(&self->host_machine, with_hits); | ||
394 | 414 | ||
395 | for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { | 415 | for (nd = rb_first(&self->machines); nd; nd = rb_next(nd)) { |
396 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | 416 | struct machine *pos = rb_entry(nd, struct machine, rb_node); |
397 | ret |= __dsos__read_build_ids(&pos->kernel_dsos, with_hits); | 417 | ret |= machine__read_build_ids(pos, with_hits); |
398 | ret |= __dsos__read_build_ids(&pos->user_dsos, with_hits); | ||
399 | } | 418 | } |
400 | 419 | ||
401 | return ret; | 420 | return ret; |
@@ -404,12 +423,14 @@ static bool dsos__read_build_ids(struct perf_header *self, bool with_hits) | |||
404 | static int perf_header__adds_write(struct perf_header *self, int fd) | 423 | static int perf_header__adds_write(struct perf_header *self, int fd) |
405 | { | 424 | { |
406 | int nr_sections; | 425 | int nr_sections; |
426 | struct perf_session *session; | ||
407 | struct perf_file_section *feat_sec; | 427 | struct perf_file_section *feat_sec; |
408 | int sec_size; | 428 | int sec_size; |
409 | u64 sec_start; | 429 | u64 sec_start; |
410 | int idx = 0, err; | 430 | int idx = 0, err; |
411 | 431 | ||
412 | if (dsos__read_build_ids(self, true)) | 432 | session = container_of(self, struct perf_session, header); |
433 | if (perf_session__read_build_ids(session, true)) | ||
413 | perf_header__set_feat(self, HEADER_BUILD_ID); | 434 | perf_header__set_feat(self, HEADER_BUILD_ID); |
414 | 435 | ||
415 | nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS); | 436 | 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) | |||
450 | } | 471 | } |
451 | buildid_sec->size = lseek(fd, 0, SEEK_CUR) - | 472 | buildid_sec->size = lseek(fd, 0, SEEK_CUR) - |
452 | buildid_sec->offset; | 473 | buildid_sec->offset; |
453 | dsos__cache_build_ids(self); | 474 | perf_session__cache_build_ids(session); |
454 | } | 475 | } |
455 | 476 | ||
456 | lseek(fd, sec_start, SEEK_SET); | 477 | lseek(fd, sec_start, SEEK_SET); |
@@ -490,7 +511,6 @@ int perf_header__write(struct perf_header *self, int fd, bool at_exit) | |||
490 | 511 | ||
491 | lseek(fd, sizeof(f_header), SEEK_SET); | 512 | lseek(fd, sizeof(f_header), SEEK_SET); |
492 | 513 | ||
493 | |||
494 | for (i = 0; i < self->attrs; i++) { | 514 | for (i = 0; i < self->attrs; i++) { |
495 | attr = self->attr[i]; | 515 | attr = self->attr[i]; |
496 | 516 | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index e4eaa6d02f57..8f83a1835766 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -895,3 +895,10 @@ size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp) | |||
895 | __dsos__fprintf(&self->host_machine.user_dsos, fp) + | 895 | __dsos__fprintf(&self->host_machine.user_dsos, fp) + |
896 | machines__fprintf_dsos(&self->machines, fp); | 896 | machines__fprintf_dsos(&self->machines, fp); |
897 | } | 897 | } |
898 | |||
899 | size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp, | ||
900 | bool with_hits) | ||
901 | { | ||
902 | size_t ret = machine__fprintf_dsos_buildid(&self->host_machine, fp, with_hits); | ||
903 | return ret + machines__fprintf_dsos_buildid(&self->machines, fp, with_hits); | ||
904 | } | ||
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index e7fce486ebe2..55c6881b218d 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -132,12 +132,8 @@ void perf_session__process_machines(struct perf_session *self, | |||
132 | 132 | ||
133 | size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp); | 133 | size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp); |
134 | 134 | ||
135 | static inline | 135 | size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, |
136 | size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp, | 136 | FILE *fp, bool with_hits); |
137 | bool with_hits) | ||
138 | { | ||
139 | return machines__fprintf_dsos_buildid(&self->machines, fp, with_hits); | ||
140 | } | ||
141 | 137 | ||
142 | static inline | 138 | static inline |
143 | size_t perf_session__fprintf_nr_events(struct perf_session *self, FILE *fp) | 139 | size_t perf_session__fprintf_nr_events(struct perf_session *self, FILE *fp) |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 87d9b1b8b6bb..96bff0e54863 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -1937,6 +1937,12 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, | |||
1937 | return ret; | 1937 | return ret; |
1938 | } | 1938 | } |
1939 | 1939 | ||
1940 | size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits) | ||
1941 | { | ||
1942 | return __dsos__fprintf_buildid(&self->kernel_dsos, fp, with_hits) + | ||
1943 | __dsos__fprintf_buildid(&self->user_dsos, fp, with_hits); | ||
1944 | } | ||
1945 | |||
1940 | size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits) | 1946 | size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits) |
1941 | { | 1947 | { |
1942 | struct rb_node *nd; | 1948 | struct rb_node *nd; |
@@ -1944,8 +1950,7 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_ | |||
1944 | 1950 | ||
1945 | for (nd = rb_first(self); nd; nd = rb_next(nd)) { | 1951 | for (nd = rb_first(self); nd; nd = rb_next(nd)) { |
1946 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | 1952 | struct machine *pos = rb_entry(nd, struct machine, rb_node); |
1947 | ret += __dsos__fprintf_buildid(&pos->kernel_dsos, fp, with_hits); | 1953 | ret += machine__fprintf_dsos_buildid(pos, fp, with_hits); |
1948 | ret += __dsos__fprintf_buildid(&pos->user_dsos, fp, with_hits); | ||
1949 | } | 1954 | } |
1950 | return ret; | 1955 | return ret; |
1951 | } | 1956 | } |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 032469e41876..5d25b5eb1456 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -170,6 +170,7 @@ int machine__load_vmlinux_path(struct machine *self, enum map_type type, | |||
170 | 170 | ||
171 | size_t __dsos__fprintf(struct list_head *head, FILE *fp); | 171 | size_t __dsos__fprintf(struct list_head *head, FILE *fp); |
172 | 172 | ||
173 | size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits); | ||
173 | size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp); | 174 | size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp); |
174 | size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits); | 175 | size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits); |
175 | 176 | ||