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/util | |
| 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/util')
| -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 | |||
