aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-04-27 20:20:43 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-04-27 20:21:18 -0400
commitd28c62232e50eab202bcd3f19b5c7a25b8b900b6 (patch)
tree544aca2fe1c7a6c813cf2bf319a8ceb4d212b649 /tools/perf/util
parent48ea8f5470aa6f35244d1b218316705ea88c0259 (diff)
perf machine: Adopt some map_groups functions
Those functions operated on members now grouped in 'struct machine', so move those methods to this new class. The changes made to 'perf probe' shows that using this abstraction inserting probes on guests almost got supported for free. Cc: Avi Kivity <avi@redhat.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Masami Hiramatsu <mhiramat@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Zhang, Yanmin <yanmin_zhang@linux.intel.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/event.c9
-rw-r--r--tools/perf/util/map.c24
-rw-r--r--tools/perf/util/map.h12
-rw-r--r--tools/perf/util/probe-event.c20
-rw-r--r--tools/perf/util/session.c7
-rw-r--r--tools/perf/util/symbol.c71
-rw-r--r--tools/perf/util/symbol.h8
7 files changed, 73 insertions, 78 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 7400e5147e13..1757b0ffeaa9 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -429,9 +429,8 @@ static int event__process_kernel_mmap(event_t *self,
429 } else 429 } else
430 strcpy(short_module_name, self->mmap.filename); 430 strcpy(short_module_name, self->mmap.filename);
431 431
432 map = map_groups__new_module(&machine->kmaps, 432 map = machine__new_module(machine, self->mmap.start,
433 self->mmap.start, 433 self->mmap.filename);
434 self->mmap.filename, machine);
435 if (map == NULL) 434 if (map == NULL)
436 goto out_problem; 435 goto out_problem;
437 436
@@ -454,9 +453,7 @@ static int event__process_kernel_mmap(event_t *self,
454 goto out_problem; 453 goto out_problem;
455 454
456 kernel->kernel = kernel_type; 455 kernel->kernel = kernel_type;
457 if (__map_groups__create_kernel_maps(&machine->kmaps, 456 if (__machine__create_kernel_maps(machine, kernel) < 0)
458 machine->vmlinux_maps,
459 kernel) < 0)
460 goto out_problem; 457 goto out_problem;
461 458
462 event_set_kernel_mmap_len(machine->vmlinux_maps, self); 459 event_set_kernel_mmap_len(machine->vmlinux_maps, self);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index ee25ee91504b..44a4df68b3cf 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -513,6 +513,19 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
513 return NULL; 513 return NULL;
514} 514}
515 515
516int machine__init(struct machine *self, const char *root_dir, pid_t pid)
517{
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
516struct machine *machines__add(struct rb_root *self, pid_t pid, 529struct machine *machines__add(struct rb_root *self, pid_t pid,
517 const char *root_dir) 530 const char *root_dir)
518{ 531{
@@ -523,13 +536,10 @@ struct machine *machines__add(struct rb_root *self, pid_t pid,
523 if (!machine) 536 if (!machine)
524 return NULL; 537 return NULL;
525 538
526 machine->pid = pid; 539 if (machine__init(machine, root_dir, pid) != 0) {
527 map_groups__init(&machine->kmaps); 540 free(machine);
528 machine->root_dir = strdup(root_dir); 541 return NULL;
529 RB_CLEAR_NODE(&machine->rb_node); 542 }
530 INIT_LIST_HEAD(&machine->user_dsos);
531 INIT_LIST_HEAD(&machine->kernel_dsos);
532 machine->kmaps.machine = machine;
533 543
534 while (*p != NULL) { 544 while (*p != NULL) {
535 parent = *p; 545 parent = *p;
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 6fabad1fd025..881dba4f8203 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -134,6 +134,7 @@ struct machine *machines__find_host(struct rb_root *self);
134struct machine *machines__find(struct rb_root *self, pid_t pid); 134struct machine *machines__find(struct rb_root *self, pid_t pid);
135struct machine *machines__findnew(struct rb_root *self, pid_t pid); 135struct machine *machines__findnew(struct rb_root *self, pid_t pid);
136char *machine__mmap_name(struct machine *self, char *bf, size_t size); 136char *machine__mmap_name(struct machine *self, char *bf, size_t size);
137int machine__init(struct machine *self, const char *root_dir, pid_t pid);
137 138
138/* 139/*
139 * Default guest kernel is defined by parameter --guestkallsyms 140 * Default guest kernel is defined by parameter --guestkallsyms
@@ -172,11 +173,11 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
172 struct map **mapp, 173 struct map **mapp,
173 symbol_filter_t filter); 174 symbol_filter_t filter);
174 175
175static inline 176static inline struct symbol *machine__find_function(struct machine *self,
176struct symbol *map_groups__find_function(struct map_groups *self, u64 addr, 177 u64 addr, struct map **mapp,
177 struct map **mapp, symbol_filter_t filter) 178 symbol_filter_t filter)
178{ 179{
179 return map_groups__find_symbol(self, MAP__FUNCTION, addr, mapp, filter); 180 return map_groups__find_symbol(&self->kmaps, MAP__FUNCTION, addr, mapp, filter);
180} 181}
181 182
182static inline 183static inline
@@ -192,8 +193,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
192 193
193struct map *map_groups__find_by_name(struct map_groups *self, 194struct map *map_groups__find_by_name(struct map_groups *self,
194 enum map_type type, const char *name); 195 enum map_type type, const char *name);
195struct map *map_groups__new_module(struct map_groups *self, u64 start, 196struct map *machine__new_module(struct machine *self, u64 start, const char *filename);
196 const char *filename, struct machine *machine);
197 197
198void map_groups__flush(struct map_groups *self); 198void map_groups__flush(struct map_groups *self);
199 199
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 9ded38ced234..914c67095d96 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -72,8 +72,7 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
72} 72}
73 73
74static char *synthesize_perf_probe_point(struct perf_probe_point *pp); 74static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
75static struct map_groups kmap_groups; 75static struct machine machine;
76static struct map *kmaps[MAP__NR_TYPES];
77 76
78/* Initialize symbol maps and path of vmlinux */ 77/* Initialize symbol maps and path of vmlinux */
79static int init_vmlinux(void) 78static int init_vmlinux(void)
@@ -92,12 +91,15 @@ static int init_vmlinux(void)
92 goto out; 91 goto out;
93 } 92 }
94 93
94 ret = machine__init(&machine, "/", 0);
95 if (ret < 0)
96 goto out;
97
95 kernel = dso__new_kernel(symbol_conf.vmlinux_name); 98 kernel = dso__new_kernel(symbol_conf.vmlinux_name);
96 if (kernel == NULL) 99 if (kernel == NULL)
97 die("Failed to create kernel dso."); 100 die("Failed to create kernel dso.");
98 101
99 map_groups__init(&kmap_groups); 102 ret = __machine__create_kernel_maps(&machine, kernel);
100 ret = __map_groups__create_kernel_maps(&kmap_groups, kmaps, kernel);
101 if (ret < 0) 103 if (ret < 0)
102 pr_debug("Failed to create kernel maps.\n"); 104 pr_debug("Failed to create kernel maps.\n");
103 105
@@ -110,12 +112,12 @@ out:
110#ifdef DWARF_SUPPORT 112#ifdef DWARF_SUPPORT
111static int open_vmlinux(void) 113static int open_vmlinux(void)
112{ 114{
113 if (map__load(kmaps[MAP__FUNCTION], NULL) < 0) { 115 if (map__load(machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) {
114 pr_debug("Failed to load kernel map.\n"); 116 pr_debug("Failed to load kernel map.\n");
115 return -EINVAL; 117 return -EINVAL;
116 } 118 }
117 pr_debug("Try to open %s\n", kmaps[MAP__FUNCTION]->dso->long_name); 119 pr_debug("Try to open %s\n", machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name);
118 return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY); 120 return open(machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
119} 121}
120 122
121/* Convert trace point to probe point with debuginfo */ 123/* Convert trace point to probe point with debuginfo */
@@ -125,7 +127,7 @@ static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
125 struct symbol *sym; 127 struct symbol *sym;
126 int fd, ret = -ENOENT; 128 int fd, ret = -ENOENT;
127 129
128 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION], 130 sym = map__find_symbol_by_name(machine.vmlinux_maps[MAP__FUNCTION],
129 tp->symbol, NULL); 131 tp->symbol, NULL);
130 if (sym) { 132 if (sym) {
131 fd = open_vmlinux(); 133 fd = open_vmlinux();
@@ -1466,7 +1468,7 @@ static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
1466 } 1468 }
1467 1469
1468 /* Currently just checking function name from symbol map */ 1470 /* Currently just checking function name from symbol map */
1469 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION], 1471 sym = map__find_symbol_by_name(machine.vmlinux_maps[MAP__FUNCTION],
1470 tev->point.symbol, NULL); 1472 tev->point.symbol, NULL);
1471 if (!sym) { 1473 if (!sym) {
1472 pr_warning("Kernel symbol \'%s\' not found.\n", 1474 pr_warning("Kernel symbol \'%s\' not found.\n",
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index b745c1c0b6c7..a8dd73ed1581 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -69,12 +69,11 @@ void perf_session__update_sample_type(struct perf_session *self)
69 69
70int perf_session__create_kernel_maps(struct perf_session *self) 70int perf_session__create_kernel_maps(struct perf_session *self)
71{ 71{
72 int ret; 72 struct rb_root *machines = &self->machines;
73 struct rb_root *root = &self->machines; 73 int ret = machines__create_kernel_maps(machines, HOST_KERNEL_ID);
74 74
75 ret = map_groups__create_kernel_maps(root, HOST_KERNEL_ID);
76 if (ret >= 0) 75 if (ret >= 0)
77 ret = map_groups__create_guest_kernel_maps(root); 76 ret = machines__create_guest_kernel_maps(machines);
78 return ret; 77 return ret;
79} 78}
80 79
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index c9c0bdd667ac..12359c37240c 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1528,21 +1528,20 @@ static char *get_kernel_version(const char *root_dir)
1528 return strdup(name); 1528 return strdup(name);
1529} 1529}
1530 1530
1531static int map_groups__set_modules_path(struct map_groups *self, 1531static int machine__set_modules_path(struct machine *self)
1532 const char *root_dir)
1533{ 1532{
1534 char *version; 1533 char *version;
1535 char modules_path[PATH_MAX]; 1534 char modules_path[PATH_MAX];
1536 1535
1537 version = get_kernel_version(root_dir); 1536 version = get_kernel_version(self->root_dir);
1538 if (!version) 1537 if (!version)
1539 return -1; 1538 return -1;
1540 1539
1541 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", 1540 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
1542 root_dir, version); 1541 self->root_dir, version);
1543 free(version); 1542 free(version);
1544 1543
1545 return map_groups__set_modules_path_dir(self, modules_path); 1544 return map_groups__set_modules_path_dir(&self->kmaps, modules_path);
1546} 1545}
1547 1546
1548/* 1547/*
@@ -1564,14 +1563,12 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1564 return self; 1563 return self;
1565} 1564}
1566 1565
1567struct map *map_groups__new_module(struct map_groups *self, u64 start, 1566struct map *machine__new_module(struct machine *self, u64 start,
1568 const char *filename, 1567 const char *filename)
1569 struct machine *machine)
1570{ 1568{
1571 struct map *map; 1569 struct map *map;
1572 struct dso *dso; 1570 struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename);
1573 1571
1574 dso = __dsos__findnew(&machine->kernel_dsos, filename);
1575 if (dso == NULL) 1572 if (dso == NULL)
1576 return NULL; 1573 return NULL;
1577 1574
@@ -1579,28 +1576,27 @@ struct map *map_groups__new_module(struct map_groups *self, u64 start,
1579 if (map == NULL) 1576 if (map == NULL)
1580 return NULL; 1577 return NULL;
1581 1578
1582 if (machine__is_host(machine)) 1579 if (machine__is_host(self))
1583 dso->origin = DSO__ORIG_KMODULE; 1580 dso->origin = DSO__ORIG_KMODULE;
1584 else 1581 else
1585 dso->origin = DSO__ORIG_GUEST_KMODULE; 1582 dso->origin = DSO__ORIG_GUEST_KMODULE;
1586 map_groups__insert(self, map); 1583 map_groups__insert(&self->kmaps, map);
1587 return map; 1584 return map;
1588} 1585}
1589 1586
1590static int map_groups__create_modules(struct machine *machine) 1587static int machine__create_modules(struct machine *self)
1591{ 1588{
1592 char *line = NULL; 1589 char *line = NULL;
1593 size_t n; 1590 size_t n;
1594 FILE *file; 1591 FILE *file;
1595 struct map *map; 1592 struct map *map;
1596 const char *root_dir;
1597 const char *modules; 1593 const char *modules;
1598 char path[PATH_MAX]; 1594 char path[PATH_MAX];
1599 1595
1600 if (machine__is_default_guest(machine)) 1596 if (machine__is_default_guest(self))
1601 modules = symbol_conf.default_guest_modules; 1597 modules = symbol_conf.default_guest_modules;
1602 else { 1598 else {
1603 sprintf(path, "%s/proc/modules", machine->root_dir); 1599 sprintf(path, "%s/proc/modules", self->root_dir);
1604 modules = path; 1600 modules = path;
1605 } 1601 }
1606 1602
@@ -1608,8 +1604,6 @@ static int map_groups__create_modules(struct machine *machine)
1608 if (file == NULL) 1604 if (file == NULL)
1609 return -1; 1605 return -1;
1610 1606
1611 root_dir = machine->root_dir;
1612
1613 while (!feof(file)) { 1607 while (!feof(file)) {
1614 char name[PATH_MAX]; 1608 char name[PATH_MAX];
1615 u64 start; 1609 u64 start;
@@ -1638,17 +1632,16 @@ static int map_groups__create_modules(struct machine *machine)
1638 *sep = '\0'; 1632 *sep = '\0';
1639 1633
1640 snprintf(name, sizeof(name), "[%s]", line); 1634 snprintf(name, sizeof(name), "[%s]", line);
1641 map = map_groups__new_module(&machine->kmaps, start, 1635 map = machine__new_module(self, start, name);
1642 name, machine);
1643 if (map == NULL) 1636 if (map == NULL)
1644 goto out_delete_line; 1637 goto out_delete_line;
1645 dso__kernel_module_get_build_id(map->dso, root_dir); 1638 dso__kernel_module_get_build_id(map->dso, self->root_dir);
1646 } 1639 }
1647 1640
1648 free(line); 1641 free(line);
1649 fclose(file); 1642 fclose(file);
1650 1643
1651 return map_groups__set_modules_path(&machine->kmaps, root_dir); 1644 return machine__set_modules_path(self);
1652 1645
1653out_delete_line: 1646out_delete_line:
1654 free(line); 1647 free(line);
@@ -2005,25 +1998,23 @@ static struct dso *dsos__create_kernel(struct machine *machine)
2005 return kernel; 1998 return kernel;
2006} 1999}
2007 2000
2008int __map_groups__create_kernel_maps(struct map_groups *self, 2001int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
2009 struct map *vmlinux_maps[MAP__NR_TYPES],
2010 struct dso *kernel)
2011{ 2002{
2012 enum map_type type; 2003 enum map_type type;
2013 2004
2014 for (type = 0; type < MAP__NR_TYPES; ++type) { 2005 for (type = 0; type < MAP__NR_TYPES; ++type) {
2015 struct kmap *kmap; 2006 struct kmap *kmap;
2016 2007
2017 vmlinux_maps[type] = map__new2(0, kernel, type); 2008 self->vmlinux_maps[type] = map__new2(0, kernel, type);
2018 if (vmlinux_maps[type] == NULL) 2009 if (self->vmlinux_maps[type] == NULL)
2019 return -1; 2010 return -1;
2020 2011
2021 vmlinux_maps[type]->map_ip = 2012 self->vmlinux_maps[type]->map_ip =
2022 vmlinux_maps[type]->unmap_ip = identity__map_ip; 2013 self->vmlinux_maps[type]->unmap_ip = identity__map_ip;
2023 2014
2024 kmap = map__kmap(vmlinux_maps[type]); 2015 kmap = map__kmap(self->vmlinux_maps[type]);
2025 kmap->kmaps = self; 2016 kmap->kmaps = &self->kmaps;
2026 map_groups__insert(self, vmlinux_maps[type]); 2017 map_groups__insert(&self->kmaps, self->vmlinux_maps[type]);
2027 } 2018 }
2028 2019
2029 return 0; 2020 return 0;
@@ -2145,10 +2136,10 @@ out_free_comm_list:
2145 return -1; 2136 return -1;
2146} 2137}
2147 2138
2148int map_groups__create_kernel_maps(struct rb_root *machines, pid_t pid) 2139int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
2149{ 2140{
2150 struct dso *kernel; 2141 struct dso *kernel;
2151 struct machine *machine = machines__findnew(machines, pid); 2142 struct machine *machine = machines__findnew(self, pid);
2152 2143
2153 if (machine == NULL) 2144 if (machine == NULL)
2154 return -1; 2145 return -1;
@@ -2156,12 +2147,10 @@ int map_groups__create_kernel_maps(struct rb_root *machines, pid_t pid)
2156 if (kernel == NULL) 2147 if (kernel == NULL)
2157 return -1; 2148 return -1;
2158 2149
2159 if (__map_groups__create_kernel_maps(&machine->kmaps, 2150 if (__machine__create_kernel_maps(machine, kernel) < 0)
2160 machine->vmlinux_maps, kernel) < 0)
2161 return -1; 2151 return -1;
2162 2152
2163 if (symbol_conf.use_modules && 2153 if (symbol_conf.use_modules && machine__create_modules(machine) < 0)
2164 map_groups__create_modules(machine) < 0)
2165 pr_debug("Problems creating module maps, continuing anyway...\n"); 2154 pr_debug("Problems creating module maps, continuing anyway...\n");
2166 /* 2155 /*
2167 * Now that we have all the maps created, just set the ->end of them: 2156 * Now that we have all the maps created, just set the ->end of them:
@@ -2213,7 +2202,7 @@ char *strxfrchar(char *s, char from, char to)
2213 return s; 2202 return s;
2214} 2203}
2215 2204
2216int map_groups__create_guest_kernel_maps(struct rb_root *machines) 2205int machines__create_guest_kernel_maps(struct rb_root *self)
2217{ 2206{
2218 int ret = 0; 2207 int ret = 0;
2219 struct dirent **namelist = NULL; 2208 struct dirent **namelist = NULL;
@@ -2224,7 +2213,7 @@ int map_groups__create_guest_kernel_maps(struct rb_root *machines)
2224 if (symbol_conf.default_guest_vmlinux_name || 2213 if (symbol_conf.default_guest_vmlinux_name ||
2225 symbol_conf.default_guest_modules || 2214 symbol_conf.default_guest_modules ||
2226 symbol_conf.default_guest_kallsyms) { 2215 symbol_conf.default_guest_kallsyms) {
2227 map_groups__create_kernel_maps(machines, DEFAULT_GUEST_KERNEL_ID); 2216 machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID);
2228 } 2217 }
2229 2218
2230 if (symbol_conf.guestmount) { 2219 if (symbol_conf.guestmount) {
@@ -2245,7 +2234,7 @@ int map_groups__create_guest_kernel_maps(struct rb_root *machines)
2245 pr_debug("Can't access file %s\n", path); 2234 pr_debug("Can't access file %s\n", path);
2246 goto failure; 2235 goto failure;
2247 } 2236 }
2248 map_groups__create_kernel_maps(machines, pid); 2237 machines__create_kernel_maps(self, pid);
2249 } 2238 }
2250failure: 2239failure:
2251 free(namelist); 2240 free(namelist);
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index ed885b06a023..37b717b861c4 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -199,11 +199,9 @@ int kallsyms__parse(const char *filename, void *arg,
199 int (*process_symbol)(void *arg, const char *name, 199 int (*process_symbol)(void *arg, const char *name,
200 char type, u64 start)); 200 char type, u64 start));
201 201
202int __map_groups__create_kernel_maps(struct map_groups *self, 202int __machine__create_kernel_maps(struct machine *self, struct dso *kernel);
203 struct map *vmlinux_maps[MAP__NR_TYPES], 203int machines__create_kernel_maps(struct rb_root *self, pid_t pid);
204 struct dso *kernel); 204int machines__create_guest_kernel_maps(struct rb_root *self);
205int map_groups__create_kernel_maps(struct rb_root *kerninfo_root, pid_t pid);
206int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root);
207 205
208int symbol__init(void); 206int symbol__init(void);
209bool symbol_type__is_a(char symbol_type, enum map_type map_type); 207bool symbol_type__is_a(char symbol_type, enum map_type map_type);