Merge branch 'cando' into for-linus
[linux-2.6-microblaze.git] / tools / perf / util / event.c
index e3fa8d3..50771b5 100644 (file)
@@ -7,6 +7,23 @@
 #include "strlist.h"
 #include "thread.h"
 
+const char *event__name[] = {
+       [0]                      = "TOTAL",
+       [PERF_RECORD_MMAP]       = "MMAP",
+       [PERF_RECORD_LOST]       = "LOST",
+       [PERF_RECORD_COMM]       = "COMM",
+       [PERF_RECORD_EXIT]       = "EXIT",
+       [PERF_RECORD_THROTTLE]   = "THROTTLE",
+       [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE",
+       [PERF_RECORD_FORK]       = "FORK",
+       [PERF_RECORD_READ]       = "READ",
+       [PERF_RECORD_SAMPLE]     = "SAMPLE",
+       [PERF_RECORD_HEADER_ATTR]        = "ATTR",
+       [PERF_RECORD_HEADER_EVENT_TYPE]  = "EVENT_TYPE",
+       [PERF_RECORD_HEADER_TRACING_DATA]        = "TRACING_DATA",
+       [PERF_RECORD_HEADER_BUILD_ID]    = "BUILD_ID",
+};
+
 static pid_t event__synthesize_comm(pid_t pid, int full,
                                    event__handler_t process,
                                    struct perf_session *session)
@@ -172,17 +189,17 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
 
 int event__synthesize_modules(event__handler_t process,
                              struct perf_session *session,
-                             struct kernel_info *kerninfo)
+                             struct machine *machine)
 {
        struct rb_node *nd;
-       struct map_groups *kmaps = &kerninfo->kmaps;
+       struct map_groups *kmaps = &machine->kmaps;
        u16 misc;
 
        /*
         * kernel uses 0 for user space maps, see kernel/perf_event.c
         * __perf_event_mmap
         */
-       if (is_host_kernel(kerninfo))
+       if (machine__is_host(machine))
                misc = PERF_RECORD_MISC_KERNEL;
        else
                misc = PERF_RECORD_MISC_GUEST_KERNEL;
@@ -204,7 +221,7 @@ int event__synthesize_modules(event__handler_t process,
                                        (sizeof(ev.mmap.filename) - size));
                ev.mmap.start = pos->start;
                ev.mmap.len   = pos->end - pos->start;
-               ev.mmap.pid   = kerninfo->pid;
+               ev.mmap.pid   = machine->pid;
 
                memcpy(ev.mmap.filename, pos->dso->long_name,
                       pos->dso->long_name_len + 1);
@@ -267,7 +284,7 @@ static int find_symbol_cb(void *arg, const char *name, char type, u64 start)
 
 int event__synthesize_kernel_mmap(event__handler_t process,
                                  struct perf_session *session,
-                                 struct kernel_info *kerninfo,
+                                 struct machine *machine,
                                  const char *symbol_name)
 {
        size_t size;
@@ -288,8 +305,8 @@ int event__synthesize_kernel_mmap(event__handler_t process,
         */
        struct process_symbol_args args = { .name = symbol_name, };
 
-       mmap_name = kern_mmap_name(kerninfo, name_buff);
-       if (is_host_kernel(kerninfo)) {
+       mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff));
+       if (machine__is_host(machine)) {
                /*
                 * kernel uses PERF_RECORD_MISC_USER for user space maps,
                 * see kernel/perf_event.c __perf_event_mmap
@@ -298,10 +315,10 @@ int event__synthesize_kernel_mmap(event__handler_t process,
                filename = "/proc/kallsyms";
        } else {
                ev.header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
-               if (is_default_guest(kerninfo))
+               if (machine__is_default_guest(machine))
                        filename = (char *) symbol_conf.default_guest_kallsyms;
                else {
-                       sprintf(path, "%s/proc/kallsyms", kerninfo->root_dir);
+                       sprintf(path, "%s/proc/kallsyms", machine->root_dir);
                        filename = path;
                }
        }
@@ -309,7 +326,7 @@ int event__synthesize_kernel_mmap(event__handler_t process,
        if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0)
                return -ENOENT;
 
-       map = kerninfo->vmlinux_maps[MAP__FUNCTION];
+       map = machine->vmlinux_maps[MAP__FUNCTION];
        size = snprintf(ev.mmap.filename, sizeof(ev.mmap.filename),
                        "%s%s", mmap_name, symbol_name) + 1;
        size = ALIGN(size, sizeof(u64));
@@ -318,7 +335,7 @@ int event__synthesize_kernel_mmap(event__handler_t process,
        ev.mmap.pgoff = args.start;
        ev.mmap.start = map->start;
        ev.mmap.len   = map->end - ev.mmap.start;
-       ev.mmap.pid   = kerninfo->pid;
+       ev.mmap.pid   = machine->pid;
 
        return process(&ev, session);
 }
@@ -368,7 +385,7 @@ int event__process_comm(event_t *self, struct perf_session *session)
 int event__process_lost(event_t *self, struct perf_session *session)
 {
        dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost);
-       session->events_stats.lost += self->lost.lost;
+       session->hists.stats.total_lost += self->lost.lost;
        return 0;
 }
 
@@ -389,18 +406,18 @@ static int event__process_kernel_mmap(event_t *self,
 {
        struct map *map;
        char kmmap_prefix[PATH_MAX];
-       struct kernel_info *kerninfo;
+       struct machine *machine;
        enum dso_kernel_type kernel_type;
        bool is_kernel_mmap;
 
-       kerninfo = kerninfo__findnew(&session->kerninfo_root, self->mmap.pid);
-       if (!kerninfo) {
-               pr_err("Can't find id %d's kerninfo\n", self->mmap.pid);
+       machine = perf_session__findnew_machine(session, self->mmap.pid);
+       if (!machine) {
+               pr_err("Can't find id %d's machine\n", self->mmap.pid);
                goto out_problem;
        }
 
-       kern_mmap_name(kerninfo, kmmap_prefix);
-       if (is_host_kernel(kerninfo))
+       machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix));
+       if (machine__is_host(machine))
                kernel_type = DSO_TYPE_KERNEL;
        else
                kernel_type = DSO_TYPE_GUEST_KERNEL;
@@ -429,10 +446,8 @@ static int event__process_kernel_mmap(event_t *self,
                } else
                        strcpy(short_module_name, self->mmap.filename);
 
-               map = map_groups__new_module(&kerninfo->kmaps,
-                               self->mmap.start,
-                               self->mmap.filename,
-                               kerninfo);
+               map = machine__new_module(machine, self->mmap.start,
+                                         self->mmap.filename);
                if (map == NULL)
                        goto out_problem;
 
@@ -449,27 +464,25 @@ static int event__process_kernel_mmap(event_t *self,
                 * Should be there already, from the build-id table in
                 * the header.
                 */
-               struct dso *kernel = __dsos__findnew(&kerninfo->dsos__kernel,
-                               kmmap_prefix);
+               struct dso *kernel = __dsos__findnew(&machine->kernel_dsos,
+                                                    kmmap_prefix);
                if (kernel == NULL)
                        goto out_problem;
 
                kernel->kernel = kernel_type;
-               if (__map_groups__create_kernel_maps(&kerninfo->kmaps,
-                                       kerninfo->vmlinux_maps, kernel) < 0)
+               if (__machine__create_kernel_maps(machine, kernel) < 0)
                        goto out_problem;
 
-               event_set_kernel_mmap_len(kerninfo->vmlinux_maps, self);
-               perf_session__set_kallsyms_ref_reloc_sym(kerninfo->vmlinux_maps,
-                               symbol_name,
-                               self->mmap.pgoff);
-               if (is_default_guest(kerninfo)) {
+               event_set_kernel_mmap_len(machine->vmlinux_maps, self);
+               perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
+                                                        symbol_name,
+                                                        self->mmap.pgoff);
+               if (machine__is_default_guest(machine)) {
                        /*
                         * preload dso of guest kernel and modules
                         */
-                       dso__load(kernel,
-                               kerninfo->vmlinux_maps[MAP__FUNCTION],
-                               NULL);
+                       dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION],
+                                 NULL);
                }
        }
        return 0;
