diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-04-14 13:48:07 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-04-14 13:48:07 -0400 |
commit | 91d7b2de318ff701451dfc7ede1c029b150ef0e9 (patch) | |
tree | 98440b6dfabaf5dc1490bd64f6d5993eea9bf3eb | |
parent | bbf86c43eace367e805199f94ad8b5a45636f805 (diff) |
perf callchain: Start moving away from global per thread cursors
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>
-rw-r--r-- | tools/perf/builtin-kmem.c | 2 | ||||
-rw-r--r-- | tools/perf/util/callchain.c | 5 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 3 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 9 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 2 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 26 | ||||
-rw-r--r-- | tools/perf/util/machine.h | 4 | ||||
-rw-r--r-- | tools/perf/util/scripting-engines/trace-event-perl.c | 2 | ||||
-rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 2 |
9 files changed, 33 insertions, 22 deletions
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index c9cb3be47cff..58adfee230de 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
@@ -375,7 +375,7 @@ static u64 find_callsite(struct perf_evsel *evsel, struct perf_sample *sample) | |||
375 | } | 375 | } |
376 | 376 | ||
377 | al.thread = machine__findnew_thread(machine, sample->pid, sample->tid); | 377 | al.thread = machine__findnew_thread(machine, sample->pid, sample->tid); |
378 | sample__resolve_callchain(sample, NULL, evsel, &al, 16); | 378 | sample__resolve_callchain(sample, &callchain_cursor, NULL, evsel, &al, 16); |
379 | 379 | ||
380 | callchain_cursor_commit(&callchain_cursor); | 380 | callchain_cursor_commit(&callchain_cursor); |
381 | while (true) { | 381 | while (true) { |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 24b4bd0d7754..2b4ceaf058bb 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -788,7 +788,8 @@ int callchain_cursor_append(struct callchain_cursor *cursor, | |||
788 | return 0; | 788 | return 0; |
789 | } | 789 | } |
790 | 790 | ||
791 | int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent, | 791 | int sample__resolve_callchain(struct perf_sample *sample, |
792 | struct callchain_cursor *cursor, struct symbol **parent, | ||
792 | struct perf_evsel *evsel, struct addr_location *al, | 793 | struct perf_evsel *evsel, struct addr_location *al, |
793 | int max_stack) | 794 | int max_stack) |
794 | { | 795 | { |
@@ -797,7 +798,7 @@ int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent | |||
797 | 798 | ||
798 | if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain || | 799 | if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain || |
799 | sort__has_parent) { | 800 | sort__has_parent) { |
800 | return thread__resolve_callchain(al->thread, evsel, sample, | 801 | return thread__resolve_callchain(al->thread, cursor, evsel, sample, |
801 | parent, al, max_stack); | 802 | parent, al, max_stack); |
802 | } | 803 | } |
803 | return 0; | 804 | return 0; |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index d2a9e694810c..cae5a7b1f5c8 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -212,7 +212,8 @@ struct hist_entry; | |||
212 | int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); | 212 | int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); |
213 | int record_callchain_opt(const struct option *opt, const char *arg, int unset); | 213 | int record_callchain_opt(const struct option *opt, const char *arg, int unset); |
214 | 214 | ||
215 | int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent, | 215 | int sample__resolve_callchain(struct perf_sample *sample, |
216 | struct callchain_cursor *cursor, struct symbol **parent, | ||
216 | struct perf_evsel *evsel, struct addr_location *al, | 217 | struct perf_evsel *evsel, struct addr_location *al, |
217 | int max_stack); | 218 | int max_stack); |
218 | int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample); | 219 | int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample); |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 6e86598682be..38f464a4fa04 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -2349,6 +2349,7 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample * | |||
2349 | FILE *fp) | 2349 | FILE *fp) |
2350 | { | 2350 | { |
2351 | int printed = 0; | 2351 | int printed = 0; |
2352 | struct callchain_cursor cursor; | ||
2352 | struct callchain_cursor_node *node; | 2353 | struct callchain_cursor_node *node; |
2353 | int print_ip = print_opts & EVSEL__PRINT_IP; | 2354 | int print_ip = print_opts & EVSEL__PRINT_IP; |
2354 | int print_sym = print_opts & EVSEL__PRINT_SYM; | 2355 | int print_sym = print_opts & EVSEL__PRINT_SYM; |
@@ -2362,14 +2363,14 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample * | |||
2362 | if (sample->callchain) { | 2363 | if (sample->callchain) { |
2363 | struct addr_location node_al; | 2364 | struct addr_location node_al; |
2364 | 2365 | ||
2365 | if (thread__resolve_callchain(al->thread, evsel, | 2366 | if (thread__resolve_callchain(al->thread, &cursor, evsel, |
2366 | sample, NULL, NULL, | 2367 | sample, NULL, NULL, |
2367 | stack_depth) != 0) { | 2368 | stack_depth) != 0) { |
2368 | if (verbose) | 2369 | if (verbose) |
2369 | error("Failed to resolve callchain. Skipping\n"); | 2370 | error("Failed to resolve callchain. Skipping\n"); |
2370 | return printed; | 2371 | return printed; |
2371 | } | 2372 | } |
2372 | callchain_cursor_commit(&callchain_cursor); | 2373 | callchain_cursor_commit(&cursor); |
2373 | 2374 | ||
2374 | if (print_symoffset) | 2375 | if (print_symoffset) |
2375 | node_al = *al; | 2376 | node_al = *al; |
@@ -2377,7 +2378,7 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample * | |||
2377 | while (stack_depth) { | 2378 | while (stack_depth) { |
2378 | u64 addr = 0; | 2379 | u64 addr = 0; |
2379 | 2380 | ||
2380 | node = callchain_cursor_current(&callchain_cursor); | 2381 | node = callchain_cursor_current(&cursor); |
2381 | if (!node) | 2382 | if (!node) |
2382 | break; | 2383 | break; |
2383 | 2384 | ||
@@ -2420,7 +2421,7 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample * | |||
2420 | 2421 | ||
2421 | stack_depth--; | 2422 | stack_depth--; |
2422 | next: | 2423 | next: |
2423 | callchain_cursor_advance(&callchain_cursor); | 2424 | callchain_cursor_advance(&cursor); |
2424 | } | 2425 | } |
2425 | } | 2426 | } |
2426 | 2427 | ||
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 3d34c57dfbe2..991a351a8a41 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -953,7 +953,7 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, | |||
953 | { | 953 | { |
954 | int err, err2; | 954 | int err, err2; |
955 | 955 | ||
956 | err = sample__resolve_callchain(iter->sample, &iter->parent, | 956 | err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent, |
957 | iter->evsel, al, max_stack_depth); | 957 | iter->evsel, al, max_stack_depth); |
958 | if (err) | 958 | if (err) |
959 | return err; | 959 | return err; |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 80b9b6a87990..0c4dabc69932 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -1599,6 +1599,7 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample, | |||
1599 | } | 1599 | } |
1600 | 1600 | ||
1601 | static int add_callchain_ip(struct thread *thread, | 1601 | static int add_callchain_ip(struct thread *thread, |
1602 | struct callchain_cursor *cursor, | ||
1602 | struct symbol **parent, | 1603 | struct symbol **parent, |
1603 | struct addr_location *root_al, | 1604 | struct addr_location *root_al, |
1604 | u8 *cpumode, | 1605 | u8 *cpumode, |
@@ -1630,7 +1631,7 @@ static int add_callchain_ip(struct thread *thread, | |||
1630 | * It seems the callchain is corrupted. | 1631 | * It seems the callchain is corrupted. |
1631 | * Discard all. | 1632 | * Discard all. |
1632 | */ | 1633 | */ |
1633 | callchain_cursor_reset(&callchain_cursor); | 1634 | callchain_cursor_reset(cursor); |
1634 | return 1; | 1635 | return 1; |
1635 | } | 1636 | } |
1636 | return 0; | 1637 | return 0; |
@@ -1648,13 +1649,13 @@ static int add_callchain_ip(struct thread *thread, | |||
1648 | /* Treat this symbol as the root, | 1649 | /* Treat this symbol as the root, |
1649 | forgetting its callees. */ | 1650 | forgetting its callees. */ |
1650 | *root_al = al; | 1651 | *root_al = al; |
1651 | callchain_cursor_reset(&callchain_cursor); | 1652 | callchain_cursor_reset(cursor); |
1652 | } | 1653 | } |
1653 | } | 1654 | } |
1654 | 1655 | ||
1655 | if (symbol_conf.hide_unresolved && al.sym == NULL) | 1656 | if (symbol_conf.hide_unresolved && al.sym == NULL) |
1656 | return 0; | 1657 | return 0; |
1657 | return callchain_cursor_append(&callchain_cursor, al.addr, al.map, al.sym); | 1658 | return callchain_cursor_append(cursor, al.addr, al.map, al.sym); |
1658 | } | 1659 | } |
1659 | 1660 | ||
1660 | struct branch_info *sample__resolve_bstack(struct perf_sample *sample, | 1661 | struct branch_info *sample__resolve_bstack(struct perf_sample *sample, |
@@ -1724,6 +1725,7 @@ static int remove_loops(struct branch_entry *l, int nr) | |||
1724 | * negative error code on other errors. | 1725 | * negative error code on other errors. |
1725 | */ | 1726 | */ |
1726 | static int resolve_lbr_callchain_sample(struct thread *thread, | 1727 | static int resolve_lbr_callchain_sample(struct thread *thread, |
1728 | struct callchain_cursor *cursor, | ||
1727 | struct perf_sample *sample, | 1729 | struct perf_sample *sample, |
1728 | struct symbol **parent, | 1730 | struct symbol **parent, |
1729 | struct addr_location *root_al, | 1731 | struct addr_location *root_al, |
@@ -1778,7 +1780,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread, | |||
1778 | ip = lbr_stack->entries[0].to; | 1780 | ip = lbr_stack->entries[0].to; |
1779 | } | 1781 | } |
1780 | 1782 | ||
1781 | err = add_callchain_ip(thread, parent, root_al, &cpumode, ip); | 1783 | err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip); |
1782 | if (err) | 1784 | if (err) |
1783 | return (err < 0) ? err : 0; | 1785 | return (err < 0) ? err : 0; |
1784 | } | 1786 | } |
@@ -1789,6 +1791,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread, | |||
1789 | } | 1791 | } |
1790 | 1792 | ||
1791 | static int thread__resolve_callchain_sample(struct thread *thread, | 1793 | static int thread__resolve_callchain_sample(struct thread *thread, |
1794 | struct callchain_cursor *cursor, | ||
1792 | struct perf_evsel *evsel, | 1795 | struct perf_evsel *evsel, |
1793 | struct perf_sample *sample, | 1796 | struct perf_sample *sample, |
1794 | struct symbol **parent, | 1797 | struct symbol **parent, |
@@ -1803,10 +1806,10 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
1803 | int skip_idx = -1; | 1806 | int skip_idx = -1; |
1804 | int first_call = 0; | 1807 | int first_call = 0; |
1805 | 1808 | ||
1806 | callchain_cursor_reset(&callchain_cursor); | 1809 | callchain_cursor_reset(cursor); |
1807 | 1810 | ||
1808 | if (has_branch_callstack(evsel)) { | 1811 | if (has_branch_callstack(evsel)) { |
1809 | err = resolve_lbr_callchain_sample(thread, sample, parent, | 1812 | err = resolve_lbr_callchain_sample(thread, cursor, sample, parent, |
1810 | root_al, max_stack); | 1813 | root_al, max_stack); |
1811 | if (err) | 1814 | if (err) |
1812 | return (err < 0) ? err : 0; | 1815 | return (err < 0) ? err : 0; |
@@ -1863,10 +1866,10 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
1863 | nr = remove_loops(be, nr); | 1866 | nr = remove_loops(be, nr); |
1864 | 1867 | ||
1865 | for (i = 0; i < nr; i++) { | 1868 | for (i = 0; i < nr; i++) { |
1866 | err = add_callchain_ip(thread, parent, root_al, | 1869 | err = add_callchain_ip(thread, cursor, parent, root_al, |
1867 | NULL, be[i].to); | 1870 | NULL, be[i].to); |
1868 | if (!err) | 1871 | if (!err) |
1869 | err = add_callchain_ip(thread, parent, root_al, | 1872 | err = add_callchain_ip(thread, cursor, parent, root_al, |
1870 | NULL, be[i].from); | 1873 | NULL, be[i].from); |
1871 | if (err == -EINVAL) | 1874 | if (err == -EINVAL) |
1872 | break; | 1875 | break; |
@@ -1896,7 +1899,7 @@ check_calls: | |||
1896 | #endif | 1899 | #endif |
1897 | ip = chain->ips[j]; | 1900 | ip = chain->ips[j]; |
1898 | 1901 | ||
1899 | err = add_callchain_ip(thread, parent, root_al, &cpumode, ip); | 1902 | err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip); |
1900 | 1903 | ||
1901 | if (err) | 1904 | if (err) |
1902 | return (err < 0) ? err : 0; | 1905 | return (err < 0) ? err : 0; |
@@ -1916,13 +1919,14 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) | |||
1916 | } | 1919 | } |
1917 | 1920 | ||
1918 | int thread__resolve_callchain(struct thread *thread, | 1921 | int thread__resolve_callchain(struct thread *thread, |
1922 | struct callchain_cursor *cursor, | ||
1919 | struct perf_evsel *evsel, | 1923 | struct perf_evsel *evsel, |
1920 | struct perf_sample *sample, | 1924 | struct perf_sample *sample, |
1921 | struct symbol **parent, | 1925 | struct symbol **parent, |
1922 | struct addr_location *root_al, | 1926 | struct addr_location *root_al, |
1923 | int max_stack) | 1927 | int max_stack) |
1924 | { | 1928 | { |
1925 | int ret = thread__resolve_callchain_sample(thread, evsel, | 1929 | int ret = thread__resolve_callchain_sample(thread, cursor, evsel, |
1926 | sample, parent, | 1930 | sample, parent, |
1927 | root_al, max_stack); | 1931 | root_al, max_stack); |
1928 | if (ret) | 1932 | if (ret) |
@@ -1938,7 +1942,7 @@ int thread__resolve_callchain(struct thread *thread, | |||
1938 | (!sample->user_stack.size)) | 1942 | (!sample->user_stack.size)) |
1939 | return 0; | 1943 | return 0; |
1940 | 1944 | ||
1941 | return unwind__get_entries(unwind_entry, &callchain_cursor, | 1945 | return unwind__get_entries(unwind_entry, cursor, |
1942 | thread, sample, max_stack); | 1946 | thread, sample, max_stack); |
1943 | 1947 | ||
1944 | } | 1948 | } |
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 8499db281158..382873bdc563 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h | |||
@@ -141,7 +141,11 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample, | |||
141 | struct addr_location *al); | 141 | struct addr_location *al); |
142 | struct mem_info *sample__resolve_mem(struct perf_sample *sample, | 142 | struct mem_info *sample__resolve_mem(struct perf_sample *sample, |
143 | struct addr_location *al); | 143 | struct addr_location *al); |
144 | |||
145 | struct callchain_cursor; | ||
146 | |||
144 | int thread__resolve_callchain(struct thread *thread, | 147 | int thread__resolve_callchain(struct thread *thread, |
148 | struct callchain_cursor *cursor, | ||
145 | struct perf_evsel *evsel, | 149 | struct perf_evsel *evsel, |
146 | struct perf_sample *sample, | 150 | struct perf_sample *sample, |
147 | struct symbol **parent, | 151 | struct symbol **parent, |
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 35ed00a600fb..ae1cebc307c5 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c | |||
@@ -263,7 +263,7 @@ static SV *perl_process_callchain(struct perf_sample *sample, | |||
263 | if (!symbol_conf.use_callchain || !sample->callchain) | 263 | if (!symbol_conf.use_callchain || !sample->callchain) |
264 | goto exit; | 264 | goto exit; |
265 | 265 | ||
266 | if (thread__resolve_callchain(al->thread, evsel, | 266 | if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel, |
267 | sample, NULL, NULL, | 267 | sample, NULL, NULL, |
268 | PERF_MAX_STACK_DEPTH) != 0) { | 268 | PERF_MAX_STACK_DEPTH) != 0) { |
269 | pr_err("Failed to resolve callchain. Skipping\n"); | 269 | pr_err("Failed to resolve callchain. Skipping\n"); |
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index fbd05242b4e5..525eb49e7ba6 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
@@ -323,7 +323,7 @@ static PyObject *python_process_callchain(struct perf_sample *sample, | |||
323 | if (!symbol_conf.use_callchain || !sample->callchain) | 323 | if (!symbol_conf.use_callchain || !sample->callchain) |
324 | goto exit; | 324 | goto exit; |
325 | 325 | ||
326 | if (thread__resolve_callchain(al->thread, evsel, | 326 | if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel, |
327 | sample, NULL, NULL, | 327 | sample, NULL, NULL, |
328 | scripting_max_stack) != 0) { | 328 | scripting_max_stack) != 0) { |
329 | pr_err("Failed to resolve callchain. Skipping\n"); | 329 | pr_err("Failed to resolve callchain. Skipping\n"); |