]> Pileus Git - ~andy/linux/blobdiff - tools/perf/util/machine.c
Merge tag 'v3.11-rc5' into perf/core
[~andy/linux] / tools / perf / util / machine.c
index b2ecad6ec46b1c87e9f2decc4b790cf497fa7933..4514e7e9b659df6244e060d1663eef2b0f00e3ce 100644 (file)
@@ -25,6 +25,8 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
        machine->kmaps.machine = machine;
        machine->pid = pid;
 
+       machine->symbol_filter = NULL;
+
        machine->root_dir = strdup(root_dir);
        if (machine->root_dir == NULL)
                return -ENOMEM;
@@ -95,6 +97,7 @@ void machines__init(struct machines *machines)
 {
        machine__init(&machines->host, "", HOST_KERNEL_ID);
        machines->guests = RB_ROOT;
+       machines->symbol_filter = NULL;
 }
 
 void machines__exit(struct machines *machines)
@@ -118,6 +121,8 @@ struct machine *machines__add(struct machines *machines, pid_t pid,
                return NULL;
        }
 
+       machine->symbol_filter = machines->symbol_filter;
+
        while (*p != NULL) {
                parent = *p;
                pos = rb_entry(parent, struct machine, rb_node);
@@ -133,6 +138,21 @@ struct machine *machines__add(struct machines *machines, pid_t pid,
        return machine;
 }
 
+void machines__set_symbol_filter(struct machines *machines,
+                                symbol_filter_t symbol_filter)
+{
+       struct rb_node *nd;
+
+       machines->symbol_filter = symbol_filter;
+       machines->host.symbol_filter = symbol_filter;
+
+       for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) {
+               struct machine *machine = rb_entry(nd, struct machine, rb_node);
+
+               machine->symbol_filter = symbol_filter;
+       }
+}
+
 struct machine *machines__find(struct machines *machines, pid_t pid)
 {
        struct rb_node **p = &machines->guests.rb_node;
@@ -233,7 +253,7 @@ void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size)
        return;
 }
 
-static struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid,
+static struct thread *__machine__findnew_thread(struct machine *machine, pid_t tid,
                                                bool create)
 {
        struct rb_node **p = &machine->threads.rb_node;
@@ -241,23 +261,23 @@ static struct thread *__machine__findnew_thread(struct machine *machine, pid_t p
        struct thread *th;
 
        /*
-        * Font-end cache - PID lookups come in blocks,
+        * Front-end cache - TID lookups come in blocks,
         * so most of the time we dont have to look up
         * the full rbtree:
         */
-       if (machine->last_match && machine->last_match->pid == pid)
+       if (machine->last_match && machine->last_match->tid == tid)
                return machine->last_match;
 
        while (*p != NULL) {
                parent = *p;
                th = rb_entry(parent, struct thread, rb_node);
 
-               if (th->pid == pid) {
+               if (th->tid == tid) {
                        machine->last_match = th;
                        return th;
                }
 
-               if (pid < th->pid)
+               if (tid < th->tid)
                        p = &(*p)->rb_left;
                else
                        p = &(*p)->rb_right;
@@ -266,7 +286,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine, pid_t p
        if (!create)
                return NULL;
 
-       th = thread__new(pid);
+       th = thread__new(tid);
        if (th != NULL) {
                rb_link_node(&th->rb_node, parent, p);
                rb_insert_color(&th->rb_node, &machine->threads);
@@ -276,14 +296,14 @@ static struct thread *__machine__findnew_thread(struct machine *machine, pid_t p
        return th;
 }
 
-struct thread *machine__findnew_thread(struct machine *machine, pid_t pid)
+struct thread *machine__findnew_thread(struct machine *machine, pid_t tid)
 {
-       return __machine__findnew_thread(machine, pid, true);
+       return __machine__findnew_thread(machine, tid, true);
 }
 
-struct thread *machine__find_thread(struct machine *machine, pid_t pid)
+struct thread *machine__find_thread(struct machine *machine, pid_t tid)
 {
-       return __machine__findnew_thread(machine, pid, false);
+       return __machine__findnew_thread(machine, tid, false);
 }
 
 int machine__process_comm_event(struct machine *machine, union perf_event *event)
@@ -628,10 +648,8 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
        struct map *map = machine->vmlinux_maps[type];
        int ret = dso__load_vmlinux_path(map->dso, map, filter);
 
-       if (ret > 0) {
+       if (ret > 0)
                dso__set_loaded(map->dso, type);
-               map__reloc_vmlinux(map);
-       }
 
        return ret;
 }
@@ -808,7 +826,10 @@ static int machine__create_modules(struct machine *machine)
        free(line);
        fclose(file);
 
-       return machine__set_modules_path(machine);
+       if (machine__set_modules_path(machine) < 0) {
+               pr_debug("Problems setting modules path maps, continuing anyway...\n");
+       }
+       return 0;
 
 out_delete_line:
        free(line);
@@ -858,6 +879,18 @@ static void machine__set_kernel_mmap_len(struct machine *machine,
        }
 }
 
+static bool machine__uses_kcore(struct machine *machine)
+{
+       struct dso *dso;
+
+       list_for_each_entry(dso, &machine->kernel_dsos, node) {
+               if (dso__is_kcore(dso))
+                       return true;
+       }
+
+       return false;
+}
+
 static int machine__process_kernel_mmap_event(struct machine *machine,
                                              union perf_event *event)
 {
@@ -866,6 +899,10 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
        enum dso_kernel_type kernel_type;
        bool is_kernel_mmap;
 
+       /* If we have maps from kcore then we do not need or want any others */
+       if (machine__uses_kcore(machine))
+               return 0;
+
        machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix));
        if (machine__is_host(machine))
                kernel_type = DSO_TYPE_KERNEL;
@@ -1058,11 +1095,10 @@ int machine__process_event(struct machine *machine, union perf_event *event)
        return ret;
 }
 
-static bool symbol__match_parent_regex(struct symbol *sym)
+static bool symbol__match_regex(struct symbol *sym, regex_t *regex)
 {
-       if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
+       if (sym->name && !regexec(regex, sym->name, 0, NULL, 0))
                return 1;
-
        return 0;
 }
 
@@ -1094,7 +1130,7 @@ static void ip__resolve_ams(struct machine *machine, struct thread *thread,
                 * or else, the symbol is unknown
                 */
                thread__find_addr_location(thread, machine, m, MAP__FUNCTION,
-                               ip, &al, NULL);
+                               ip, &al);
                if (al.sym)
                        goto found;
        }
