perf callchain: Start moving away from global per thread cursors
authorArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 14 Apr 2016 17:48:07 +0000 (14:48 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 14 Apr 2016 17:48:07 +0000 (14:48 -0300)
The recent perf_evsel__fprintf_callchain() move to evsel.c added several
new symbol requirements to the python binding, for instance:

  # perf test -v python
  16: Try 'import perf' in python, checking link problems      :
  --- start ---
  test child forked, pid 18030
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  ImportError: /tmp/build/perf/python/perf.so: undefined symbol:
  callchain_cursor
  test child finished with -1
  ---- end ----
  Try 'import perf' in python, checking link problems: FAILED!
  #

This would require linking against callchain.c to access to the global
callchain_cursor variables.

Since lots of functions already receive as a parameter a
callchain_cursor struct pointer, make that be the case for some more
function so that we can start phasing out usage of yet another global
variable.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-djko3097eyg2rn66v2qcqfvn@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-kmem.c
tools/perf/util/callchain.c
tools/perf/util/callchain.h
tools/perf/util/evsel.c
tools/perf/util/hist.c
tools/perf/util/machine.c
tools/perf/util/machine.h
tools/perf/util/scripting-engines/trace-event-perl.c
tools/perf/util/scripting-engines/trace-event-python.c

index c9cb3be47cff4801d105d8c5091768a4646ccdc5..58adfee230de8c2c2d36b5692b1cc668c1af5f01 100644 (file)
@@ -375,7 +375,7 @@ static u64 find_callsite(struct perf_evsel *evsel, struct perf_sample *sample)
        }
 
        al.thread = machine__findnew_thread(machine, sample->pid, sample->tid);
-       sample__resolve_callchain(sample, NULL, evsel, &al, 16);
+       sample__resolve_callchain(sample, &callchain_cursor, NULL, evsel, &al, 16);
 
        callchain_cursor_commit(&callchain_cursor);
        while (true) {
index 24b4bd0d77545e7bb9f95e83222eb103c92f5151..2b4ceaf058bb3d56f4df49b09a1a27f433f59f55 100644 (file)
@@ -788,7 +788,8 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
        return 0;
 }
 
-int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent,
+int sample__resolve_callchain(struct perf_sample *sample,
+                             struct callchain_cursor *cursor, struct symbol **parent,
                              struct perf_evsel *evsel, struct addr_location *al,
                              int max_stack)
 {
@@ -797,7 +798,7 @@ int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent
 
        if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain ||
            sort__has_parent) {
-               return thread__resolve_callchain(al->thread, evsel, sample,
+               return thread__resolve_callchain(al->thread, cursor, evsel, sample,
                                                 parent, al, max_stack);
        }
        return 0;
index d2a9e694810c12c3a6c7fd8e89879b1424a87fa3..cae5a7b1f5c8f5d288ed2797f4b0f07ca21f31de 100644 (file)
@@ -212,7 +212,8 @@ struct hist_entry;
 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
 
-int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent,
+int sample__resolve_callchain(struct perf_sample *sample,
+                             struct callchain_cursor *cursor, struct symbol **parent,
                              struct perf_evsel *evsel, struct addr_location *al,
                              int max_stack);
 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample);
index 6e86598682be4c622427fa2f4bdea0270ae6fafe..38f464a4fa04fb436fcd44493b832be97b42d21d 100644 (file)
@@ -2349,6 +2349,7 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
                                  FILE *fp)
 {
        int printed = 0;
+       struct callchain_cursor cursor;
        struct callchain_cursor_node *node;
        int print_ip = print_opts & EVSEL__PRINT_IP;
        int print_sym = print_opts & EVSEL__PRINT_SYM;
@@ -2362,14 +2363,14 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
        if (sample->callchain) {
                struct addr_location node_al;
 
-               if (thread__resolve_callchain(al->thread, evsel,
+               if (thread__resolve_callchain(al->thread, &cursor, evsel,
                                              sample, NULL, NULL,
                                              stack_depth) != 0) {
                        if (verbose)
                                error("Failed to resolve callchain. Skipping\n");
                        return printed;
                }
-               callchain_cursor_commit(&callchain_cursor);
+               callchain_cursor_commit(&cursor);
 
                if (print_symoffset)
                        node_al = *al;
@@ -2377,7 +2378,7 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
                while (stack_depth) {
                        u64 addr = 0;
 
-                       node = callchain_cursor_current(&callchain_cursor);
+                       node = callchain_cursor_current(&cursor);
                        if (!node)
                                break;
 
@@ -2420,7 +2421,7 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
 
                        stack_depth--;
 next:
-                       callchain_cursor_advance(&callchain_cursor);
+                       callchain_cursor_advance(&cursor);
                }
        }
 
index 3d34c57dfbe26b8b8efee1cd84da49e99829d6a0..991a351a8a41d66864666ade2ce71c2c673c9fcb 100644 (file)
@@ -953,7 +953,7 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
 {
        int err, err2;
 
-       err = sample__resolve_callchain(iter->sample, &iter->parent,
+       err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent,
                                        iter->evsel, al, max_stack_depth);
        if (err)
                return err;
index 80b9b6a87990b29e4722a956e62814130c1290de..0c4dabc699329755cc063ffc8ba04b381376fd78 100644 (file)
@@ -1599,6 +1599,7 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
 }
 
 static int add_callchain_ip(struct thread *thread,
+                           struct callchain_cursor *cursor,
                            struct symbol **parent,
                            struct addr_location *root_al,
                            u8 *cpumode,
@@ -1630,7 +1631,7 @@ static int add_callchain_ip(struct thread *thread,
                                 * It seems the callchain is corrupted.
                                 * Discard all.
                                 */
-                               callchain_cursor_reset(&callchain_cursor);
+                               callchain_cursor_reset(cursor);
                                return 1;
                        }
                        return 0;
@@ -1648,13 +1649,13 @@ static int add_callchain_ip(struct thread *thread,
                        /* Treat this symbol as the root,
                           forgetting its callees. */
                        *root_al = al;
-                       callchain_cursor_reset(&callchain_cursor);
+                       callchain_cursor_reset(cursor);
                }
        }
 
        if (symbol_conf.hide_unresolved && al.sym == NULL)
                return 0;
-       return callchain_cursor_append(&callchain_cursor, al.addr, al.map, al.sym);
+       return callchain_cursor_append(cursor, al.addr, al.map, al.sym);
 }
 
 struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
@@ -1724,6 +1725,7 @@ static int remove_loops(struct branch_entry *l, int nr)
  * negative error code on other errors.
  */
 static int resolve_lbr_callchain_sample(struct thread *thread,
+                                       struct callchain_cursor *cursor,
                                        struct perf_sample *sample,
                                        struct symbol **parent,
                                        struct addr_location *root_al,
@@ -1778,7 +1780,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
                                        ip = lbr_stack->entries[0].to;
                        }
 
-                       err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
+                       err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip);
                        if (err)
                                return (err < 0) ? err : 0;
                }