@@ -479,7 +492,7 @@ out_problem:
 
 int event__process_mmap(event_t *self, struct perf_session *session)
 {
-       struct kernel_info *kerninfo;
+       struct machine *machine;
        struct thread *thread;
        struct map *map;
        u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
@@ -497,9 +510,11 @@ int event__process_mmap(event_t *self, struct perf_session *session)
                return 0;
        }
 
+       machine = perf_session__find_host_machine(session);
+       if (machine == NULL)
+               goto out_problem;
        thread = perf_session__findnew(session, self->mmap.pid);
-       kerninfo = kerninfo__findhost(&session->kerninfo_root);
-       map = map__new(&kerninfo->dsos__user, self->mmap.start,
+       map = map__new(&machine->user_dsos, self->mmap.start,
                        self->mmap.len, self->mmap.pgoff,
                        self->mmap.pid, self->mmap.filename,
                        MAP__FUNCTION, session->cwd, session->cwdlen);
@@ -546,7 +561,7 @@ void thread__find_addr_map(struct thread *self,
                           struct addr_location *al)
 {
        struct map_groups *mg = &self->mg;
-       struct kernel_info *kerninfo = NULL;
+       struct machine *machine = NULL;
 
        al->thread = self;
        al->addr = addr;
@@ -555,19 +570,23 @@ void thread__find_addr_map(struct thread *self,
 
        if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
                al->level = 'k';
-               kerninfo = kerninfo__findhost(&session->kerninfo_root);
-               mg = &kerninfo->kmaps;
+               machine = perf_session__find_host_machine(session);
+               if (machine == NULL) {
+                       al->map = NULL;
+                       return;
+               }
+               mg = &machine->kmaps;
        } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
                al->level = '.';
-               kerninfo = kerninfo__findhost(&session->kerninfo_root);
+               machine = perf_session__find_host_machine(session);
        } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
                al->level = 'g';
-               kerninfo = kerninfo__find(&session->kerninfo_root, pid);
-               if (!kerninfo) {
+               machine = perf_session__find_machine(session, pid);
+               if (machine == NULL) {
                        al->map = NULL;
                        return;
                }
-               mg = &kerninfo->kmaps;
+               mg = &machine->kmaps;
        } else {
                /*
                 * 'u' means guest os user space.
@@ -603,10 +622,9 @@ try_again:
                 * in the whole kernel symbol list.
                 */
                if ((long long)al->addr < 0 &&
-                       cpumode == PERF_RECORD_MISC_KERNEL &&
-                       kerninfo &&
-                       mg != &kerninfo->kmaps)  {
-                       mg = &kerninfo->kmaps;
+                   cpumode == PERF_RECORD_MISC_KERNEL &&
+                   machine && mg != &machine->kmaps) {
+                       mg = &machine->kmaps;
                        goto try_again;
                }
        } else
@@ -631,8 +649,10 @@ static void dso__calc_col_width(struct dso *self)
        if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
            (!symbol_conf.dso_list ||
             strlist__has_entry(symbol_conf.dso_list, self->name))) {
-               unsigned int slen = strlen(self->name);
-               if (slen > dsos__col_width)
+               u16 slen = self->short_name_len;
+               if (verbose)
+                       slen = self->long_name_len;
+               if (dsos__col_width < slen)
                        dsos__col_width = slen;
        }
 
@@ -653,6 +673,16 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
                goto out_filtered;
 
        dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
+       /*
+        * Have we already created the kernel maps for the host machine?
+        *
+        * This should have happened earlier, when we processed the kernel MMAP
+        * events, but for older perf.data files there was no such thing, so do
+        * it now.
+        */
+       if (cpumode == PERF_RECORD_MISC_KERNEL &&
+           session->host_machine.vmlinux_maps[MAP__FUNCTION] == NULL)
+               machine__create_kernel_maps(&session->host_machine);
 
        thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
                              self->ip.pid, self->ip.ip, al);
@@ -679,6 +709,13 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
                        dso__calc_col_width(al->map->dso);
 
                al->sym = map__find_symbol(al->map, al->addr, filter);
+       } else {
+               const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
+
+               if (dsos__col_width < unresolved_col_width &&
+                   !symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
+                   !symbol_conf.dso_list)
+                       dsos__col_width = unresolved_col_width;
        }
 
        if (symbol_conf.sym_list && al->sym &&
@@ -718,6 +755,7 @@ int event__parse_sample(event_t *event, u64 type, struct sample_data *data)
                array++;
        }
 
+       data->id = -1ULL;
        if (type & PERF_SAMPLE_ID) {
                data->id = *array;
                array++;