perf session: Move kmaps to perf_session
authorArnaldo Carvalho de Melo <acme@redhat.com>
Sun, 13 Dec 2009 21:50:29 +0000 (19:50 -0200)
committerIngo Molnar <mingo@elte.hu>
Mon, 14 Dec 2009 15:57:17 +0000 (16:57 +0100)
There is still some more work to do to disentangle map creation
from DSO loading, but this happens only for the kernel, and for
the early adopters of perf diff, where this disentanglement
matters most, we'll be testing different kernels, so no problem
here.

Further clarification: right now we create the kernel maps for
the various modules and discontiguous kernel text maps when
loading the DSO, we should do it as a two step process, first
creating the maps, for multiple mappings with the same DSO
store, then doing the dso load just once, for the first hit on
one of the maps sharing this DSO backing store.

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: <1260741029-4430-6-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
18 files changed:
tools/perf/builtin-annotate.c
tools/perf/builtin-buildid-list.c
tools/perf/builtin-kmem.c
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/builtin-sched.c
tools/perf/builtin-timechart.c
tools/perf/builtin-top.c
tools/perf/builtin-trace.c
tools/perf/util/event.c
tools/perf/util/event.h
tools/perf/util/map.c
tools/perf/util/session.c
tools/perf/util/session.h
tools/perf/util/symbol.c
tools/perf/util/symbol.h
tools/perf/util/thread.c
tools/perf/util/thread.h

