perf symbols: Unify symbol maps
tip-bot for Arnaldo Carvalho de Melo
merge botCommit-ID: 3183f8ca304fd84096c44332f9bb699943beb6f1 Gitweb: https://git.kernel.org/tip/3183f8ca304fd84096c44332f9bb699943beb6f1 Author: Arnaldo Carvalho de Melo <[email protected]> AuthorDate: Thu, 26 Apr 2018 16:52:34 -0300 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Fri, 27 Apr 2018 10:47:06 -0300
perf symbols: Unify symbol maps
Remove the split of symbol tables for data (MAP__VARIABLE) and for functions (MAP__FUNCTION), its unneeded and there were various places doing two lookups to find a symbol, so simplify this.
We still will consider only the symbols that matched the filters in place, i.e. see the (elf_(sec,sym)|symbol_type)__filter() routines in the patch, just so that we consider only the same symbols as before, to reduce the possibility of regressions.
All the tests on 50-something build environments, in varios versions of lots of distros and cross build environments were performed without build regressions, as usual with all pull requests the other tests were also performed: 'perf test' and 'make -C tools/perf build-test'.
Also this was done at a great granularity so that regressions can be bisected more easily.
--- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-report.c | 5 +- tools/perf/tests/hists_common.c | 4 +- tools/perf/ui/browsers/map.c | 2 +- tools/perf/util/db-export.c | 2 +- tools/perf/util/dso.c | 34 ++++------ tools/perf/util/dso.h | 36 +++++----- tools/perf/util/event.c | 13 +--- tools/perf/util/machine.c | 124 +++++++++++++---------------------- tools/perf/util/machine.h | 32 +++------ tools/perf/util/map.c | 91 ++++++++------------------ tools/perf/util/map.h | 54 ++++----------- tools/perf/util/probe-event.c | 9 ++- tools/perf/util/session.c | 13 ++-- tools/perf/util/symbol-elf.c | 51 +++++---------- tools/perf/util/symbol-minimal.c | 3 +- tools/perf/util/symbol.c | 138 +++++++++++++++------------------------ tools/perf/util/symbol.h | 16 ++--- tools/perf/util/symbol_fprintf.c | 4 +- tools/perf/util/thread.c | 30 ++++----- 20 files changed, 232 insertions(+), 431 deletions(-)
tools/perf/builtin-annotate.c +1 -1
@@ -228,7 +228,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,*/ if (al->sym !=NULL ) {rb_erase (&al->sym->rb_node, - &al->map->dso->symbols[al->map->type]); + &al->map->dso->symbols);symbol__delete (al->sym);dso__reset_find_symbol_cache (al->map->dso); }
tools/perf/builtin-report.c +1 -4
@@ -715,10 +715,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)static int map_groups__fprintf_task (struct map_groups *mg,int indent,FILE *fp) { -int printed =0 , i; -for (i =0 ; i <MAP__NR_TYPES ; ++i) - printed +=maps__fprintf_task (&mg->maps[i], indent, fp); -return printed; +return maps__fprintf_task (&mg->maps, indent, fp); }static void task__print_level (struct task *task,FILE *fp,int level)
tools/perf/tests/hists_common.c +2 -2
@@ -131,7 +131,7 @@ struct machine *setup_fake_machine(struct machines *machines) goto out;/* emulate dso__load() */ -dso__set_loaded (dso,MAP__FUNCTION ); +dso__set_loaded (dso);for (k =0 ; k < fake_symbols[i].nr_syms; k++) {struct symbol *sym;
@@ -144,7 +144,7 @@ struct machine *setup_fake_machine(struct machines *machines) goto out; } -symbols__insert (&dso->symbols[MAP__FUNCTION ], sym); +symbols__insert (&dso->symbols, sym); }dso__put (dso);
tools/perf/ui/browsers/map.c +1 -1
@@ -104,7 +104,7 @@ int map__browse(struct map *map) {struct map_browser mb = { .b = { - .entries = &map->dso->symbols[map->type], + .entries = &map->dso->symbols, .refresh = ui_browser__rb_tree_refresh, .seek = ui_browser__rb_tree_seek, .write = map_browser__write,
tools/perf/util/db-export.c +1 -1
@@ -249,7 +249,7 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al,if (!al->sym) { al->sym =symbol__new (al->addr,0 ,0 ,0 ,"unknown" );if (al->sym) -dso__insert_symbol (dso, al->map->type, al->sym); +dso__insert_symbol (dso, al->sym); }if (al->sym) {
tools/perf/util/dso.c +13 -21
@@ -1014,7 +1014,7 @@ struct map *dso__new_map(const char *name)struct dso *dso =dso__new (name);if (dso) - map =map__new2 (0 , dso,MAP__FUNCTION ); + map =map__new2 (0 , dso);return map; }
@@ -1176,19 +1176,19 @@ int dso__name_len(const struct dso *dso)return dso->short_name_len; } -bool dso__loaded (const struct dso *dso,enum map_type type) +bool dso__loaded (const struct dso *dso) { -return dso->loaded & (1 << type); +return dso->loaded; } -bool dso__sorted_by_name (const struct dso *dso,enum map_type type) +bool dso__sorted_by_name (const struct dso *dso) { -return dso->sorted_by_name & (1 << type); +return dso->sorted_by_name; } -void dso__set_sorted_by_name (struct dso *dso,enum map_type type) +void dso__set_sorted_by_name (struct dso *dso) { - dso->sorted_by_name |= (1 << type); + dso->sorted_by_name = true; }struct dso *dso__new (const char *name)
@@ -1196,12 +1196,10 @@ struct dso *dso__new(const char *name)struct dso *dso =calloc (1 ,sizeof (*dso) +strlen (name) +1 );if (dso !=NULL ) { -int i;strcpy (dso->name, name);dso__set_long_name (dso, dso->name, false);dso__set_short_name (dso, dso->name, false); -for (i =0 ; i <MAP__NR_TYPES ; ++i) - dso->symbols[i] = dso->symbol_names[i] =RB_ROOT ; + dso->symbols = dso->symbol_names =RB_ROOT ; dso->data.cache =RB_ROOT ; dso->inlined_nodes =RB_ROOT ; dso->srclines =RB_ROOT ;
@@ -1231,8 +1229,6 @@ struct dso *dso__new(const char *name)void dso__delete (struct dso *dso) { -int i; -if (!RB_EMPTY_NODE (&dso->rb_node))pr_err ("DSO %s is still in rbtree when being deleted!\n" , dso->long_name);
@@ -1240,8 +1236,7 @@ void dso__delete(struct dso *dso)/* free inlines first, as they reference symbols */ inlines__tree_delete (&dso->inlined_nodes);srcline__tree_delete (&dso->srclines); -for (i =0 ; i <MAP__NR_TYPES ; ++i) -symbols__delete (&dso->symbols[i]); +symbols__delete (&dso->symbols);if (dso->short_name_allocated) {zfree ((char **)&dso->short_name);
@@ -1451,9 +1446,7 @@ size_t __dsos__fprintf(struct list_head *head, FILE *fp)size_t ret =0 ;list_for_each_entry (pos, head, node) { -int i; -for (i =0 ; i <MAP__NR_TYPES ; ++i) - ret +=dso__fprintf (pos, i, fp); + ret +=dso__fprintf (pos, fp); }return ret;
@@ -1467,18 +1460,17 @@ size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)return fprintf (fp,"%s" , sbuild_id); } -size_t dso__fprintf (struct dso *dso,enum map_type type,FILE *fp) +size_t dso__fprintf (struct dso *dso,FILE *fp) {struct rb_node *nd;size_t ret =fprintf (fp,"dso: %s (" , dso->short_name);if (dso->short_name != dso->long_name) ret +=fprintf (fp,"%s, " , dso->long_name); - ret +=fprintf (fp,"%s, %sloaded, " , map_type__name[type], -dso__loaded (dso, type) ?"" :"NOT " ); + ret +=fprintf (fp,"%sloaded, " ,dso__loaded (dso) ?"" :"NOT " ); ret +=dso__fprintf_buildid (dso, fp); ret +=fprintf (fp,")\n" ); -for (nd =rb_first (&dso->symbols[type]); nd; nd =rb_next (nd)) { +for (nd =rb_first (&dso->symbols); nd; nd =rb_next (nd)) { struct symbol *pos = rb_entry(nd, struct symbol, rb_node); ret +=symbol__fprintf (pos, fp); }
tools/perf/util/dso.h +17 -19
@@ -140,14 +140,14 @@ struct dso {struct list_head node;struct rb_node rb_node;/* rbtree node sorted by long name */ struct rb_root *root;/* root of rbtree that rb_node is in */ -struct rb_root symbols[MAP__NR_TYPES ]; -struct rb_root symbol_names[MAP__NR_TYPES ]; +struct rb_root symbols; +struct rb_root symbol_names;struct rb_root inlined_nodes;struct rb_root srclines;struct {u64 addr;struct symbol *symbol; - } last_find_result[MAP__NR_TYPES ]; + } last_find_result;void *a2l;char *symsrc_filename;unsigned int a2l_fails;
@@ -164,8 +164,8 @@ struct dso { u8 short_name_allocated:1; u8 long_name_allocated:1; u8 is_64_bit:1; -u8 sorted_by_name; -u8 loaded; +bool sorted_by_name; +bool loaded;u8 rel;u8 build_id[BUILD_ID_SIZE ];u64 text_offset;
@@ -202,14 +202,13 @@ struct dso {* @dso: the 'struct dso *' in which symbols itereated * @pos: the 'struct symbol *' to use as a loop cursor * @n: the 'struct rb_node *' to use as a temporary storage -* @type: the 'enum map_type' type of symbols */ -#define dso__for_each_symbol (dso, pos, n, type) \ - symbols__for_each_entry(&(dso)->symbols[(type)], pos, n) +#define dso__for_each_symbol (dso, pos, n) \ + symbols__for_each_entry(&(dso)->symbols, pos, n) -static inline void dso__set_loaded (struct dso *dso,enum map_type type) +static inline void dso__set_loaded (struct dso *dso) { - dso->loaded |= (1 << type); + dso->loaded = true; }struct dso *dso__new (const char *name);
@@ -231,16 +230,16 @@ static inline void __dso__zput(struct dso **dso)#define dso__zput (dso) __dso__zput(&dso) -bool dso__loaded (const struct dso *dso,enum map_type type); +bool dso__loaded (const struct dso *dso); -static inline bool dso__has_symbols (const struct dso *dso,enum map_type type) +static inline bool dso__has_symbols (const struct dso *dso) { -return !RB_EMPTY_ROOT (&dso->symbols[type]); +return !RB_EMPTY_ROOT (&dso->symbols); } -bool dso__sorted_by_name (const struct dso *dso,enum map_type type); -void dso__set_sorted_by_name (struct dso *dso,enum map_type type); -void dso__sort_by_name (struct dso *dso,enum map_type type); +bool dso__sorted_by_name (const struct dso *dso); +void dso__set_sorted_by_name (struct dso *dso); +void dso__sort_by_name (struct dso *dso);void dso__set_build_id (struct dso *dso,void *build_id);bool dso__build_id_equal (const struct dso *dso,u8 *build_id);
@@ -354,9 +353,8 @@ size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,size_t __dsos__fprintf (struct list_head *head,FILE *fp);size_t dso__fprintf_buildid (struct dso *dso,FILE *fp); -size_t dso__fprintf_symbols_by_name (struct dso *dso, -enum map_type type,FILE *fp); -size_t dso__fprintf (struct dso *dso,enum map_type type,FILE *fp); +size_t dso__fprintf_symbols_by_name (struct dso *dso,FILE *fp); +size_t dso__fprintf (struct dso *dso,FILE *fp);static inline bool dso__is_vmlinux (struct dso *dso) {
tools/perf/util/event.c +3 -10
@@ -1488,8 +1488,8 @@ int perf_event__process(struct perf_tool *tool __maybe_unused,return machine__process_event (machine, event, sample); } -static struct map *__thread__find_map (struct thread *thread,u8 cpumode,enum map_type type, -u64 addr,struct addr_location *al) +struct map *thread__find_map (struct thread *thread,u8 cpumode,u64 addr, +struct addr_location *al) {struct map_groups *mg = thread->mg;struct machine *machine = mg->machine;
@@ -1534,7 +1534,7 @@ static struct map *__thread__find_map(struct thread *thread, u8 cpumode, enum mareturn NULL ; } try_again: - al->map =__map_groups__find (mg, type, al->addr); + al->map =map_groups__find (mg, al->addr);if (al->map ==NULL ) {/* * If this is outside of all known maps, and is a negative
@@ -1565,13 +1565,6 @@ try_again:return al->map; } -struct map *thread__find_map (struct thread *thread,u8 cpumode,u64 addr, -struct addr_location *al) -{ -struct map *map =__thread__find_map (thread, cpumode,MAP__FUNCTION , addr, al); -return map ?:__thread__find_map (thread, cpumode,MAP__VARIABLE , addr, al); -} -struct symbol *thread__find_symbol (struct thread *thread,u8 cpumode,u64 addr,struct addr_location *al) {
tools/perf/util/machine.c +44 -80
233 lines not on this page · raw message
tools/perf/util/machine.h +9 -23
@@ -49,7 +49,7 @@ struct machine {struct perf_env *env;struct dsos dsos;struct map_groups kmaps; -struct map *vmlinux_maps[MAP__NR_TYPES ]; +struct map *vmlinux_map;u64 kernel_start;pid_t *current_tid;union {/* Tool specific area */
@@ -64,19 +64,13 @@ static inline struct threads *machine__threads(struct machine *machine, pid_t tireturn &machine->threads[(unsigned int )tid %THREADS__TABLE_SIZE ]; } -static inline -struct map *__machine__kernel_map (struct machine *machine,enum map_type type) -{ -return machine->vmlinux_maps[type]; -} -/* * The main kernel (vmlinux) map */ static inline struct map *machine__kernel_map (struct machine *machine) { -return __machine__kernel_map (machine,MAP__FUNCTION ); +return machine->vmlinux_map; }/*
@@ -85,7 +79,7 @@ struct map *machine__kernel_map(struct machine *machine)static inline struct maps *machine__kernel_maps (struct machine *machine) { -return &machine->kmaps.maps[MAP__FUNCTION ]; +return &machine->kmaps.maps; }int machine__get_kernel_start (struct machine *machine);
@@ -202,27 +196,25 @@ struct dso *machine__findnew_dso(struct machine *machine, const char *filename);size_t machine__fprintf (struct machine *machine,FILE *fp);static inline -struct symbol *machine__find_kernel_symbol (struct machine *machine, -enum map_type type,u64 addr, +struct symbol *machine__find_kernel_symbol (struct machine *machine,u64 addr,struct map **mapp) { -return map_groups__find_symbol (&machine->kmaps, type, addr, mapp); +return map_groups__find_symbol (&machine->kmaps, addr, mapp); }static inline struct symbol *machine__find_kernel_symbol_by_name (struct machine *machine, -enum map_type type,const char *name, +const char *name,struct map **mapp) { -return map_groups__find_symbol_by_name (&machine->kmaps, type, name, mapp); +return map_groups__find_symbol_by_name (&machine->kmaps, name, mapp); }static inline struct symbol *machine__find_kernel_function (struct machine *machine,u64 addr,struct map **mapp) { -return machine__find_kernel_symbol (machine,MAP__FUNCTION , addr, - mapp); +return machine__find_kernel_symbol (machine, addr, mapp); } static inline
@@ -237,13 +229,7 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start, const char *filename);int arch__fix_module_text_start (u64 *start,const char *name); -int __machine__load_kallsyms (struct machine *machine,const char *filename, -enum map_type type); - -static inline int machine__load_kallsyms (struct machine *machine,const char *filename) -{ -return __machine__load_kallsyms (machine, filename,MAP__FUNCTION ); -} +int machine__load_kallsyms (struct machine *machine,const char *filename);int machine__load_vmlinux_path (struct machine *machine);
tools/perf/util/map.c +28 -63
246 lines not on this page · raw message
tools/perf/util/map.h +14 -40
133 lines not on this page · raw message
tools/perf/util/probe-event.c +4 -5
@@ -3503,19 +3503,18 @@ int show_available_funcs(const char *target, struct nsinfo *nsi, (target) ? : "kernel"); goto end; } -if (!dso__sorted_by_name (map->dso, map->type)) -dso__sort_by_name (map->dso, map->type); +if (!dso__sorted_by_name (map->dso)) +dso__sort_by_name (map->dso);/* Show all (filtered) symbols */ setup_pager (); -for (nd =rb_first (&map->dso->symbol_names[map->type]); nd; nd =rb_next (nd)) { +for (nd =rb_first (&map->dso->symbol_names); nd; nd =rb_next (nd)) { struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);if (strfilter__compare (_filter, pos->sym.name))printf ("%s\n" , pos->sym.name); - } - + } end:map__put (map);exit_probe_symbol_maps ();
tools/perf/util/session.c +4 -9
@@ -1973,12 +1973,11 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg)return false; } -int maps__set_kallsyms_ref_reloc_sym (struct map **maps, -const char *symbol_name,u64 addr) +int map__set_kallsyms_ref_reloc_sym (struct map *map,const char *symbol_name,u64 addr) {char *bracket; -int i;struct ref_reloc_sym *ref; +struct kmap *kmap; ref =zalloc (sizeof (struct ref_reloc_sym ));if (ref ==NULL )
@@ -1996,13 +1995,9 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps, ref->addr = addr; -for (i =0 ; i <MAP__NR_TYPES ; ++i) { -struct kmap *kmap =map__kmap (maps[i]); - -if (!kmap) -continue ; + kmap =map__kmap (map); +if (kmap) kmap->ref_reloc_sym = ref; - }return 0 ; }
tools/perf/util/symbol-elf.c +18 -33
136 lines not on this page · raw message
tools/perf/util/symbol-minimal.c +1 -2
@@ -288,8 +288,7 @@ void symsrc__destroy(struct symsrc *ss) }int dso__synthesize_plt_symbols (struct dso *dso__maybe_unused , -struct symsrc *ss__maybe_unused , -struct map *map__maybe_unused ) +struct symsrc *ss__maybe_unused ) {return 0 ; }
tools/perf/util/symbol.c +52 -86
349 lines not on this page · raw message
tools/perf/util/symbol.h +5 -11
@@ -260,16 +260,11 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map, bool no_kcore);int dso__load_kallsyms (struct dso *dso,const char *filename,struct map *map); -void dso__insert_symbol (struct dso *dso,enum map_type type, +void dso__insert_symbol (struct dso *dso,struct symbol *sym); -struct symbol *__dso__find_symbol (struct dso *dso,enum map_type type,u64 addr); -struct symbol *__dso__find_symbol_by_name (struct dso *dso,enum map_type type,const char *name); - -static inline struct symbol *dso__find_symbol (struct dso *dso,u64 addr) -{ -return __dso__find_symbol (dso,MAP__FUNCTION , addr); -} +struct symbol *dso__find_symbol (struct dso *dso,u64 addr); +struct symbol *dso__find_symbol_by_name (struct dso *dso,const char *name);struct symbol *symbol__next_by_name (struct symbol *sym);
@@ -312,8 +307,7 @@ int symbol__config_symfs(const struct option *opt __maybe_unused,int dso__load_sym (struct dso *dso,struct map *map,struct symsrc *syms_ss,struct symsrc *runtime_ss,int kmodule); -int dso__synthesize_plt_symbols (struct dso *dso,struct symsrc *ss, -struct map *map); +int dso__synthesize_plt_symbols (struct dso *dso,struct symsrc *ss);char *dso__demangle_sym (struct dso *dso,int kmodule,const char *elf_name);
@@ -321,7 +315,7 @@ void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel)void symbols__insert (struct rb_root *symbols,struct symbol *sym);void symbols__fixup_duplicate (struct rb_root *symbols);void symbols__fixup_end (struct rb_root *symbols); -void __map_groups__fixup_end (struct map_groups *mg,enum map_type type); +void map_groups__fixup_end (struct map_groups *mg);typedef int (*mapfn_t )(u64 start,u64 len,u64 pgoff,void *data); int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
tools/perf/util/symbol_fprintf.c +2 -2
@@ -58,13 +58,13 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp) }size_t dso__fprintf_symbols_by_name (struct dso *dso, -enum map_type type,FILE *fp) +FILE *fp) {size_t ret =0 ;struct rb_node *nd;struct symbol_name_rb_node *pos; -for (nd =rb_first (&dso->symbol_names[type]); nd; nd =rb_next (nd)) { +for (nd =rb_first (&dso->symbol_names); nd; nd =rb_next (nd)) { pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);fprintf (fp,"%s\n" , pos->sym.name); }
tools/perf/util/thread.c +12 -18
@@ -302,23 +302,20 @@ int thread__insert_map(struct thread *thread, struct map *map)static int __thread__prepare_access (struct thread *thread) {bool initialized = false; -int i, err =0 ; - -for (i =0 ; i <MAP__NR_TYPES ; ++i) { -struct maps *maps = &thread->mg->maps[i]; -struct map *map; +int err =0 ; +struct maps *maps = &thread->mg->maps; +struct map *map; -down_read (&maps->lock); +down_read (&maps->lock); -for (map =maps__first (maps); map; map =map__next (map)) { - err =unwind__prepare_access (thread, map, &initialized); -if (err || initialized) -break ; - } - -up_read (&maps->lock); +for (map =maps__first (maps); map; map =map__next (map)) { + err =unwind__prepare_access (thread, map, &initialized); +if (err || initialized) +break ; } +up_read (&maps->lock); +return err; }
@@ -335,8 +332,6 @@ static int thread__prepare_access(struct thread *thread)static int thread__clone_map_groups (struct thread *thread,struct thread *parent) { -int i; -/* This is new thread, we share map groups for process. */ if (thread->pid_ == parent->pid_)return thread__prepare_access (thread);
@@ -348,9 +343,8 @@ static int thread__clone_map_groups(struct thread *thread, }/* But this one is new process, copy maps. */ -for (i =0 ; i <MAP__NR_TYPES ; ++i) -if (map_groups__clone (thread, parent->mg, i) <0 ) -return -ENOMEM ; +if (map_groups__clone (thread, parent->mg) <0 ) +return -ENOMEM ;return 0 ; }