diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-11-24 09:05:15 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-24 10:37:02 -0500 |
commit | b32d133aec5dc882cf783a293f393bfb3f4379e1 (patch) | |
tree | 41fc56a4aaec8892a235ffd530b36278d147dc4e /tools/perf/util | |
parent | 7cc017edb9459193d3b581155a14029e4bef0c49 (diff) |
perf symbols: Simplify symbol machinery setup
And also express its configuration toggles via a struct.
Now all one has to do is to call symbol__init(NULL) if the
defaults are OK, or pass a struct symbol_conf pointer with the
desired configuration.
If a tool uses kernel_maps__find_symbol() to look at the kernel
and modules mappings for a symbol but didn't call symbol__init()
first, that will generate a one time warning too, alerting the
subcommand developer that symbol__init() must be called.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1259071517-3242-2-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/data_map.c | 8 | ||||
-rw-r--r-- | tools/perf/util/data_map.h | 2 | ||||
-rw-r--r-- | tools/perf/util/header.c | 6 | ||||
-rw-r--r-- | tools/perf/util/include/asm/bug.h | 22 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 31 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 11 |
6 files changed, 51 insertions, 29 deletions
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index f318d19b2562..b238462b8983 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c | |||
@@ -101,8 +101,6 @@ out: | |||
101 | 101 | ||
102 | int mmap_dispatch_perf_file(struct perf_header **pheader, | 102 | int mmap_dispatch_perf_file(struct perf_header **pheader, |
103 | const char *input_name, | 103 | const char *input_name, |
104 | const char *vmlinux_name, | ||
105 | bool try_vmlinux_path, | ||
106 | int force, | 104 | int force, |
107 | int full_paths, | 105 | int full_paths, |
108 | int *cwdlen, | 106 | int *cwdlen, |
@@ -172,12 +170,6 @@ int mmap_dispatch_perf_file(struct perf_header **pheader, | |||
172 | curr_handler->sample_type_check(sample_type) < 0) | 170 | curr_handler->sample_type_check(sample_type) < 0) |
173 | goto out_delete; | 171 | goto out_delete; |
174 | 172 | ||
175 | err = -ENOMEM; | ||
176 | if (kernel_maps__init(vmlinux_name, try_vmlinux_path, true) < 0) { | ||
177 | pr_err("failed to setup the kernel maps to resolve symbols\n"); | ||
178 | goto out_delete; | ||
179 | } | ||
180 | |||
181 | if (!full_paths) { | 173 | if (!full_paths) { |
182 | if (getcwd(__cwd, sizeof(__cwd)) == NULL) { | 174 | if (getcwd(__cwd, sizeof(__cwd)) == NULL) { |
183 | pr_err("failed to get the current directory\n"); | 175 | pr_err("failed to get the current directory\n"); |
diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h index 3f0d21b3819e..ae036ecd7625 100644 --- a/tools/perf/util/data_map.h +++ b/tools/perf/util/data_map.h | |||
@@ -23,8 +23,6 @@ struct perf_file_handler { | |||
23 | void register_perf_file_handler(struct perf_file_handler *handler); | 23 | void register_perf_file_handler(struct perf_file_handler *handler); |
24 | int mmap_dispatch_perf_file(struct perf_header **pheader, | 24 | int mmap_dispatch_perf_file(struct perf_header **pheader, |
25 | const char *input_name, | 25 | const char *input_name, |
26 | const char *vmlinux_name, | ||
27 | bool try_vmlinux_path, | ||
28 | int force, | 26 | int force, |
29 | int full_paths, | 27 | int full_paths, |
30 | int *cwdlen, | 28 | int *cwdlen, |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 1332f8ec04aa..271a1600e6f7 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -253,12 +253,6 @@ static int perf_header__adds_write(struct perf_header *self, int fd) | |||
253 | 253 | ||
254 | buildid_sec = &feat_sec[idx++]; | 254 | buildid_sec = &feat_sec[idx++]; |
255 | 255 | ||
256 | /* | ||
257 | * Read the kernel buildid nad the list of loaded modules with | ||
258 | * its build_ids: | ||
259 | */ | ||
260 | kernel_maps__init(NULL, false, true); | ||
261 | |||
262 | /* Write build-ids */ | 256 | /* Write build-ids */ |
263 | buildid_sec->offset = lseek(fd, 0, SEEK_CUR); | 257 | buildid_sec->offset = lseek(fd, 0, SEEK_CUR); |
264 | err = dsos__write_buildid_table(fd); | 258 | err = dsos__write_buildid_table(fd); |
diff --git a/tools/perf/util/include/asm/bug.h b/tools/perf/util/include/asm/bug.h new file mode 100644 index 000000000000..7fcc6810adc2 --- /dev/null +++ b/tools/perf/util/include/asm/bug.h | |||
@@ -0,0 +1,22 @@ | |||
1 | #ifndef _PERF_ASM_GENERIC_BUG_H | ||
2 | #define _PERF_ASM_GENERIC_BUG_H | ||
3 | |||
4 | #define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0) | ||
5 | |||
6 | #define WARN(condition, format...) ({ \ | ||
7 | int __ret_warn_on = !!(condition); \ | ||
8 | if (unlikely(__ret_warn_on)) \ | ||
9 | __WARN_printf(format); \ | ||
10 | unlikely(__ret_warn_on); \ | ||
11 | }) | ||
12 | |||
13 | #define WARN_ONCE(condition, format...) ({ \ | ||
14 | static int __warned; \ | ||
15 | int __ret_warn_once = !!(condition); \ | ||
16 | \ | ||
17 | if (unlikely(__ret_warn_once)) \ | ||
18 | if (WARN(!__warned, format)) \ | ||
19 | __warned = 1; \ | ||
20 | unlikely(__ret_warn_once); \ | ||
21 | }) | ||
22 | #endif | ||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 44d81d5ae8cf..c4ca974b36e3 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #include "debug.h" | 7 | #include "debug.h" |
8 | 8 | ||
9 | #include <asm/bug.h> | ||
9 | #include <libelf.h> | 10 | #include <libelf.h> |
10 | #include <gelf.h> | 11 | #include <gelf.h> |
11 | #include <elf.h> | 12 | #include <elf.h> |
@@ -37,6 +38,11 @@ unsigned int symbol__priv_size; | |||
37 | static int vmlinux_path__nr_entries; | 38 | static int vmlinux_path__nr_entries; |
38 | static char **vmlinux_path; | 39 | static char **vmlinux_path; |
39 | 40 | ||
41 | static struct symbol_conf symbol_conf__defaults = { | ||
42 | .use_modules = true, | ||
43 | .try_vmlinux_path = true, | ||
44 | }; | ||
45 | |||
40 | static struct rb_root kernel_maps; | 46 | static struct rb_root kernel_maps; |
41 | 47 | ||
42 | static void dso__fixup_sym_end(struct dso *self) | 48 | static void dso__fixup_sym_end(struct dso *self) |
@@ -1166,7 +1172,9 @@ struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp, | |||
1166 | if (map) { | 1172 | if (map) { |
1167 | ip = map->map_ip(map, ip); | 1173 | ip = map->map_ip(map, ip); |
1168 | return map__find_symbol(map, ip, filter); | 1174 | return map__find_symbol(map, ip, filter); |
1169 | } | 1175 | } else |
1176 | WARN_ONCE(RB_EMPTY_ROOT(&kernel_maps), | ||
1177 | "Empty kernel_maps, was symbol__init() called?\n"); | ||
1170 | 1178 | ||
1171 | return NULL; | 1179 | return NULL; |
1172 | } | 1180 | } |
@@ -1485,9 +1493,9 @@ size_t dsos__fprintf_buildid(FILE *fp) | |||
1485 | return ret; | 1493 | return ret; |
1486 | } | 1494 | } |
1487 | 1495 | ||
1488 | static int kernel_maps__create_kernel_map(const char *vmlinux_name) | 1496 | static int kernel_maps__create_kernel_map(const struct symbol_conf *conf) |
1489 | { | 1497 | { |
1490 | struct dso *kernel = dso__new(vmlinux_name ?: "[kernel.kallsyms]"); | 1498 | struct dso *kernel = dso__new(conf->vmlinux_name ?: "[kernel.kallsyms]"); |
1491 | 1499 | ||
1492 | if (kernel == NULL) | 1500 | if (kernel == NULL) |
1493 | return -1; | 1501 | return -1; |
@@ -1577,18 +1585,21 @@ out_fail: | |||
1577 | return -1; | 1585 | return -1; |
1578 | } | 1586 | } |
1579 | 1587 | ||
1580 | int kernel_maps__init(const char *vmlinux_name, bool try_vmlinux_path, | 1588 | static int kernel_maps__init(const struct symbol_conf *conf) |
1581 | bool use_modules) | ||
1582 | { | 1589 | { |
1583 | if (try_vmlinux_path && vmlinux_path__init() < 0) | 1590 | const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults; |
1591 | |||
1592 | symbol__priv_size = pconf->priv_size; | ||
1593 | |||
1594 | if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) | ||
1584 | return -1; | 1595 | return -1; |
1585 | 1596 | ||
1586 | if (kernel_maps__create_kernel_map(vmlinux_name) < 0) { | 1597 | if (kernel_maps__create_kernel_map(pconf) < 0) { |
1587 | vmlinux_path__exit(); | 1598 | vmlinux_path__exit(); |
1588 | return -1; | 1599 | return -1; |
1589 | } | 1600 | } |
1590 | 1601 | ||
1591 | if (use_modules && kernel_maps__create_module_maps() < 0) | 1602 | if (pconf->use_modules && kernel_maps__create_module_maps() < 0) |
1592 | pr_debug("Failed to load list of modules in use, " | 1603 | pr_debug("Failed to load list of modules in use, " |
1593 | "continuing...\n"); | 1604 | "continuing...\n"); |
1594 | /* | 1605 | /* |
@@ -1598,8 +1609,8 @@ int kernel_maps__init(const char *vmlinux_name, bool try_vmlinux_path, | |||
1598 | return 0; | 1609 | return 0; |
1599 | } | 1610 | } |
1600 | 1611 | ||
1601 | void symbol__init(unsigned int priv_size) | 1612 | int symbol__init(struct symbol_conf *conf) |
1602 | { | 1613 | { |
1603 | elf_version(EV_CURRENT); | 1614 | elf_version(EV_CURRENT); |
1604 | symbol__priv_size = priv_size; | 1615 | return kernel_maps__init(conf); |
1605 | } | 1616 | } |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 8c4d026e067a..5538691494af 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -49,6 +49,13 @@ struct symbol { | |||
49 | char name[0]; | 49 | char name[0]; |
50 | }; | 50 | }; |
51 | 51 | ||
52 | struct symbol_conf { | ||
53 | unsigned short priv_size; | ||
54 | bool try_vmlinux_path, | ||
55 | use_modules; | ||
56 | const char *vmlinux_name; | ||
57 | }; | ||
58 | |||
52 | extern unsigned int symbol__priv_size; | 59 | extern unsigned int symbol__priv_size; |
53 | 60 | ||
54 | static inline void *symbol__priv(struct symbol *self) | 61 | static inline void *symbol__priv(struct symbol *self) |
@@ -93,11 +100,9 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size); | |||
93 | bool dsos__read_build_ids(void); | 100 | bool dsos__read_build_ids(void); |
94 | int build_id__sprintf(u8 *self, int len, char *bf); | 101 | int build_id__sprintf(u8 *self, int len, char *bf); |
95 | 102 | ||
96 | int kernel_maps__init(const char *vmlinux_name, bool try_vmlinux_path, | ||
97 | bool use_modules); | ||
98 | size_t kernel_maps__fprintf(FILE *fp); | 103 | size_t kernel_maps__fprintf(FILE *fp); |
99 | 104 | ||
100 | void symbol__init(unsigned int priv_size); | 105 | int symbol__init(struct symbol_conf *conf); |
101 | 106 | ||
102 | extern struct list_head dsos; | 107 | extern struct list_head dsos; |
103 | extern struct map *kernel_map; | 108 | extern struct map *kernel_map; |