@@ -1112,8 +1148,8 @@ static void ip__resolve_data(struct machine *machine, struct thread *thread,
 
        memset(&al, 0, sizeof(al));
 
-       thread__find_addr_location(thread, machine, m, MAP__VARIABLE, addr, &al,
-                                  NULL);
+       thread__find_addr_location(thread, machine, m, MAP__VARIABLE, addr,
+                                  &al);
        ams->addr = addr;
        ams->al_addr = al.addr;
        ams->sym = al.sym;
@@ -1159,8 +1195,8 @@ struct branch_info *machine__resolve_bstack(struct machine *machine,
 static int machine__resolve_callchain_sample(struct machine *machine,
                                             struct thread *thread,
                                             struct ip_callchain *chain,
-                                            struct symbol **parent)
-
+                                            struct symbol **parent,
+                                            struct addr_location *root_al)
 {
        u8 cpumode = PERF_RECORD_MISC_USER;
        unsigned int i;
@@ -1208,11 +1244,18 @@ static int machine__resolve_callchain_sample(struct machine *machine,
 
                al.filtered = false;
                thread__find_addr_location(thread, machine, cpumode,
-                                          MAP__FUNCTION, ip, &al, NULL);
+                                          MAP__FUNCTION, ip, &al);
                if (al.sym != NULL) {
                        if (sort__has_parent && !*parent &&
-                           symbol__match_parent_regex(al.sym))
+                           symbol__match_regex(al.sym, &parent_regex))
                                *parent = al.sym;
+                       else if (have_ignore_callees && root_al &&
+                         symbol__match_regex(al.sym, &ignore_callees_regex)) {
+                               /* Treat this symbol as the root,
+                                  forgetting its callees. */
+                               *root_al = al;
+                               callchain_cursor_reset(&callchain_cursor);
+                       }
                        if (!symbol_conf.use_callchain)
                                break;
                }
@@ -1237,15 +1280,13 @@ int machine__resolve_callchain(struct machine *machine,
                               struct perf_evsel *evsel,
                               struct thread *thread,
                               struct perf_sample *sample,
-                              struct symbol **parent)
-
+                              struct symbol **parent,
+                              struct addr_location *root_al)
 {
        int ret;
 
-       callchain_cursor_reset(&callchain_cursor);
-
        ret = machine__resolve_callchain_sample(machine, thread,
-                                               sample->callchain, parent);
+                                               sample->callchain, parent, root_al);
        if (ret)
                return ret;