@@ -1789,6 +1791,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
 }
 
 static int thread__resolve_callchain_sample(struct thread *thread,
+                                           struct callchain_cursor *cursor,
                                            struct perf_evsel *evsel,
                                            struct perf_sample *sample,
                                            struct symbol **parent,
@@ -1803,10 +1806,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
        int skip_idx = -1;
        int first_call = 0;
 
-       callchain_cursor_reset(&callchain_cursor);
+       callchain_cursor_reset(cursor);
 
        if (has_branch_callstack(evsel)) {
-               err = resolve_lbr_callchain_sample(thread, sample, parent,
+               err = resolve_lbr_callchain_sample(thread, cursor, sample, parent,
                                                   root_al, max_stack);
                if (err)
                        return (err < 0) ? err : 0;
@@ -1863,10 +1866,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
                nr = remove_loops(be, nr);
 
                for (i = 0; i < nr; i++) {
-                       err = add_callchain_ip(thread, parent, root_al,
+                       err = add_callchain_ip(thread, cursor, parent, root_al,
                                               NULL, be[i].to);
                        if (!err)
-                               err = add_callchain_ip(thread, parent, root_al,
+                               err = add_callchain_ip(thread, cursor, parent, root_al,
                                                       NULL, be[i].from);
                        if (err == -EINVAL)
                                break;
@@ -1896,7 +1899,7 @@ check_calls:
 #endif
                ip = chain->ips[j];
 
-               err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
+               err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip);
 
                if (err)
                        return (err < 0) ? err : 0;
@@ -1916,13 +1919,14 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
 }
 
 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 = thread__resolve_callchain_sample(thread, evsel,
+       int ret = thread__resolve_callchain_sample(thread, cursor, evsel,
                                                   sample, parent,
                                                   root_al, max_stack);
        if (ret)
@@ -1938,7 +1942,7 @@ int thread__resolve_callchain(struct thread *thread,
            (!sample->user_stack.size))
                return 0;
 
-       return unwind__get_entries(unwind_entry, &callchain_cursor,
+       return unwind__get_entries(unwind_entry, cursor,
                                   thread, sample, max_stack);
 
 }
index 8499db2811583000e5181f1fc91f94c5e5f9f418..382873bdc5635fac25770b5a270433ef21132f69 100644 (file)
@@ -141,7 +141,11 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
                                           struct addr_location *al);
 struct mem_info *sample__resolve_mem(struct perf_sample *sample,
                                     struct addr_location *al);
+
+struct callchain_cursor;
+
 int thread__resolve_callchain(struct thread *thread,
+                             struct callchain_cursor *cursor,
                              struct perf_evsel *evsel,
                              struct perf_sample *sample,
                              struct symbol **parent,
index 35ed00a600fbe12282c533d3e5d89d513e99c86d..ae1cebc307c5bc09a2d4d30d8d733aa2d50b8ac8 100644 (file)
@@ -263,7 +263,7 @@ static SV *perl_process_callchain(struct perf_sample *sample,
        if (!symbol_conf.use_callchain || !sample->callchain)
                goto exit;
 
-       if (thread__resolve_callchain(al->thread, evsel,
+       if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
                                      sample, NULL, NULL,
                                      PERF_MAX_STACK_DEPTH) != 0) {
                pr_err("Failed to resolve callchain. Skipping\n");
index fbd05242b4e59786ca0e081a52729248d780f5a0..525eb49e7ba6b38feb99b1a946757b51240091f9 100644 (file)
@@ -323,7 +323,7 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
        if (!symbol_conf.use_callchain || !sample->callchain)
                goto exit;
 
-       if (thread__resolve_callchain(al->thread, evsel,
+       if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
                                      sample, NULL, NULL,
                                      scripting_max_stack) != 0) {
                pr_err("Failed to resolve callchain. Skipping\n");