]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - tools/perf/util/machine.c
perf symbols: Introduce DSO__NAME_KALLSYMS and DSO__NAME_KCORE
[mirror_ubuntu-zesty-kernel.git] / tools / perf / util / machine.c
index 656c1d7ee7d46f771d473873823ae4c716bfaf06..18dd96bdde05d1a50523bb5a50610cff47e82141 100644 (file)
@@ -32,6 +32,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
 
        machine->threads = RB_ROOT;
        pthread_rwlock_init(&machine->threads_lock, NULL);
+       machine->nr_threads = 0;
        INIT_LIST_HEAD(&machine->dead_threads);
        machine->last_match = NULL;
 
@@ -430,6 +431,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
                 */
                thread__get(th);
                machine->last_match = th;
+               ++machine->nr_threads;
        }
 
        return th;
@@ -681,11 +683,13 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp)
 
 size_t machine__fprintf(struct machine *machine, FILE *fp)
 {
-       size_t ret = 0;
+       size_t ret;
        struct rb_node *nd;
 
        pthread_rwlock_rdlock(&machine->threads_lock);
 
+       ret = fprintf(fp, "Threads: %u\n", machine->nr_threads);
+
        for (nd = rb_first(&machine->threads); nd; nd = rb_next(nd)) {
                struct thread *pos = rb_entry(nd, struct thread, rb_node);
 
@@ -705,7 +709,7 @@ static struct dso *machine__get_kernel(struct machine *machine)
        if (machine__is_host(machine)) {
                vmlinux_name = symbol_conf.vmlinux_name;
                if (!vmlinux_name)
-                       vmlinux_name = "[kernel.kallsyms]";
+                       vmlinux_name = DSO__NAME_KALLSYMS;
 
                kernel = machine__findnew_kernel(machine, vmlinux_name,
                                                 "[kernel]", DSO_TYPE_KERNEL);
@@ -1419,6 +1423,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th,
                pthread_rwlock_wrlock(&machine->threads_lock);
        rb_erase_init(&th->rb_node, &machine->threads);
        RB_CLEAR_NODE(&th->rb_node);
+       --machine->nr_threads;
        /*
         * Move it first to the dead_threads list, then drop the reference,
         * if this is the last reference, then the thread__delete destructor
@@ -1647,7 +1652,7 @@ static int add_callchain_ip(struct thread *thread,
        }
 
        if (al.sym != NULL) {
-               if (sort__has_parent && !*parent &&
+               if (perf_hpp_list.parent && !*parent &&
                    symbol__match_regex(al.sym, &parent_regex))
                        *parent = al.sym;
                else if (have_ignore_callees && root_al &&
@@ -1764,7 +1769,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
                 */
                int mix_chain_nr = i + 1 + lbr_nr + 1;
 
-               if (mix_chain_nr > PERF_MAX_STACK_DEPTH + PERF_MAX_BRANCH_DEPTH) {
+               if (mix_chain_nr > (int)sysctl_perf_event_max_stack + PERF_MAX_BRANCH_DEPTH) {
                        pr_warning("corrupted callchain. skipping...\n");
                        return 0;
                }
@@ -1812,8 +1817,6 @@ static int thread__resolve_callchain_sample(struct thread *thread,
        int skip_idx = -1;
        int first_call = 0;
 
-       callchain_cursor_reset(cursor);
-
        if (perf_evsel__has_branch_callstack(evsel)) {
                err = resolve_lbr_callchain_sample(thread, cursor, sample, parent,
                                                   root_al, max_stack);
@@ -1825,7 +1828,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
         * Based on DWARF debug information, some architectures skip
         * a callchain entry saved by the kernel.
         */
-       if (chain->nr < PERF_MAX_STACK_DEPTH)
+       if (chain->nr < sysctl_perf_event_max_stack)
                skip_idx = arch_skip_callchain_idx(thread, chain);
 
        /*
@@ -1886,7 +1889,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
        }
 
 check_calls:
-       if (chain->nr > PERF_MAX_STACK_DEPTH && (int)chain->nr > max_stack) {
+       if (chain->nr > sysctl_perf_event_max_stack && (int)chain->nr > max_stack) {
                pr_warning("corrupted callchain. skipping...\n");
                return 0;
        }
@@ -1924,20 +1927,12 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
                                       entry->map, entry->sym);
 }
 
-int thread__resolve_callchain(struct thread *thread,
-                             struct callchain_cursor *cursor,
-                             struct perf_evsel *evsel,
-                             struct perf_sample *sample,
-                             struct symbol **parent,
-                             struct addr_location *root_al,
-                             int max_stack)
+static int thread__resolve_callchain_unwind(struct thread *thread,
+                                           struct callchain_cursor *cursor,
+                                           struct perf_evsel *evsel,
+                                           struct perf_sample *sample,
+                                           int max_stack)
 {
-       int ret = thread__resolve_callchain_sample(thread, cursor, evsel,
-                                                  sample, parent,
-                                                  root_al, max_stack);
-       if (ret)
-               return ret;
-
        /* Can we do dwarf post unwind? */
        if (!((evsel->attr.sample_type & PERF_SAMPLE_REGS_USER) &&
              (evsel->attr.sample_type & PERF_SAMPLE_STACK_USER)))
@@ -1950,7 +1945,43 @@ int thread__resolve_callchain(struct thread *thread,
 
        return unwind__get_entries(unwind_entry, cursor,
                                   thread, sample, max_stack);
+}
 
+int thread__resolve_callchain(struct thread *thread,
+                             struct callchain_cursor *cursor,
+                             struct perf_evsel *evsel,
+                             struct perf_sample *sample,
+                             struct symbol **parent,
+                             struct addr_location *root_al,
+                             int max_stack)
+{
+       int ret = 0;
+
+       callchain_cursor_reset(&callchain_cursor);
+
+       if (callchain_param.order == ORDER_CALLEE) {
+               ret = thread__resolve_callchain_sample(thread, cursor,
+                                                      evsel, sample,
+                                                      parent, root_al,
+                                                      max_stack);
+               if (ret)
+                       return ret;
+               ret = thread__resolve_callchain_unwind(thread, cursor,
+                                                      evsel, sample,
+                                                      max_stack);
+       } else {
+               ret = thread__resolve_callchain_unwind(thread, cursor,
+                                                      evsel, sample,
+                                                      max_stack);
+               if (ret)
+                       return ret;
+               ret = thread__resolve_callchain_sample(thread, cursor,
+                                                      evsel, sample,
+                                                      parent, root_al,
+                                                      max_stack);
+       }
+
+       return ret;
 }
 
 int machine__for_each_thread(struct machine *machine,