Loading tools/perf/util/hist.c +2 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) if (self != NULL) { *self = *template; self->nr_events = 1; if (self->ms.map) self->ms.map->referenced = true; if (symbol_conf.use_callchain) callchain_init(self->callchain); } Loading tools/perf/util/map.c +32 −17 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ void map__init(struct map *self, enum map_type type, self->unmap_ip = map__unmap_ip; RB_CLEAR_NODE(&self->rb_node); self->groups = NULL; self->referenced = false; } struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, Loading Loading @@ -387,6 +388,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, { struct rb_root *root = &self->maps[map->type]; struct rb_node *next = rb_first(root); int err = 0; while (next) { struct map *pos = rb_entry(next, struct map, rb_node); Loading @@ -402,12 +404,6 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, } rb_erase(&pos->rb_node, root); /* * We may have references to this map, for instance in some * hist_entry instances, so just move them to a separate * list. */ list_add_tail(&pos->node, &self->removed_maps[map->type]); /* * Now check if we need to create new maps for areas not * overlapped by the new map: Loading @@ -415,8 +411,10 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, if (map->start > pos->start) { struct map *before = map__clone(pos); if (before == NULL) return -ENOMEM; if (before == NULL) { err = -ENOMEM; goto move_map; } before->end = map->start - 1; map_groups__insert(self, before); Loading @@ -427,14 +425,27 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, if (map->end < pos->end) { struct map *after = map__clone(pos); if (after == NULL) return -ENOMEM; if (after == NULL) { err = -ENOMEM; goto move_map; } after->start = map->end + 1; map_groups__insert(self, after); if (verbose >= 2) map__fprintf(after, fp); } move_map: /* * If we have references, just move them to a separate list. */ if (pos->referenced) list_add_tail(&pos->node, &self->removed_maps[map->type]); else map__delete(pos); if (err) return err; } return 0; Loading Loading @@ -506,6 +517,11 @@ void maps__insert(struct rb_root *maps, struct map *map) rb_insert_color(&map->rb_node, maps); } void maps__remove(struct rb_root *self, struct map *map) { rb_erase(&map->rb_node, self); } struct map *maps__find(struct rb_root *maps, u64 ip) { struct rb_node **p = &maps->rb_node; Loading Loading @@ -551,13 +567,6 @@ static void dsos__delete(struct list_head *self) void machine__exit(struct machine *self) { struct kmap *kmap = map__kmap(self->vmlinux_maps[MAP__FUNCTION]); if (kmap->ref_reloc_sym) { free((char *)kmap->ref_reloc_sym->name); free(kmap->ref_reloc_sym); } map_groups__exit(&self->kmaps); dsos__delete(&self->user_dsos); dsos__delete(&self->kernel_dsos); Loading @@ -565,6 +574,12 @@ void machine__exit(struct machine *self) self->root_dir = NULL; } void machine__delete(struct machine *self) { machine__exit(self); free(self); } struct machine *machines__add(struct rb_root *self, pid_t pid, const char *root_dir) { Loading tools/perf/util/map.h +9 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,8 @@ struct map { }; u64 start; u64 end; enum map_type type; u8 /* enum map_type */ type; bool referenced; u32 priv; u64 pgoff; Loading Loading @@ -125,6 +126,7 @@ void map__reloc_vmlinux(struct map *self); size_t __map_groups__fprintf_maps(struct map_groups *self, enum map_type type, int verbose, FILE *fp); void maps__insert(struct rb_root *maps, struct map *map); void maps__remove(struct rb_root *self, struct map *map); struct map *maps__find(struct rb_root *maps, u64 addr); void map_groups__init(struct map_groups *self); void map_groups__exit(struct map_groups *self); Loading @@ -144,6 +146,7 @@ struct machine *machines__findnew(struct rb_root *self, pid_t pid); char *machine__mmap_name(struct machine *self, char *bf, size_t size); int machine__init(struct machine *self, const char *root_dir, pid_t pid); void machine__exit(struct machine *self); void machine__delete(struct machine *self); /* * Default guest kernel is defined by parameter --guestkallsyms Loading @@ -165,6 +168,11 @@ static inline void map_groups__insert(struct map_groups *self, struct map *map) map->groups = self; } static inline void map_groups__remove(struct map_groups *self, struct map *map) { maps__remove(&self->maps[map->type], map); } static inline struct map *map_groups__find(struct map_groups *self, enum map_type type, u64 addr) { Loading tools/perf/util/session.c +8 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,12 @@ int perf_session__create_kernel_maps(struct perf_session *self) return ret; } static void perf_session__destroy_kernel_maps(struct perf_session *self) { machine__destroy_kernel_maps(&self->host_machine); machines__destroy_guest_kernel_maps(&self->machines); } struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) { size_t len = filename ? strlen(filename) + 1 : 0; Loading Loading @@ -150,6 +156,7 @@ static void perf_session__delete_threads(struct perf_session *self) void perf_session__delete(struct perf_session *self) { perf_header__exit(&self->header); perf_session__destroy_kernel_maps(self); perf_session__delete_dead_threads(self); perf_session__delete_threads(self); machine__exit(&self->host_machine); Loading @@ -159,6 +166,7 @@ void perf_session__delete(struct perf_session *self) void perf_session__remove_thread(struct perf_session *self, struct thread *th) { self->last_match = NULL; rb_erase(&th->rb_node, &self->threads); /* * We may have references to this thread, for instance in some hist_entry Loading tools/perf/util/symbol.c +43 −0 Original line number Diff line number Diff line Loading @@ -2107,6 +2107,36 @@ int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) return 0; } void machine__destroy_kernel_maps(struct machine *self) { enum map_type type; for (type = 0; type < MAP__NR_TYPES; ++type) { struct kmap *kmap; if (self->vmlinux_maps[type] == NULL) continue; kmap = map__kmap(self->vmlinux_maps[type]); map_groups__remove(&self->kmaps, self->vmlinux_maps[type]); if (kmap->ref_reloc_sym) { /* * ref_reloc_sym is shared among all maps, so free just * on one of them. */ if (type == MAP__FUNCTION) { free((char *)kmap->ref_reloc_sym->name); kmap->ref_reloc_sym->name = NULL; free(kmap->ref_reloc_sym); } kmap->ref_reloc_sym = NULL; } map__delete(self->vmlinux_maps[type]); self->vmlinux_maps[type] = NULL; } } int machine__create_kernel_maps(struct machine *self) { struct dso *kernel = machine__create_kernel(self); Loading Loading @@ -2351,6 +2381,19 @@ int machines__create_guest_kernel_maps(struct rb_root *self) return ret; } void machines__destroy_guest_kernel_maps(struct rb_root *self) { struct rb_node *next = rb_first(self); while (next) { struct machine *pos = rb_entry(next, struct machine, rb_node); next = rb_next(&pos->rb_node); rb_erase(&pos->rb_node, self); machine__delete(pos); } } int machine__load_kallsyms(struct machine *self, const char *filename, enum map_type type, symbol_filter_t filter) { Loading Loading
tools/perf/util/hist.c +2 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) if (self != NULL) { *self = *template; self->nr_events = 1; if (self->ms.map) self->ms.map->referenced = true; if (symbol_conf.use_callchain) callchain_init(self->callchain); } Loading
tools/perf/util/map.c +32 −17 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ void map__init(struct map *self, enum map_type type, self->unmap_ip = map__unmap_ip; RB_CLEAR_NODE(&self->rb_node); self->groups = NULL; self->referenced = false; } struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, Loading Loading @@ -387,6 +388,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, { struct rb_root *root = &self->maps[map->type]; struct rb_node *next = rb_first(root); int err = 0; while (next) { struct map *pos = rb_entry(next, struct map, rb_node); Loading @@ -402,12 +404,6 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, } rb_erase(&pos->rb_node, root); /* * We may have references to this map, for instance in some * hist_entry instances, so just move them to a separate * list. */ list_add_tail(&pos->node, &self->removed_maps[map->type]); /* * Now check if we need to create new maps for areas not * overlapped by the new map: Loading @@ -415,8 +411,10 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, if (map->start > pos->start) { struct map *before = map__clone(pos); if (before == NULL) return -ENOMEM; if (before == NULL) { err = -ENOMEM; goto move_map; } before->end = map->start - 1; map_groups__insert(self, before); Loading @@ -427,14 +425,27 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, if (map->end < pos->end) { struct map *after = map__clone(pos); if (after == NULL) return -ENOMEM; if (after == NULL) { err = -ENOMEM; goto move_map; } after->start = map->end + 1; map_groups__insert(self, after); if (verbose >= 2) map__fprintf(after, fp); } move_map: /* * If we have references, just move them to a separate list. */ if (pos->referenced) list_add_tail(&pos->node, &self->removed_maps[map->type]); else map__delete(pos); if (err) return err; } return 0; Loading Loading @@ -506,6 +517,11 @@ void maps__insert(struct rb_root *maps, struct map *map) rb_insert_color(&map->rb_node, maps); } void maps__remove(struct rb_root *self, struct map *map) { rb_erase(&map->rb_node, self); } struct map *maps__find(struct rb_root *maps, u64 ip) { struct rb_node **p = &maps->rb_node; Loading Loading @@ -551,13 +567,6 @@ static void dsos__delete(struct list_head *self) void machine__exit(struct machine *self) { struct kmap *kmap = map__kmap(self->vmlinux_maps[MAP__FUNCTION]); if (kmap->ref_reloc_sym) { free((char *)kmap->ref_reloc_sym->name); free(kmap->ref_reloc_sym); } map_groups__exit(&self->kmaps); dsos__delete(&self->user_dsos); dsos__delete(&self->kernel_dsos); Loading @@ -565,6 +574,12 @@ void machine__exit(struct machine *self) self->root_dir = NULL; } void machine__delete(struct machine *self) { machine__exit(self); free(self); } struct machine *machines__add(struct rb_root *self, pid_t pid, const char *root_dir) { Loading
tools/perf/util/map.h +9 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,8 @@ struct map { }; u64 start; u64 end; enum map_type type; u8 /* enum map_type */ type; bool referenced; u32 priv; u64 pgoff; Loading Loading @@ -125,6 +126,7 @@ void map__reloc_vmlinux(struct map *self); size_t __map_groups__fprintf_maps(struct map_groups *self, enum map_type type, int verbose, FILE *fp); void maps__insert(struct rb_root *maps, struct map *map); void maps__remove(struct rb_root *self, struct map *map); struct map *maps__find(struct rb_root *maps, u64 addr); void map_groups__init(struct map_groups *self); void map_groups__exit(struct map_groups *self); Loading @@ -144,6 +146,7 @@ struct machine *machines__findnew(struct rb_root *self, pid_t pid); char *machine__mmap_name(struct machine *self, char *bf, size_t size); int machine__init(struct machine *self, const char *root_dir, pid_t pid); void machine__exit(struct machine *self); void machine__delete(struct machine *self); /* * Default guest kernel is defined by parameter --guestkallsyms Loading @@ -165,6 +168,11 @@ static inline void map_groups__insert(struct map_groups *self, struct map *map) map->groups = self; } static inline void map_groups__remove(struct map_groups *self, struct map *map) { maps__remove(&self->maps[map->type], map); } static inline struct map *map_groups__find(struct map_groups *self, enum map_type type, u64 addr) { Loading
tools/perf/util/session.c +8 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,12 @@ int perf_session__create_kernel_maps(struct perf_session *self) return ret; } static void perf_session__destroy_kernel_maps(struct perf_session *self) { machine__destroy_kernel_maps(&self->host_machine); machines__destroy_guest_kernel_maps(&self->machines); } struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) { size_t len = filename ? strlen(filename) + 1 : 0; Loading Loading @@ -150,6 +156,7 @@ static void perf_session__delete_threads(struct perf_session *self) void perf_session__delete(struct perf_session *self) { perf_header__exit(&self->header); perf_session__destroy_kernel_maps(self); perf_session__delete_dead_threads(self); perf_session__delete_threads(self); machine__exit(&self->host_machine); Loading @@ -159,6 +166,7 @@ void perf_session__delete(struct perf_session *self) void perf_session__remove_thread(struct perf_session *self, struct thread *th) { self->last_match = NULL; rb_erase(&th->rb_node, &self->threads); /* * We may have references to this thread, for instance in some hist_entry Loading
tools/perf/util/symbol.c +43 −0 Original line number Diff line number Diff line Loading @@ -2107,6 +2107,36 @@ int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) return 0; } void machine__destroy_kernel_maps(struct machine *self) { enum map_type type; for (type = 0; type < MAP__NR_TYPES; ++type) { struct kmap *kmap; if (self->vmlinux_maps[type] == NULL) continue; kmap = map__kmap(self->vmlinux_maps[type]); map_groups__remove(&self->kmaps, self->vmlinux_maps[type]); if (kmap->ref_reloc_sym) { /* * ref_reloc_sym is shared among all maps, so free just * on one of them. */ if (type == MAP__FUNCTION) { free((char *)kmap->ref_reloc_sym->name); kmap->ref_reloc_sym->name = NULL; free(kmap->ref_reloc_sym); } kmap->ref_reloc_sym = NULL; } map__delete(self->vmlinux_maps[type]); self->vmlinux_maps[type] = NULL; } } int machine__create_kernel_maps(struct machine *self) { struct dso *kernel = machine__create_kernel(self); Loading Loading @@ -2351,6 +2381,19 @@ int machines__create_guest_kernel_maps(struct rb_root *self) return ret; } void machines__destroy_guest_kernel_maps(struct rb_root *self) { struct rb_node *next = rb_first(self); while (next) { struct machine *pos = rb_entry(next, struct machine, rb_node); next = rb_next(&pos->rb_node); rb_erase(&pos->rb_node, self); machine__delete(pos); } } int machine__load_kallsyms(struct machine *self, const char *filename, enum map_type type, symbol_filter_t filter) { Loading