aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2016-04-14 13:48:07 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-04-14 13:48:07 -0400
commit91d7b2de318ff701451dfc7ede1c029b150ef0e9 (patch)
tree98440b6dfabaf5dc1490bd64f6d5993eea9bf3eb
parentbbf86c43eace367e805199f94ad8b5a45636f805 (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.c2
-rw-r--r--tools/perf/util/callchain.c5
-rw-r--r--tools/perf/util/callchain.h3
-rw-r--r--tools/perf/util/evsel.c9
-rw-r--r--tools/perf/util/hist.c2
-rw-r--r--tools/perf/util/machine.c26
-rw-r--r--tools/perf/util/machine.h4
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c2
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c2
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
791int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent, 791int 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;
212int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); 212int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
213int record_callchain_opt(const struct option *opt, const char *arg, int unset); 213int record_callchain_opt(const struct option *opt, const char *arg, int unset);
214 214
215int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent, 215int 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);
218int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample); 219int 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--;
2422next: 2423next:
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
1601static int add_callchain_ip(struct thread *thread, 1601static 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
1660struct branch_info *sample__resolve_bstack(struct perf_sample *sample, 1661struct 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 */
1726static int resolve_lbr_callchain_sample(struct thread *thread, 1727static 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
1791static int thread__resolve_callchain_sample(struct thread *thread, 1793static 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
1918int thread__resolve_callchain(struct thread *thread, 1921int 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);
142struct mem_info *sample__resolve_mem(struct perf_sample *sample, 142struct mem_info *sample__resolve_mem(struct perf_sample *sample,
143 struct addr_location *al); 143 struct addr_location *al);
144
145struct callchain_cursor;
146
144int thread__resolve_callchain(struct thread *thread, 147int 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");