index 795f865c1366f415fde8e5c741c2b2e54dfcb5cc..e44c54c79be474e71eb602ed2bd70dd1b7d2b7f5 100644 (file)
@@ -463,7 +463,7 @@ static struct perf_event_ops event_ops = {
 static int __cmd_annotate(void)
 {
        struct perf_session *session = perf_session__new(input_name, O_RDONLY,
-                                                        force);
+                                                        force, &symbol_conf);
        int ret;
 
        if (session == NULL)
index 2629f76d95fe5acfc85f952b1f1961c55aaaeda5..7c36e4b2eccf31dc3283853894b30c82d86b6ddd 100644 (file)
@@ -54,8 +54,8 @@ static int perf_file_section__process_buildids(struct perf_file_section *self,
 static int __cmd_buildid_list(void)
 {
        int err = -1;
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY, force);
-
+       struct perf_session *session = perf_session__new(input_name, O_RDONLY,
+                                                        force, NULL);
        if (session == NULL)
                return -1;
 
index de194958fe6e17f8b087a8719153ccfc0dca2630..e79ecbc17181c12d920ed2d3ed6eea66b1f350da 100644 (file)
@@ -364,19 +364,6 @@ static struct perf_event_ops event_ops = {
        .sample_type_check      = sample_type_check,
 };
 
-static int read_events(void)
-{
-       int err;
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
-
-       if (session == NULL)
-               return -ENOMEM;
-
-       err = perf_session__process_events(session, &event_ops);
-       perf_session__delete(session);
-       return err;
-}
-
 static double fragmentation(unsigned long n_req, unsigned long n_alloc)
 {
        if (n_alloc == 0)
@@ -385,7 +372,8 @@ static double fragmentation(unsigned long n_req, unsigned long n_alloc)
                return 100.0 - (100.0 * n_req / n_alloc);
 }
 
-static void __print_result(struct rb_root *root, int n_lines, int is_caller)
+static void __print_result(struct rb_root *root, struct perf_session *session,
+                          int n_lines, int is_caller)
 {
        struct rb_node *next;
 
@@ -406,7 +394,7 @@ static void __print_result(struct rb_root *root, int n_lines, int is_caller)
                if (is_caller) {
                        addr = data->call_site;
                        if (!raw_ip)
-                               sym = map_groups__find_function(kmaps, addr, NULL);
+                               sym = map_groups__find_function(&session->kmaps, session, addr, NULL);
                } else
                        addr = data->ptr;
 
@@ -447,12 +435,12 @@ static void print_summary(void)
        printf("Cross CPU allocations: %lu/%lu\n", nr_cross_allocs, nr_allocs);
 }
 
-static void print_result(void)
+static void print_result(struct perf_session *session)
 {
        if (caller_flag)
-               __print_result(&root_caller_sorted, caller_lines, 1);
+               __print_result(&root_caller_sorted, session, caller_lines, 1);
        if (alloc_flag)
-               __print_result(&root_alloc_sorted, alloc_lines, 0);
+               __print_result(&root_alloc_sorted, session, alloc_lines, 0);
        print_summary();
 }
 
@@ -520,12 +508,21 @@ static void sort_result(void)
 
 static int __cmd_kmem(void)
 {
+       int err;
+       struct perf_session *session = perf_session__new(input_name, O_RDONLY,
+                                                        0, NULL);
+       if (session == NULL)
+               return -ENOMEM;
+
        setup_pager();
-       read_events();
+       err = perf_session__process_events(session, &event_ops);
+       if (err != 0)
+               goto out_delete;
        sort_result();
-       print_result();
-
-       return 0;
+       print_result(session);
+out_delete:
+       perf_session__delete(session);
+       return err;
 }
 
 static const char * const kmem_usage[] = {
index b7e15a1b1ec2d29a9e03d7bb417a51f76f34c532..a66a58d52818b971822f05b6db71493bf72f86a4 100644 (file)
@@ -442,7 +442,7 @@ static int __cmd_record(int argc, const char **argv)
                exit(-1);
        }
 
-       session = perf_session__new(output_name, O_WRONLY, force);
+       session = perf_session__new(output_name, O_WRONLY, force, NULL);
        if (session == NULL) {
                pr_err("Not enough memory for reading perf file header\n");
                return -1;
index efa8147b899118e10396e74f8d6df2925a71fb71..3487224670a8779dab6525c6a4ccf336a0fd3d4e 100644 (file)
@@ -414,6 +414,7 @@ static int call__match(struct symbol *sym)
 }
 
 static struct symbol **resolve_callchain(struct thread *thread,
+                                        struct perf_session *session,
                                         struct ip_callchain *chain,
                                         struct symbol **parent)
 {
@@ -447,8 +448,8 @@ static struct symbol **resolve_callchain(struct thread *thread,
                        continue;
                }
 
-               thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
-                                          ip, &al, NULL);
+               thread__find_addr_location(thread, session, cpumode,
+                                          MAP__FUNCTION, ip, &al, NULL);
                if (al.sym != NULL) {
                        if (sort__has_parent && !*parent &&
                            call__match(al.sym))
@@ -467,6 +468,7 @@ static struct symbol **resolve_callchain(struct thread *thread,
  */
 
 static int hist_entry__add(struct addr_location *al,
+                          struct perf_session *session,
                           struct ip_callchain *chain, u64 count)
 {
        struct symbol **syms = NULL, *parent = NULL;
@@ -474,7 +476,7 @@ static int hist_entry__add(struct addr_location *al,
        struct hist_entry *he;
 
        if ((sort__has_parent || callchain) && chain)
-               syms = resolve_callchain(al->thread, chain, &parent);
+               syms = resolve_callchain(al->thread, session, chain, &parent);
 
        he = __hist_entry__add(al, parent, count, &hit);
        if (he == NULL)
@@ -650,7 +652,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
 
        cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 
-       thread__find_addr_location(thread, cpumode,
+       thread__find_addr_location(thread, session, cpumode,
                                   MAP__FUNCTION, data.ip, &al, NULL);
        /*
         * We have to do this here as we may have a dso with no symbol hit that
@@ -669,7 +671,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name))
                return 0;
 
-       if (hist_entry__add(&al, data.callchain, data.period)) {
+       if (hist_entry__add(&al, session, data.callchain, data.period)) {
                pr_debug("problem incrementing symbol count, skipping event\n");
                return -1;
        }
@@ -763,7 +765,7 @@ static int __cmd_report(void)
        int ret;
        struct perf_session *session;
 
-       session = perf_session__new(input_name, O_RDONLY, force);
+       session = perf_session__new(input_name, O_RDONLY, force, &symbol_conf);
        if (session == NULL)
                return -ENOMEM;
 
index 8d58d9e07a7bd8274049578ca4ab6940f9597a0e..bce05dff6dfeb8886eb9ec939d0331d43c9de2d3 100644 (file)
@@ -1679,8 +1679,8 @@ static struct perf_event_ops event_ops = {
 static int read_events(void)
 {
        int err;
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
-
+       struct perf_session *session = perf_session__new(input_name, O_RDONLY,
+                                                        0, NULL);
        if (session == NULL)
                return -ENOMEM;
 
index b5211facddc6cb6d3dbf877b28f1f5d44d610935..27018531404b68761adef79aa9a3bd43a3950087 100644 (file)
@@ -1056,7 +1056,8 @@ static struct perf_event_ops event_ops = {
 
 static int __cmd_timechart(void)
 {
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
+       struct perf_session *session = perf_session__new(input_name, O_RDONLY,
+                                                        0, NULL);
        int ret;
 
        if (session == NULL)
index 0f7a4da2924c7e0edeb89b1b67dd1909a56e3f37..3b212bb2e4dfdfdb5fc86c5dfddc1b693f68decb 100644 (file)
@@ -1162,8 +1162,8 @@ static int __cmd_top(void)
         * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
         * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
         */
-       struct perf_session *session = perf_session__new(NULL, O_WRONLY, false);
-
+       struct perf_session *session = perf_session__new(NULL, O_WRONLY, false,
+                                                        &symbol_conf);
        if (session == NULL)
                return -ENOMEM;
 
index d76532375054768344a1a898a13ba9e02cec2c6a..9d89ae423ca594f9d9b429b54ac13c7b4365d359 100644 (file)
@@ -318,7 +318,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
 
        setup_pager();
 
-       session = perf_session__new(input_name, O_RDONLY, 0);
+       session = perf_session__new(input_name, O_RDONLY, 0, NULL);
        if (session == NULL)
                return -ENOMEM;
 
index 2d09c29b3a6c0ff1424afbe6532a55622c5c9793..222efb1fc3bdbc3fa7acd0916caa7c64e7dbe480 100644 (file)
@@ -256,7 +256,8 @@ int event__process_task(event_t *self, struct perf_session *session)
        return 0;
 }
 
-void thread__find_addr_location(struct thread *self, u8 cpumode,
+void thread__find_addr_location(struct thread *self,
+                               struct perf_session *session, u8 cpumode,
                                enum map_type type, u64 addr,
                                struct addr_location *al,
                                symbol_filter_t filter)
@@ -268,7 +269,7 @@ void thread__find_addr_location(struct thread *self, u8 cpumode,
 
        if (cpumode & PERF_RECORD_MISC_KERNEL) {
                al->level = 'k';
-               mg = kmaps;
+               mg = &session->kmaps;
        } else if (cpumode & PERF_RECORD_MISC_USER)
                al->level = '.';
        else {
@@ -289,14 +290,14 @@ try_again:
                 * "[vdso]" dso, but for now lets use the old trick of looking
                 * in the whole kernel symbol list.
                 */
-               if ((long long)al->addr < 0 && mg != kmaps) {
-                       mg = kmaps;
+               if ((long long)al->addr < 0 && mg != &session->kmaps) {
+                       mg = &session->kmaps;
                        goto try_again;
                }
                al->sym = NULL;
        } else {
                al->addr = al->map->map_ip(al->map, al->addr);
-               al->sym = map__find_symbol(al->map, al->addr, filter);
+               al->sym = map__find_symbol(al->map, session, al->addr, filter);
        }
 }
 
@@ -311,7 +312,7 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
 
        dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
 
-       thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
+       thread__find_addr_location(thread, session, cpumode, MAP__FUNCTION,
                                   self->ip.ip, al, filter);
        dump_printf(" ...... dso: %s\n",
                    al->map ? al->map->dso->long_name :
index bb090257570e07a1a1c6d733d4cad3aa2c2261c5..035ecf3c25cc2b9d0a5a52516a04e12df66adacf 100644 (file)
@@ -149,15 +149,17 @@ void map__delete(struct map *self);
 struct map *map__clone(struct map *self);
 int map__overlap(struct map *l, struct map *r);
 size_t map__fprintf(struct map *self, FILE *fp);
-struct symbol *map__find_symbol(struct map *self, u64 addr,
-                               symbol_filter_t filter);
+
+struct perf_session;
+
+struct symbol *map__find_symbol(struct map *self, struct perf_session *session,
+                               u64 addr, symbol_filter_t filter);
 struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
+                                       struct perf_session *session,
                                        symbol_filter_t filter);
 void map__fixup_start(struct map *self);
 void map__fixup_end(struct map *self);
 
-struct perf_session;
-
 int event__synthesize_thread(pid_t pid,
                             int (*process)(event_t *event,
                                            struct perf_session *session),
index 76bdca640a9b5fcde2f7206f39940dc23e4750e8..8b3dd467adb5f29f80c450e7c211c92ad1b350e7 100644 (file)
@@ -104,10 +104,11 @@ void map__fixup_end(struct map *self)
 
 #define DSO__DELETED "(deleted)"
 
-static int map__load(struct map *self, symbol_filter_t filter)
+static int map__load(struct map *self, struct perf_session *session,
+                    symbol_filter_t filter)
 {
        const char *name = self->dso->long_name;
-       int nr = dso__load(self->dso, self, filter);
+       int nr = dso__load(self->dso, self, session, filter);
 
        if (nr < 0) {
                if (self->dso->has_build_id) {
@@ -143,19 +144,20 @@ static int map__load(struct map *self, symbol_filter_t filter)
        return 0;
 }
 
-struct symbol *map__find_symbol(struct map *self, u64 addr,
-                               symbol_filter_t filter)
+struct symbol *map__find_symbol(struct map *self, struct perf_session *session,
+                               u64 addr, symbol_filter_t filter)
 {
-       if (!dso__loaded(self->dso, self->type) && map__load(self, filter) < 0)
+       if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0)
                return NULL;
 
        return dso__find_symbol(self->dso, self->type, addr);
 }
 
 struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
+                                       struct perf_session *session,
                                        symbol_filter_t filter)
 {
-       if (!dso__loaded(self->dso, self->type) && map__load(self, filter) < 0)
+       if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0)
                return NULL;
 
        if (!dso__sorted_by_name(self->dso, self->type))
index 09836a537fc5bd8b4cca4ec1ccba008aadadd75a..fe87a2f2e5a52cf72b00d6926ecc11144a121db3 100644 (file)
@@ -49,7 +49,7 @@ out_close:
 }
 
 struct perf_session *perf_session__new(const char *filename, int mode,
-                                      bool force)
+                                      bool force, struct symbol_conf *conf)
 {
        size_t len = filename ? strlen(filename) + 1 : 0;
        struct perf_session *self = zalloc(sizeof(*self) + len);
@@ -58,7 +58,7 @@ struct perf_session *perf_session__new(const char *filename, int mode,
                goto out;
 
        if (perf_header__init(&self->header) < 0)
-               goto out_delete;
+               goto out_free;
 
        memcpy(self->filename, filename, len);
        self->threads = RB_ROOT;
@@ -66,16 +66,21 @@ struct perf_session *perf_session__new(const char *filename, int mode,
        self->mmap_window = 32;
        self->cwd = NULL;
        self->cwdlen = 0;
+       map_groups__init(&self->kmaps);
 
-       if (mode == O_RDONLY && perf_session__open(self, force) < 0) {
-               perf_session__delete(self);
-               self = NULL;
-       }
+       if (perf_session__create_kernel_maps(self, conf) < 0)
+               goto out_delete;
+
+       if (mode == O_RDONLY && perf_session__open(self, force) < 0)
+               goto out_delete;
 out:
        return self;
-out_delete:
+out_free:
        free(self);
        return NULL;
+out_delete:
+       perf_session__delete(self);
+       return NULL;
 }
 
 void perf_session__delete(struct perf_session *self)
index 1dbef7cdd4892e1a821c390854fd8579ecfa2ed9..20b2c9cc834b17db1210aeaa7bf4410ac62ce83d 100644 (file)
@@ -3,19 +3,23 @@
 
 #include "event.h"
 #include "header.h"
+#include "thread.h"
 #include <linux/rbtree.h>
 
 struct thread;
+struct symbol_conf;
 
 struct perf_session {
        struct perf_header      header;
        unsigned long           size;
        unsigned long           mmap_window;
+       struct map_groups       kmaps;
        struct rb_root          threads;
        struct thread           *last_match;
        int                     fd;
        int                     cwdlen;
        char                    *cwd;
+       bool                    use_modules;
        char filename[0];
 };
 
@@ -37,7 +41,7 @@ struct perf_event_ops {
 };
 
 struct perf_session *perf_session__new(const char *filename, int mode,
-                                      bool force);
+                                      bool force, struct symbol_conf *conf);
 void perf_session__delete(struct perf_session *self);
 
 int perf_session__process_events(struct perf_session *self,
index d3d9fed74f1dbcb56fc1ba66aa5cbc09e53e426c..185b9eec192be18df25a9c368e0fba20963dfb0e 100644 (file)
@@ -1,5 +1,6 @@
 #include "util.h"
 #include "../perf.h"
+#include "session.h"
 #include "string.h"
 #include "symbol.h"
 #include "thread.h"
@@ -31,7 +32,7 @@ enum dso_origin {
 static void dsos__add(struct list_head *head, struct dso *dso);
 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
 static int dso__load_kernel_sym(struct dso *self, struct map *map,
-                               struct map_groups *mg, symbol_filter_t filter);
+                               struct perf_session *session, symbol_filter_t filter);
 unsigned int symbol__priv_size;
 static int vmlinux_path__nr_entries;
 static char **vmlinux_path;
@@ -41,9 +42,6 @@ static struct symbol_conf symbol_conf__defaults = {
        .try_vmlinux_path = true,
 };
 
-static struct map_groups kmaps_mem;
-struct map_groups *kmaps = &kmaps_mem;
-
 bool dso__loaded(const struct dso *self, enum map_type type)
 {
        return self->loaded & (1 << type);
@@ -456,7 +454,7 @@ out_failure:
  * the original ELF section names vmlinux have.
  */
 static int dso__split_kallsyms(struct dso *self, struct map *map,
-                              struct map_groups *mg, symbol_filter_t filter)
+                              struct perf_session *session, symbol_filter_t filter)
 {
        struct map *curr_map = map;
        struct symbol *pos;
@@ -473,13 +471,13 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
 
                module = strchr(pos->name, '\t');
                if (module) {
-                       if (!mg->use_modules)
+                       if (!session->use_modules)
                                goto discard_symbol;
 
                        *module++ = '\0';
 
                        if (strcmp(self->name, module)) {
-                               curr_map = map_groups__find_by_name(mg, map->type, module);
+                               curr_map = map_groups__find_by_name(&session->kmaps, map->type, module);
                                if (curr_map == NULL) {
                                        pr_debug("/proc/{kallsyms,modules} "
                                                 "inconsistency!\n");
@@ -510,7 +508,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                        }
 
                        curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
-                       map_groups__insert(mg, curr_map);
+                       map_groups__insert(&session->kmaps, curr_map);
                        ++kernel_range;
                }
 
@@ -531,7 +529,7 @@ discard_symbol:             rb_erase(&pos->rb_node, root);
 
 
 static int dso__load_kallsyms(struct dso *self, struct map *map,
-                             struct map_groups *mg, symbol_filter_t filter)
+                             struct perf_session *session, symbol_filter_t filter)
 {
        if (dso__load_all_kallsyms(self, map) < 0)
                return -1;
@@ -539,14 +537,7 @@ static int dso__load_kallsyms(struct dso *self, struct map *map,
        symbols__fixup_end(&self->symbols[map->type]);
        self->origin = DSO__ORIG_KERNEL;
 
-       return dso__split_kallsyms(self, map, mg, filter);
-}
-
-size_t kernel_maps__fprintf(FILE *fp)
-{
-       size_t printed = fprintf(fp, "Kernel maps:\n");
-       printed += map_groups__fprintf_maps(kmaps, fp);
-       return printed + fprintf(fp, "END kernel maps\n");
+       return dso__split_kallsyms(self, map, session, filter);
 }
 
 static int dso__load_perf_map(struct dso *self, struct map *map,
@@ -873,7 +864,7 @@ static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type
 }
 
 static int dso__load_sym(struct dso *self, struct map *map,
-                        struct map_groups *mg, const char *name, int fd,
+                        struct perf_session *session, const char *name, int fd,
                         symbol_filter_t filter, int kernel, int kmodule)
 {
        struct map *curr_map = map;
@@ -977,7 +968,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
                        snprintf(dso_name, sizeof(dso_name),
                                 "%s%s", self->short_name, section_name);
 
-                       curr_map = map_groups__find_by_name(mg, map->type, dso_name);
+                       curr_map = map_groups__find_by_name(&session->kmaps, map->type, dso_name);
                        if (curr_map == NULL) {
                                u64 start = sym.st_value;
 
@@ -996,7 +987,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
                                curr_map->map_ip = identity__map_ip;
                                curr_map->unmap_ip = identity__map_ip;
                                curr_dso->origin = DSO__ORIG_KERNEL;
-                               map_groups__insert(kmaps, curr_map);
+                               map_groups__insert(&session->kmaps, curr_map);
                                dsos__add(&dsos__kernel, curr_dso);
                        } else
                                curr_dso = curr_map->dso;
@@ -1211,7 +1202,8 @@ char dso__symtab_origin(const struct dso *self)
        return origin[self->origin];
 }
 
-int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
+int dso__load(struct dso *self, struct map *map, struct perf_session *session,
+             symbol_filter_t filter)
 {
        int size = PATH_MAX;
        char *name;
@@ -1222,7 +1214,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
        dso__set_loaded(self, map->type);
 
        if (self->kernel)
-               return dso__load_kernel_sym(self, map, kmaps, filter);
+               return dso__load_kernel_sym(self, map, session, filter);
 
        name = malloc(size);
        if (!name)
@@ -1323,7 +1315,7 @@ struct map *map_groups__find_by_name(struct map_groups *self,
        return NULL;
 }
 
-static int dsos__set_modules_path_dir(char *dirname)
+static int perf_session__set_modules_path_dir(struct perf_session *self, char *dirname)
 {
        struct dirent *dent;
        DIR *dir = opendir(dirname);
@@ -1343,7 +1335,7 @@ static int dsos__set_modules_path_dir(char *dirname)
 
                        snprintf(path, sizeof(path), "%s/%s",
                                 dirname, dent->d_name);
-                       if (dsos__set_modules_path_dir(path) < 0)
+                       if (perf_session__set_modules_path_dir(self, path) < 0)
                                goto failure;
                } else {
                        char *dot = strrchr(dent->d_name, '.'),
@@ -1357,7 +1349,7 @@ static int dsos__set_modules_path_dir(char *dirname)
                                 (int)(dot - dent->d_name), dent->d_name);
 
                        strxfrchar(dso_name, '-', '_');
-                       map = map_groups__find_by_name(kmaps, MAP__FUNCTION, dso_name);
+                       map = map_groups__find_by_name(&self->kmaps, MAP__FUNCTION, dso_name);
                        if (map == NULL)
                                continue;
 
@@ -1377,7 +1369,7 @@ failure:
        return -1;
 }
 
-static int dsos__set_modules_path(void)
+static int perf_session__set_modules_path(struct perf_session *self)
 {
        struct utsname uts;
        char modules_path[PATH_MAX];
@@ -1388,7 +1380,7 @@ static int dsos__set_modules_path(void)
        snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
                 uts.release);
 
-       return dsos__set_modules_path_dir(modules_path);
+       return perf_session__set_modules_path_dir(self, modules_path);
 }
 
 /*
@@ -1410,7 +1402,7 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
        return self;
 }
 
-static int map_groups__create_module_maps(struct map_groups *self)
+static int perf_session__create_module_maps(struct perf_session *self)
 {
        char *line = NULL;
        size_t n;
@@ -1467,14 +1459,14 @@ static int map_groups__create_module_maps(struct map_groups *self)
                        dso->has_build_id = true;
 
                dso->origin = DSO__ORIG_KMODULE;
-               map_groups__insert(self, map);
+               map_groups__insert(&self->kmaps, map);
                dsos__add(&dsos__kernel, dso);
        }
 
        free(line);
        fclose(file);
 
-       return dsos__set_modules_path();
+       return perf_session__set_modules_path(self);
 
 out_delete_line:
        free(line);
@@ -1483,7 +1475,7 @@ out_failure:
 }
 
 static int dso__load_vmlinux(struct dso *self, struct map *map,
-                            struct map_groups *mg,
+                            struct perf_session *session,
                             const char *vmlinux, symbol_filter_t filter)
 {
        int err = -1, fd;
@@ -1517,14 +1509,14 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
                return -1;
 
        dso__set_loaded(self, map->type);
-       err = dso__load_sym(self, map, mg, self->long_name, fd, filter, 1, 0);
+       err = dso__load_sym(self, map, session, self->long_name, fd, filter, 1, 0);
        close(fd);
 
        return err;
 }
 
 static int dso__load_kernel_sym(struct dso *self, struct map *map,
-                               struct map_groups *mg, symbol_filter_t filter)
+                               struct perf_session *session, symbol_filter_t filter)
 {
        int err;
        bool is_kallsyms;
@@ -1534,7 +1526,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
                pr_debug("Looking at the vmlinux_path (%d entries long)\n",
                         vmlinux_path__nr_entries);
                for (i = 0; i < vmlinux_path__nr_entries; ++i) {
-                       err = dso__load_vmlinux(self, map, mg,
+                       err = dso__load_vmlinux(self, map, session,
                                                vmlinux_path[i], filter);
                        if (err > 0) {
                                pr_debug("Using %s for symbols\n",
@@ -1550,12 +1542,12 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
        if (is_kallsyms)
                goto do_kallsyms;
 
-       err = dso__load_vmlinux(self, map, mg, self->long_name, filter);
+       err = dso__load_vmlinux(self, map, session, self->long_name, filter);
        if (err <= 0) {
                pr_info("The file %s cannot be used, "
                        "trying to use /proc/kallsyms...", self->long_name);
 do_kallsyms:
-               err = dso__load_kallsyms(self, map, mg, filter);
+               err = dso__load_kallsyms(self, map, session, filter);
                if (err > 0 && !is_kallsyms)
                         dso__set_long_name(self, strdup("[kernel.kallsyms]"));
        }
@@ -1757,23 +1749,30 @@ int symbol__init(struct symbol_conf *conf)
        if (pconf->sort_by_name)
                symbol__priv_size += (sizeof(struct symbol_name_rb_node) -
                                      sizeof(struct symbol));
-       map_groups__init(kmaps);
 
        if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
                return -1;
 
-       if (map_groups__create_kernel_maps(kmaps, pconf->vmlinux_name) < 0) {
-               vmlinux_path__exit();
+       return 0;
+}
+
+int perf_session__create_kernel_maps(struct perf_session *self,
+                                    struct symbol_conf *conf)
+{
+       const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;
+
+       if (map_groups__create_kernel_maps(&self->kmaps,
+                                          pconf->vmlinux_name) < 0)
                return -1;
-       }
 
-       kmaps->use_modules = pconf->use_modules;
-       if (pconf->use_modules && map_groups__create_module_maps(kmaps) < 0)
-               pr_debug("Failed to load list of modules in use, "
-                        "continuing...\n");
+       self->use_modules = pconf->use_modules;
+
+       if (pconf->use_modules && perf_session__create_module_maps(self) < 0)
+               pr_debug("Failed to load list of modules for session %s, "
+                        "continuing...\n", self->filename);
        /*
         * Now that we have all the maps created, just set the ->end of them:
         */
-       map_groups__fixup_end(kmaps);
+       map_groups__fixup_end(&self->kmaps);
        return 0;
 }
index cf99f88adf39c52d2010e8b6e0c580307dbc69fa..941ef331790ef70d80cade87fa89af2fbab14859 100644 (file)
@@ -98,8 +98,11 @@ bool dso__sorted_by_name(const struct dso *self, enum map_type type);
 
 void dso__sort_by_name(struct dso *self, enum map_type type);
 
+struct perf_session;
+
 struct dso *dsos__findnew(const char *name);
-int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
+int dso__load(struct dso *self, struct map *map, struct perf_session *session,
+             symbol_filter_t filter);
 void dsos__fprintf(FILE *fp);
 size_t dsos__fprintf_buildid(FILE *fp);
 
@@ -116,12 +119,10 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size);
 bool dsos__read_build_ids(void);
 int build_id__sprintf(u8 *self, int len, char *bf);
 
-size_t kernel_maps__fprintf(FILE *fp);
-
 int symbol__init(struct symbol_conf *conf);
+int perf_session__create_kernel_maps(struct perf_session *self,
+                                    struct symbol_conf *conf);
 
-struct map_groups;
-struct map_groups *kmaps;
 extern struct list_head dsos__user, dsos__kernel;
 extern struct dso *vdso;
 #endif /* __PERF_SYMBOL */
index 634b7f7140d52796f60c168aeed8d1f1758c6916..4a08dcf50b68c4bd9858c17fd569ae6acdec8257 100644 (file)
@@ -282,13 +282,14 @@ size_t perf_session__fprintf(struct perf_session *self, FILE *fp)
 }
 
 struct symbol *map_groups__find_symbol(struct map_groups *self,
+                                      struct perf_session *session,
                                       enum map_type type, u64 addr,
                                       symbol_filter_t filter)
 {
        struct map *map = map_groups__find(self, type, addr);
 
        if (map != NULL)
-               return map__find_symbol(map, map->map_ip(map, addr), filter);
+               return map__find_symbol(map, session, map->map_ip(map, addr), filter);
 
        return NULL;
 }
index e93abf2d9cb657ad9254030ab1cbe2f3fe1e021c..c206f72c88811fb959d26d984b2e7a3506621d9a 100644 (file)
@@ -8,7 +8,6 @@
 struct map_groups {
        struct rb_root          maps[MAP__NR_TYPES];
        struct list_head        removed_maps[MAP__NR_TYPES];
-       bool                    use_modules;
 };
 
 struct thread {
@@ -49,19 +48,21 @@ static inline struct map *thread__find_map(struct thread *self,
        return self ? map_groups__find(&self->mg, type, addr) : NULL;
 }
 
-void thread__find_addr_location(struct thread *self, u8 cpumode,
+void thread__find_addr_location(struct thread *self,
+                               struct perf_session *session, u8 cpumode,
                                enum map_type type, u64 addr,
                                struct addr_location *al,
                                symbol_filter_t filter);
 struct symbol *map_groups__find_symbol(struct map_groups *self,
+                                      struct perf_session *session,
                                       enum map_type type, u64 addr,
                                       symbol_filter_t filter);
 
 static inline struct symbol *
-map_groups__find_function(struct map_groups *self, u64 addr,
-                         symbol_filter_t filter)
+map_groups__find_function(struct map_groups *self, struct perf_session *session,
+                         u64 addr, symbol_filter_t filter)
 {
-       return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter);
+       return map_groups__find_symbol(self, session, MAP__FUNCTION, addr, filter);
 }
 
 struct map *map_groups__find_by_name(struct map_groups *self,