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; |
