aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/map.c
diff options
context:
space:
mode:
authorZhang, Yanmin <yanmin_zhang@linux.intel.com>2010-04-19 01:32:50 -0400
committerAvi Kivity <avi@redhat.com>2010-04-19 05:37:24 -0400
commita1645ce12adb6c9cc9e19d7695466204e3f017fe (patch)
tree5d31aaaf534997e6e9cebc07f38eca35f76986cf /tools/perf/util/map.c
parentff9d07a0e7ce756a183e7c2e483aec452ee6b574 (diff)
perf: 'perf kvm' tool for monitoring guest performance from host
Here is the patch of userspace perf tool. Signed-off-by: Zhang Yanmin <yanmin_zhang@linux.intel.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r--tools/perf/util/map.c139
1 files changed, 137 insertions, 2 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 37913b241bdf..7facd016ec97 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -4,6 +4,7 @@
4#include <stdlib.h> 4#include <stdlib.h>
5#include <string.h> 5#include <string.h>
6#include <stdio.h> 6#include <stdio.h>
7#include <unistd.h>
7#include "map.h" 8#include "map.h"
8 9
9const char *map_type__name[MAP__NR_TYPES] = { 10const char *map_type__name[MAP__NR_TYPES] = {
@@ -37,9 +38,11 @@ void map__init(struct map *self, enum map_type type,
37 self->map_ip = map__map_ip; 38 self->map_ip = map__map_ip;
38 self->unmap_ip = map__unmap_ip; 39 self->unmap_ip = map__unmap_ip;
39 RB_CLEAR_NODE(&self->rb_node); 40 RB_CLEAR_NODE(&self->rb_node);
41 self->groups = NULL;
40} 42}
41 43
42struct map *map__new(u64 start, u64 len, u64 pgoff, u32 pid, char *filename, 44struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
45 u64 pgoff, u32 pid, char *filename,
43 enum map_type type, char *cwd, int cwdlen) 46 enum map_type type, char *cwd, int cwdlen)
44{ 47{
45 struct map *self = malloc(sizeof(*self)); 48 struct map *self = malloc(sizeof(*self));
@@ -66,7 +69,7 @@ struct map *map__new(u64 start, u64 len, u64 pgoff, u32 pid, char *filename,
66 filename = newfilename; 69 filename = newfilename;
67 } 70 }
68 71
69 dso = dsos__findnew(filename); 72 dso = __dsos__findnew(dsos__list, filename);
70 if (dso == NULL) 73 if (dso == NULL)
71 goto out_delete; 74 goto out_delete;
72 75
@@ -242,6 +245,7 @@ void map_groups__init(struct map_groups *self)
242 self->maps[i] = RB_ROOT; 245 self->maps[i] = RB_ROOT;
243 INIT_LIST_HEAD(&self->removed_maps[i]); 246 INIT_LIST_HEAD(&self->removed_maps[i]);
244 } 247 }
248 self->this_kerninfo = NULL;
245} 249}
246 250
247void map_groups__flush(struct map_groups *self) 251void map_groups__flush(struct map_groups *self)
@@ -508,3 +512,134 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
508 512
509 return NULL; 513 return NULL;
510} 514}
515
516struct kernel_info *add_new_kernel_info(struct rb_root *kerninfo_root,
517 pid_t pid, const char *root_dir)
518{
519 struct rb_node **p = &kerninfo_root->rb_node;
520 struct rb_node *parent = NULL;
521 struct kernel_info *kerninfo, *pos;
522
523 kerninfo = malloc(sizeof(struct kernel_info));
524 if (!kerninfo)
525 return NULL;
526
527 kerninfo->pid = pid;
528 map_groups__init(&kerninfo->kmaps);
529 kerninfo->root_dir = strdup(root_dir);
530 RB_CLEAR_NODE(&kerninfo->rb_node);
531 INIT_LIST_HEAD(&kerninfo->dsos__user);
532 INIT_LIST_HEAD(&kerninfo->dsos__kernel);
533 kerninfo->kmaps.this_kerninfo = kerninfo;
534
535 while (*p != NULL) {
536 parent = *p;
537 pos = rb_entry(parent, struct kernel_info, rb_node);
538 if (pid < pos->pid)
539 p = &(*p)->rb_left;
540 else
541 p = &(*p)->rb_right;
542 }
543
544 rb_link_node(&kerninfo->rb_node, parent, p);
545 rb_insert_color(&kerninfo->rb_node, kerninfo_root);
546
547 return kerninfo;
548}
549
550struct kernel_info *kerninfo__find(struct rb_root *kerninfo_root, pid_t pid)
551{
552 struct rb_node **p = &kerninfo_root->rb_node;
553 struct rb_node *parent = NULL;
554 struct kernel_info *kerninfo;
555 struct kernel_info *default_kerninfo = NULL;
556
557 while (*p != NULL) {
558 parent = *p;
559 kerninfo = rb_entry(parent, struct kernel_info, rb_node);
560 if (pid < kerninfo->pid)
561 p = &(*p)->rb_left;
562 else if (pid > kerninfo->pid)
563 p = &(*p)->rb_right;
564 else
565 return kerninfo;
566 if (!kerninfo->pid)
567 default_kerninfo = kerninfo;
568 }
569
570 return default_kerninfo;
571}
572
573struct kernel_info *kerninfo__findhost(struct rb_root *kerninfo_root)
574{
575 struct rb_node **p = &kerninfo_root->rb_node;
576 struct rb_node *parent = NULL;
577 struct kernel_info *kerninfo;
578 pid_t pid = HOST_KERNEL_ID;
579
580 while (*p != NULL) {
581 parent = *p;
582 kerninfo = rb_entry(parent, struct kernel_info, rb_node);
583 if (pid < kerninfo->pid)
584 p = &(*p)->rb_left;
585 else if (pid > kerninfo->pid)
586 p = &(*p)->rb_right;
587 else
588 return kerninfo;
589 }
590
591 return NULL;
592}
593
594struct kernel_info *kerninfo__findnew(struct rb_root *kerninfo_root, pid_t pid)
595{
596 char path[PATH_MAX];
597 const char *root_dir;
598 int ret;
599 struct kernel_info *kerninfo = kerninfo__find(kerninfo_root, pid);
600
601 if (!kerninfo || kerninfo->pid != pid) {
602 if (pid == HOST_KERNEL_ID || pid == DEFAULT_GUEST_KERNEL_ID)
603 root_dir = "";
604 else {
605 if (!symbol_conf.guestmount)
606 goto out;
607 sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
608 ret = access(path, R_OK);
609 if (ret) {
610 pr_err("Can't access file %s\n", path);
611 goto out;
612 }
613 root_dir = path;
614 }
615 kerninfo = add_new_kernel_info(kerninfo_root, pid, root_dir);
616 }
617
618out:
619 return kerninfo;
620}
621
622void kerninfo__process_allkernels(struct rb_root *kerninfo_root,
623 process_kernel_info process,
624 void *data)
625{
626 struct rb_node *nd;
627
628 for (nd = rb_first(kerninfo_root); nd; nd = rb_next(nd)) {
629 struct kernel_info *pos = rb_entry(nd, struct kernel_info,
630 rb_node);
631 process(pos, data);
632 }
633}
634
635char *kern_mmap_name(struct kernel_info *kerninfo, char *buff)
636{
637 if (is_host_kernel(kerninfo))
638 sprintf(buff, "[%s]", "kernel.kallsyms");
639 else if (is_default_guest(kerninfo))
640 sprintf(buff, "[%s]", "guest.kernel.kallsyms");
641 else
642 sprintf(buff, "[%s.%d]", "guest.kernel.kallsyms", kerninfo->pid);
643
644 return buff;
645}