diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-04-30 03:58:05 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-04-30 03:58:05 -0400 |
commit | bc4b473f1aa2ef785ccfd890a24a1de5a6660f98 (patch) | |
tree | 77bbea692517ae4723b575631222bf715b4a1eb1 /tools/perf/util/map.c | |
parent | 3ca50496c2677a2b3fdd3ede86660fd1433beac6 (diff) | |
parent | 1c6a800cde3b818fd8320b5d402f2d77d2948c00 (diff) |
Merge branch 'perf' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r-- | tools/perf/util/map.c | 121 |
1 files changed, 64 insertions, 57 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 7facd016ec97..44a4df68b3cf 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -245,7 +245,7 @@ void map_groups__init(struct map_groups *self) | |||
245 | self->maps[i] = RB_ROOT; | 245 | self->maps[i] = RB_ROOT; |
246 | INIT_LIST_HEAD(&self->removed_maps[i]); | 246 | INIT_LIST_HEAD(&self->removed_maps[i]); |
247 | } | 247 | } |
248 | self->this_kerninfo = NULL; | 248 | self->machine = NULL; |
249 | } | 249 | } |
250 | 250 | ||
251 | void map_groups__flush(struct map_groups *self) | 251 | void map_groups__flush(struct map_groups *self) |
@@ -513,133 +513,140 @@ struct map *maps__find(struct rb_root *maps, u64 ip) | |||
513 | return NULL; | 513 | return NULL; |
514 | } | 514 | } |
515 | 515 | ||
516 | struct kernel_info *add_new_kernel_info(struct rb_root *kerninfo_root, | 516 | int machine__init(struct machine *self, const char *root_dir, pid_t pid) |
517 | pid_t pid, const char *root_dir) | ||
518 | { | 517 | { |
519 | struct rb_node **p = &kerninfo_root->rb_node; | 518 | map_groups__init(&self->kmaps); |
519 | RB_CLEAR_NODE(&self->rb_node); | ||
520 | INIT_LIST_HEAD(&self->user_dsos); | ||
521 | INIT_LIST_HEAD(&self->kernel_dsos); | ||
522 | |||
523 | self->kmaps.machine = self; | ||
524 | self->pid = pid; | ||
525 | self->root_dir = strdup(root_dir); | ||
526 | return self->root_dir == NULL ? -ENOMEM : 0; | ||
527 | } | ||
528 | |||
529 | struct machine *machines__add(struct rb_root *self, pid_t pid, | ||
530 | const char *root_dir) | ||
531 | { | ||
532 | struct rb_node **p = &self->rb_node; | ||
520 | struct rb_node *parent = NULL; | 533 | struct rb_node *parent = NULL; |
521 | struct kernel_info *kerninfo, *pos; | 534 | struct machine *pos, *machine = malloc(sizeof(*machine)); |
522 | 535 | ||
523 | kerninfo = malloc(sizeof(struct kernel_info)); | 536 | if (!machine) |
524 | if (!kerninfo) | ||
525 | return NULL; | 537 | return NULL; |
526 | 538 | ||
527 | kerninfo->pid = pid; | 539 | if (machine__init(machine, root_dir, pid) != 0) { |
528 | map_groups__init(&kerninfo->kmaps); | 540 | free(machine); |
529 | kerninfo->root_dir = strdup(root_dir); | 541 | return NULL; |
530 | RB_CLEAR_NODE(&kerninfo->rb_node); | 542 | } |
531 | INIT_LIST_HEAD(&kerninfo->dsos__user); | ||
532 | INIT_LIST_HEAD(&kerninfo->dsos__kernel); | ||
533 | kerninfo->kmaps.this_kerninfo = kerninfo; | ||
534 | 543 | ||
535 | while (*p != NULL) { | 544 | while (*p != NULL) { |
536 | parent = *p; | 545 | parent = *p; |
537 | pos = rb_entry(parent, struct kernel_info, rb_node); | 546 | pos = rb_entry(parent, struct machine, rb_node); |
538 | if (pid < pos->pid) | 547 | if (pid < pos->pid) |
539 | p = &(*p)->rb_left; | 548 | p = &(*p)->rb_left; |
540 | else | 549 | else |
541 | p = &(*p)->rb_right; | 550 | p = &(*p)->rb_right; |
542 | } | 551 | } |
543 | 552 | ||
544 | rb_link_node(&kerninfo->rb_node, parent, p); | 553 | rb_link_node(&machine->rb_node, parent, p); |
545 | rb_insert_color(&kerninfo->rb_node, kerninfo_root); | 554 | rb_insert_color(&machine->rb_node, self); |
546 | 555 | ||
547 | return kerninfo; | 556 | return machine; |
548 | } | 557 | } |
549 | 558 | ||
550 | struct kernel_info *kerninfo__find(struct rb_root *kerninfo_root, pid_t pid) | 559 | struct machine *machines__find(struct rb_root *self, pid_t pid) |
551 | { | 560 | { |
552 | struct rb_node **p = &kerninfo_root->rb_node; | 561 | struct rb_node **p = &self->rb_node; |
553 | struct rb_node *parent = NULL; | 562 | struct rb_node *parent = NULL; |
554 | struct kernel_info *kerninfo; | 563 | struct machine *machine; |
555 | struct kernel_info *default_kerninfo = NULL; | 564 | struct machine *default_machine = NULL; |
556 | 565 | ||
557 | while (*p != NULL) { | 566 | while (*p != NULL) { |
558 | parent = *p; | 567 | parent = *p; |
559 | kerninfo = rb_entry(parent, struct kernel_info, rb_node); | 568 | machine = rb_entry(parent, struct machine, rb_node); |
560 | if (pid < kerninfo->pid) | 569 | if (pid < machine->pid) |
561 | p = &(*p)->rb_left; | 570 | p = &(*p)->rb_left; |
562 | else if (pid > kerninfo->pid) | 571 | else if (pid > machine->pid) |
563 | p = &(*p)->rb_right; | 572 | p = &(*p)->rb_right; |
564 | else | 573 | else |
565 | return kerninfo; | 574 | return machine; |
566 | if (!kerninfo->pid) | 575 | if (!machine->pid) |
567 | default_kerninfo = kerninfo; | 576 | default_machine = machine; |
568 | } | 577 | } |
569 | 578 | ||
570 | return default_kerninfo; | 579 | return default_machine; |
571 | } | 580 | } |
572 | 581 | ||
573 | struct kernel_info *kerninfo__findhost(struct rb_root *kerninfo_root) | 582 | /* |
583 | * FIXME: Why repeatedly search for this? | ||
584 | */ | ||
585 | struct machine *machines__find_host(struct rb_root *self) | ||
574 | { | 586 | { |
575 | struct rb_node **p = &kerninfo_root->rb_node; | 587 | struct rb_node **p = &self->rb_node; |
576 | struct rb_node *parent = NULL; | 588 | struct rb_node *parent = NULL; |
577 | struct kernel_info *kerninfo; | 589 | struct machine *machine; |
578 | pid_t pid = HOST_KERNEL_ID; | 590 | pid_t pid = HOST_KERNEL_ID; |
579 | 591 | ||
580 | while (*p != NULL) { | 592 | while (*p != NULL) { |
581 | parent = *p; | 593 | parent = *p; |
582 | kerninfo = rb_entry(parent, struct kernel_info, rb_node); | 594 | machine = rb_entry(parent, struct machine, rb_node); |
583 | if (pid < kerninfo->pid) | 595 | if (pid < machine->pid) |
584 | p = &(*p)->rb_left; | 596 | p = &(*p)->rb_left; |
585 | else if (pid > kerninfo->pid) | 597 | else if (pid > machine->pid) |
586 | p = &(*p)->rb_right; | 598 | p = &(*p)->rb_right; |
587 | else | 599 | else |
588 | return kerninfo; | 600 | return machine; |
589 | } | 601 | } |
590 | 602 | ||
591 | return NULL; | 603 | return NULL; |
592 | } | 604 | } |
593 | 605 | ||
594 | struct kernel_info *kerninfo__findnew(struct rb_root *kerninfo_root, pid_t pid) | 606 | struct machine *machines__findnew(struct rb_root *self, pid_t pid) |
595 | { | 607 | { |
596 | char path[PATH_MAX]; | 608 | char path[PATH_MAX]; |
597 | const char *root_dir; | 609 | const char *root_dir; |
598 | int ret; | 610 | struct machine *machine = machines__find(self, pid); |
599 | struct kernel_info *kerninfo = kerninfo__find(kerninfo_root, pid); | ||
600 | 611 | ||
601 | if (!kerninfo || kerninfo->pid != pid) { | 612 | if (!machine || machine->pid != pid) { |
602 | if (pid == HOST_KERNEL_ID || pid == DEFAULT_GUEST_KERNEL_ID) | 613 | if (pid == HOST_KERNEL_ID || pid == DEFAULT_GUEST_KERNEL_ID) |
603 | root_dir = ""; | 614 | root_dir = ""; |
604 | else { | 615 | else { |
605 | if (!symbol_conf.guestmount) | 616 | if (!symbol_conf.guestmount) |
606 | goto out; | 617 | goto out; |
607 | sprintf(path, "%s/%d", symbol_conf.guestmount, pid); | 618 | sprintf(path, "%s/%d", symbol_conf.guestmount, pid); |
608 | ret = access(path, R_OK); | 619 | if (access(path, R_OK)) { |
609 | if (ret) { | ||
610 | pr_err("Can't access file %s\n", path); | 620 | pr_err("Can't access file %s\n", path); |
611 | goto out; | 621 | goto out; |
612 | } | 622 | } |
613 | root_dir = path; | 623 | root_dir = path; |
614 | } | 624 | } |
615 | kerninfo = add_new_kernel_info(kerninfo_root, pid, root_dir); | 625 | machine = machines__add(self, pid, root_dir); |
616 | } | 626 | } |
617 | 627 | ||
618 | out: | 628 | out: |
619 | return kerninfo; | 629 | return machine; |
620 | } | 630 | } |
621 | 631 | ||
622 | void kerninfo__process_allkernels(struct rb_root *kerninfo_root, | 632 | void machines__process(struct rb_root *self, machine__process_t process, void *data) |
623 | process_kernel_info process, | ||
624 | void *data) | ||
625 | { | 633 | { |
626 | struct rb_node *nd; | 634 | struct rb_node *nd; |
627 | 635 | ||
628 | for (nd = rb_first(kerninfo_root); nd; nd = rb_next(nd)) { | 636 | for (nd = rb_first(self); nd; nd = rb_next(nd)) { |
629 | struct kernel_info *pos = rb_entry(nd, struct kernel_info, | 637 | struct machine *pos = rb_entry(nd, struct machine, rb_node); |
630 | rb_node); | ||
631 | process(pos, data); | 638 | process(pos, data); |
632 | } | 639 | } |
633 | } | 640 | } |
634 | 641 | ||
635 | char *kern_mmap_name(struct kernel_info *kerninfo, char *buff) | 642 | char *machine__mmap_name(struct machine *self, char *bf, size_t size) |
636 | { | 643 | { |
637 | if (is_host_kernel(kerninfo)) | 644 | if (machine__is_host(self)) |
638 | sprintf(buff, "[%s]", "kernel.kallsyms"); | 645 | snprintf(bf, size, "[%s]", "kernel.kallsyms"); |
639 | else if (is_default_guest(kerninfo)) | 646 | else if (machine__is_default_guest(self)) |
640 | sprintf(buff, "[%s]", "guest.kernel.kallsyms"); | 647 | snprintf(bf, size, "[%s]", "guest.kernel.kallsyms"); |
641 | else | 648 | else |
642 | sprintf(buff, "[%s.%d]", "guest.kernel.kallsyms", kerninfo->pid); | 649 | snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms", self->pid); |
643 | 650 | ||
644 | return buff; | 651 | return bf; |
645 | } | 652 | } |