aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJin Yao <yao.jin@linux.intel.com>2017-08-07 09:05:15 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-08-30 09:03:27 -0400
commitc4ee06251d4212a0d55e2371f2db464f6a1e0901 (patch)
tree03b82daa6519bfd7d999ccc288f8edb09b27e4e2
parent1b2f76d77a277bb70d38ad0991ed7f16bbc115a9 (diff)
perf report: Calculate the average cycles of iterations
The branch history code has a loop detection function. With this, we can get the number of iterations by calculating the removed loops. While it would be nice for knowing the average cycles of iterations. This patch adds up the cycles in branch entries of removed loops and save the result to the next branch entry (e.g. branch entry A). Finally it will display the iteration number and average cycles at the "from" of branch entry A. For example: perf record -g -j any,save_type ./div perf report --branch-history --no-children --stdio --22.63%--main div.c:42 (RET CROSS_2M) compute_flag div.c:28 (cycles:2 iter:173115 avg_cycles:2) | --10.73%--compute_flag div.c:27 (RET CROSS_2M) rand rand.c:28 (cycles:1) rand rand.c:28 (RET CROSS_2M) __random random.c:298 (cycles:1) __random random.c:297 (COND_BWD CROSS_2M) __random random.c:295 (cycles:1) __random random.c:295 (COND_BWD CROSS_2M) __random random.c:295 (cycles:1) __random random.c:295 (RET CROSS_2M) Signed-off-by: Yao Jin <yao.jin@linux.intel.com> Reviewed-by: Andi Kleen <ak@linux.intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kan Liang <kan.liang@intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1502111115-18305-1-git-send-email-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/ui/browsers/hists.c8
-rw-r--r--tools/perf/ui/stdio/hist.c10
-rw-r--r--tools/perf/util/callchain.c49
-rw-r--r--tools/perf/util/callchain.h9
-rw-r--r--tools/perf/util/machine.c88
5 files changed, 85 insertions, 79 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index f4bc2462bc2c..13dfb0a0bdeb 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -931,12 +931,8 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser,
931 browser->show_dso); 931 browser->show_dso);
932 932
933 if (symbol_conf.show_branchflag_count) { 933 if (symbol_conf.show_branchflag_count) {
934 if (need_percent) 934 callchain_list_counts__printf_value(chain, NULL,
935 callchain_list_counts__printf_value(node, chain, NULL, 935 buf, sizeof(buf));
936 buf, sizeof(buf));
937 else
938 callchain_list_counts__printf_value(NULL, chain, NULL,
939 buf, sizeof(buf));
940 936
941 if (asprintf(&alloc_str2, "%s%s", str, buf) < 0) 937 if (asprintf(&alloc_str2, "%s%s", str, buf) < 0)
942 str = "Not enough memory!"; 938 str = "Not enough memory!";
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 5c95b8301c67..8bdb7a500181 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -124,12 +124,8 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node,
124 str = callchain_list__sym_name(chain, bf, sizeof(bf), false); 124 str = callchain_list__sym_name(chain, bf, sizeof(bf), false);
125 125
126 if (symbol_conf.show_branchflag_count) { 126 if (symbol_conf.show_branchflag_count) {
127 if (!period) 127 callchain_list_counts__printf_value(chain, NULL,
128 callchain_list_counts__printf_value(node, chain, NULL, 128 buf, sizeof(buf));
129 buf, sizeof(buf));
130 else
131 callchain_list_counts__printf_value(NULL, chain, NULL,
132 buf, sizeof(buf));
133 129
134 if (asprintf(&alloc_str, "%s%s", str, buf) < 0) 130 if (asprintf(&alloc_str, "%s%s", str, buf) < 0)
135 str = "Not enough memory!"; 131 str = "Not enough memory!";
@@ -313,7 +309,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
313 309
314 if (symbol_conf.show_branchflag_count) 310 if (symbol_conf.show_branchflag_count)
315 ret += callchain_list_counts__printf_value( 311 ret += callchain_list_counts__printf_value(
316 NULL, chain, fp, NULL, 0); 312 chain, fp, NULL, 0);
317 ret += fprintf(fp, "\n"); 313 ret += fprintf(fp, "\n");
318 314
319 if (++entries_printed == callchain_param.print_limit) 315 if (++entries_printed == callchain_param.print_limit)
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index f320b0777e0d..510b513e0f01 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -588,7 +588,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor)
588 call->cycles_count = 588 call->cycles_count =
589 cursor_node->branch_flags.cycles; 589 cursor_node->branch_flags.cycles;
590 call->iter_count = cursor_node->nr_loop_iter; 590 call->iter_count = cursor_node->nr_loop_iter;
591 call->samples_count = cursor_node->samples; 591 call->iter_cycles = cursor_node->iter_cycles;
592 } 592 }
593 } 593 }
594 594
@@ -722,7 +722,7 @@ static enum match_result match_chain(struct callchain_cursor_node *node,
722 cnode->cycles_count += 722 cnode->cycles_count +=
723 node->branch_flags.cycles; 723 node->branch_flags.cycles;
724 cnode->iter_count += node->nr_loop_iter; 724 cnode->iter_count += node->nr_loop_iter;
725 cnode->samples_count += node->samples; 725 cnode->iter_cycles += node->iter_cycles;
726 } 726 }
727 } 727 }
728 728
@@ -998,7 +998,7 @@ int callchain_merge(struct callchain_cursor *cursor,
998int callchain_cursor_append(struct callchain_cursor *cursor, 998int callchain_cursor_append(struct callchain_cursor *cursor,
999 u64 ip, struct map *map, struct symbol *sym, 999 u64 ip, struct map *map, struct symbol *sym,
1000 bool branch, struct branch_flags *flags, 1000 bool branch, struct branch_flags *flags,
1001 int nr_loop_iter, int samples, u64 branch_from) 1001 int nr_loop_iter, u64 iter_cycles, u64 branch_from)
1002{ 1002{
1003 struct callchain_cursor_node *node = *cursor->last; 1003 struct callchain_cursor_node *node = *cursor->last;
1004 1004
@@ -1016,7 +1016,7 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
1016 node->sym = sym; 1016 node->sym = sym;
1017 node->branch = branch; 1017 node->branch = branch;
1018 node->nr_loop_iter = nr_loop_iter; 1018 node->nr_loop_iter = nr_loop_iter;
1019 node->samples = samples; 1019 node->iter_cycles = iter_cycles;
1020 1020
1021 if (flags) 1021 if (flags)
1022 memcpy(&node->branch_flags, flags, 1022 memcpy(&node->branch_flags, flags,
@@ -1306,7 +1306,7 @@ static int branch_to_str(char *bf, int bfsize,
1306static int branch_from_str(char *bf, int bfsize, 1306static int branch_from_str(char *bf, int bfsize,
1307 u64 branch_count, 1307 u64 branch_count,
1308 u64 cycles_count, u64 iter_count, 1308 u64 cycles_count, u64 iter_count,
1309 u64 samples_count) 1309 u64 iter_cycles)
1310{ 1310{
1311 int printed = 0, i = 0; 1311 int printed = 0, i = 0;
1312 u64 cycles; 1312 u64 cycles;
@@ -1318,9 +1318,13 @@ static int branch_from_str(char *bf, int bfsize,
1318 bf + printed, bfsize - printed); 1318 bf + printed, bfsize - printed);
1319 } 1319 }
1320 1320
1321 if (iter_count && samples_count) { 1321 if (iter_count) {
1322 printed += count_pri64_printf(i++, "iterations", 1322 printed += count_pri64_printf(i++, "iter",
1323 iter_count / samples_count, 1323 iter_count,
1324 bf + printed, bfsize - printed);
1325
1326 printed += count_pri64_printf(i++, "avg_cycles",
1327 iter_cycles / iter_count,
1324 bf + printed, bfsize - printed); 1328 bf + printed, bfsize - printed);
1325 } 1329 }
1326 1330
@@ -1333,7 +1337,7 @@ static int branch_from_str(char *bf, int bfsize,
1333static int counts_str_build(char *bf, int bfsize, 1337static int counts_str_build(char *bf, int bfsize,
1334 u64 branch_count, u64 predicted_count, 1338 u64 branch_count, u64 predicted_count,
1335 u64 abort_count, u64 cycles_count, 1339 u64 abort_count, u64 cycles_count,
1336 u64 iter_count, u64 samples_count, 1340 u64 iter_count, u64 iter_cycles,
1337 struct branch_type_stat *brtype_stat) 1341 struct branch_type_stat *brtype_stat)
1338{ 1342{
1339 int printed; 1343 int printed;
@@ -1346,7 +1350,7 @@ static int counts_str_build(char *bf, int bfsize,
1346 predicted_count, abort_count, brtype_stat); 1350 predicted_count, abort_count, brtype_stat);
1347 } else { 1351 } else {
1348 printed = branch_from_str(bf, bfsize, branch_count, 1352 printed = branch_from_str(bf, bfsize, branch_count,
1349 cycles_count, iter_count, samples_count); 1353 cycles_count, iter_count, iter_cycles);
1350 } 1354 }
1351 1355
1352 if (!printed) 1356 if (!printed)
@@ -1358,14 +1362,14 @@ static int counts_str_build(char *bf, int bfsize,
1358static int callchain_counts_printf(FILE *fp, char *bf, int bfsize, 1362static int callchain_counts_printf(FILE *fp, char *bf, int bfsize,
1359 u64 branch_count, u64 predicted_count, 1363 u64 branch_count, u64 predicted_count,
1360 u64 abort_count, u64 cycles_count, 1364 u64 abort_count, u64 cycles_count,
1361 u64 iter_count, u64 samples_count, 1365 u64 iter_count, u64 iter_cycles,
1362 struct branch_type_stat *brtype_stat) 1366 struct branch_type_stat *brtype_stat)
1363{ 1367{
1364 char str[256]; 1368 char str[256];
1365 1369
1366 counts_str_build(str, sizeof(str), branch_count, 1370 counts_str_build(str, sizeof(str), branch_count,
1367 predicted_count, abort_count, cycles_count, 1371 predicted_count, abort_count, cycles_count,
1368 iter_count, samples_count, brtype_stat); 1372 iter_count, iter_cycles, brtype_stat);
1369 1373
1370 if (fp) 1374 if (fp)
1371 return fprintf(fp, "%s", str); 1375 return fprintf(fp, "%s", str);
@@ -1373,31 +1377,23 @@ static int callchain_counts_printf(FILE *fp, char *bf, int bfsize,
1373 return scnprintf(bf, bfsize, "%s", str); 1377 return scnprintf(bf, bfsize, "%s", str);
1374} 1378}
1375 1379
1376int callchain_list_counts__printf_value(struct callchain_node *node, 1380int callchain_list_counts__printf_value(struct callchain_list *clist,
1377 struct callchain_list *clist,
1378 FILE *fp, char *bf, int bfsize) 1381 FILE *fp, char *bf, int bfsize)
1379{ 1382{
1380 u64 branch_count, predicted_count; 1383 u64 branch_count, predicted_count;
1381 u64 abort_count, cycles_count; 1384 u64 abort_count, cycles_count;
1382 u64 iter_count = 0, samples_count = 0; 1385 u64 iter_count, iter_cycles;
1383 1386
1384 branch_count = clist->branch_count; 1387 branch_count = clist->branch_count;
1385 predicted_count = clist->predicted_count; 1388 predicted_count = clist->predicted_count;
1386 abort_count = clist->abort_count; 1389 abort_count = clist->abort_count;
1387 cycles_count = clist->cycles_count; 1390 cycles_count = clist->cycles_count;
1388 1391 iter_count = clist->iter_count;
1389 if (node) { 1392 iter_cycles = clist->iter_cycles;
1390 struct callchain_list *call;
1391
1392 list_for_each_entry(call, &node->val, list) {
1393 iter_count += call->iter_count;
1394 samples_count += call->samples_count;
1395 }
1396 }
1397 1393
1398 return callchain_counts_printf(fp, bf, bfsize, branch_count, 1394 return callchain_counts_printf(fp, bf, bfsize, branch_count,
1399 predicted_count, abort_count, 1395 predicted_count, abort_count,
1400 cycles_count, iter_count, samples_count, 1396 cycles_count, iter_count, iter_cycles,
1401 &clist->brtype_stat); 1397 &clist->brtype_stat);
1402} 1398}
1403 1399
@@ -1523,7 +1519,8 @@ int callchain_cursor__copy(struct callchain_cursor *dst,
1523 1519
1524 rc = callchain_cursor_append(dst, node->ip, node->map, node->sym, 1520 rc = callchain_cursor_append(dst, node->ip, node->map, node->sym,
1525 node->branch, &node->branch_flags, 1521 node->branch, &node->branch_flags,
1526 node->nr_loop_iter, node->samples, 1522 node->nr_loop_iter,
1523 node->iter_cycles,
1527 node->branch_from); 1524 node->branch_from);
1528 if (rc) 1525 if (rc)
1529 break; 1526 break;
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 97738201464a..1ed6fc61d0a5 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -119,7 +119,7 @@ struct callchain_list {
119 u64 abort_count; 119 u64 abort_count;
120 u64 cycles_count; 120 u64 cycles_count;
121 u64 iter_count; 121 u64 iter_count;
122 u64 samples_count; 122 u64 iter_cycles;
123 struct branch_type_stat brtype_stat; 123 struct branch_type_stat brtype_stat;
124 char *srcline; 124 char *srcline;
125 struct list_head list; 125 struct list_head list;
@@ -139,7 +139,7 @@ struct callchain_cursor_node {
139 struct branch_flags branch_flags; 139 struct branch_flags branch_flags;
140 u64 branch_from; 140 u64 branch_from;
141 int nr_loop_iter; 141 int nr_loop_iter;
142 int samples; 142 u64 iter_cycles;
143 struct callchain_cursor_node *next; 143 struct callchain_cursor_node *next;
144}; 144};
145 145
@@ -201,7 +201,7 @@ static inline void callchain_cursor_reset(struct callchain_cursor *cursor)
201int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip, 201int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
202 struct map *map, struct symbol *sym, 202 struct map *map, struct symbol *sym,
203 bool branch, struct branch_flags *flags, 203 bool branch, struct branch_flags *flags,
204 int nr_loop_iter, int samples, u64 branch_from); 204 int nr_loop_iter, u64 iter_cycles, u64 branch_from);
205 205
206/* Close a cursor writing session. Initialize for the reader */ 206/* Close a cursor writing session. Initialize for the reader */
207static inline void callchain_cursor_commit(struct callchain_cursor *cursor) 207static inline void callchain_cursor_commit(struct callchain_cursor *cursor)
@@ -282,8 +282,7 @@ char *callchain_node__scnprintf_value(struct callchain_node *node,
282int callchain_node__fprintf_value(struct callchain_node *node, 282int callchain_node__fprintf_value(struct callchain_node *node,
283 FILE *fp, u64 total); 283 FILE *fp, u64 total);
284 284
285int callchain_list_counts__printf_value(struct callchain_node *node, 285int callchain_list_counts__printf_value(struct callchain_list *clist,
286 struct callchain_list *clist,
287 FILE *fp, char *bf, int bfsize); 286 FILE *fp, char *bf, int bfsize);
288 287
289void free_callchain(struct callchain_root *root); 288void free_callchain(struct callchain_root *root);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 5c8eacaca4f4..9eaa95302c86 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1675,6 +1675,11 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
1675 return mi; 1675 return mi;
1676} 1676}
1677 1677
1678struct iterations {
1679 int nr_loop_iter;
1680 u64 cycles;
1681};
1682
1678static int add_callchain_ip(struct thread *thread, 1683static int add_callchain_ip(struct thread *thread,
1679 struct callchain_cursor *cursor, 1684 struct callchain_cursor *cursor,
1680 struct symbol **parent, 1685 struct symbol **parent,
@@ -1683,11 +1688,12 @@ static int add_callchain_ip(struct thread *thread,
1683 u64 ip, 1688 u64 ip,
1684 bool branch, 1689 bool branch,
1685 struct branch_flags *flags, 1690 struct branch_flags *flags,
1686 int nr_loop_iter, 1691 struct iterations *iter,
1687 int samples,
1688 u64 branch_from) 1692 u64 branch_from)
1689{ 1693{
1690 struct addr_location al; 1694 struct addr_location al;
1695 int nr_loop_iter = 0;
1696 u64 iter_cycles = 0;
1691 1697
1692 al.filtered = 0; 1698 al.filtered = 0;
1693 al.sym = NULL; 1699 al.sym = NULL;
@@ -1737,9 +1743,15 @@ static int add_callchain_ip(struct thread *thread,
1737 1743
1738 if (symbol_conf.hide_unresolved && al.sym == NULL) 1744 if (symbol_conf.hide_unresolved && al.sym == NULL)
1739 return 0; 1745 return 0;
1746
1747 if (iter) {
1748 nr_loop_iter = iter->nr_loop_iter;
1749 iter_cycles = iter->cycles;
1750 }
1751
1740 return callchain_cursor_append(cursor, al.addr, al.map, al.sym, 1752 return callchain_cursor_append(cursor, al.addr, al.map, al.sym,
1741 branch, flags, nr_loop_iter, samples, 1753 branch, flags, nr_loop_iter,
1742 branch_from); 1754 iter_cycles, branch_from);
1743} 1755}
1744 1756
1745struct branch_info *sample__resolve_bstack(struct perf_sample *sample, 1757struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
@@ -1760,6 +1772,18 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
1760 return bi; 1772 return bi;
1761} 1773}
1762 1774
1775static void save_iterations(struct iterations *iter,
1776 struct branch_entry *be, int nr)
1777{
1778 int i;
1779
1780 iter->nr_loop_iter = nr;
1781 iter->cycles = 0;
1782
1783 for (i = 0; i < nr; i++)
1784 iter->cycles += be[i].flags.cycles;
1785}
1786
1763#define CHASHSZ 127 1787#define CHASHSZ 127
1764#define CHASHBITS 7 1788#define CHASHBITS 7
1765#define NO_ENTRY 0xff 1789#define NO_ENTRY 0xff
@@ -1767,7 +1791,8 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
1767#define PERF_MAX_BRANCH_DEPTH 127 1791#define PERF_MAX_BRANCH_DEPTH 127
1768 1792
1769/* Remove loops. */ 1793/* Remove loops. */
1770static int remove_loops(struct branch_entry *l, int nr) 1794static int remove_loops(struct branch_entry *l, int nr,
1795 struct iterations *iter)
1771{ 1796{
1772 int i, j, off; 1797 int i, j, off;
1773 unsigned char chash[CHASHSZ]; 1798 unsigned char chash[CHASHSZ];
@@ -1792,8 +1817,18 @@ static int remove_loops(struct branch_entry *l, int nr)
1792 break; 1817 break;
1793 } 1818 }
1794 if (is_loop) { 1819 if (is_loop) {
1795 memmove(l + i, l + i + off, 1820 j = nr - (i + off);
1796 (nr - (i + off)) * sizeof(*l)); 1821 if (j > 0) {
1822 save_iterations(iter + i + off,
1823 l + i, off);
1824
1825 memmove(iter + i, iter + i + off,
1826 j * sizeof(*iter));
1827
1828 memmove(l + i, l + i + off,
1829 j * sizeof(*l));
1830 }
1831
1797 nr -= off; 1832 nr -= off;
1798 } 1833 }
1799 } 1834 }
@@ -1883,7 +1918,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
1883 1918
1884 err = add_callchain_ip(thread, cursor, parent, 1919 err = add_callchain_ip(thread, cursor, parent,
1885 root_al, &cpumode, ip, 1920 root_al, &cpumode, ip,
1886 branch, flags, 0, 0, 1921 branch, flags, NULL,
1887 branch_from); 1922 branch_from);
1888 if (err) 1923 if (err)
1889 return (err < 0) ? err : 0; 1924 return (err < 0) ? err : 0;
@@ -1909,7 +1944,6 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1909 int i, j, err, nr_entries; 1944 int i, j, err, nr_entries;
1910 int skip_idx = -1; 1945 int skip_idx = -1;
1911 int first_call = 0; 1946 int first_call = 0;
1912 int nr_loop_iter;
1913 1947
1914 if (chain) 1948 if (chain)
1915 chain_nr = chain->nr; 1949 chain_nr = chain->nr;
@@ -1942,6 +1976,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1942 if (branch && callchain_param.branch_callstack) { 1976 if (branch && callchain_param.branch_callstack) {
1943 int nr = min(max_stack, (int)branch->nr); 1977 int nr = min(max_stack, (int)branch->nr);
1944 struct branch_entry be[nr]; 1978 struct branch_entry be[nr];
1979 struct iterations iter[nr];
1945 1980
1946 if (branch->nr > PERF_MAX_BRANCH_DEPTH) { 1981 if (branch->nr > PERF_MAX_BRANCH_DEPTH) {
1947 pr_warning("corrupted branch chain. skipping...\n"); 1982 pr_warning("corrupted branch chain. skipping...\n");
@@ -1972,38 +2007,21 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1972 be[i] = branch->entries[branch->nr - i - 1]; 2007 be[i] = branch->entries[branch->nr - i - 1];
1973 } 2008 }
1974 2009
1975 nr_loop_iter = nr; 2010 memset(iter, 0, sizeof(struct iterations) * nr);
1976 nr = remove_loops(be, nr); 2011 nr = remove_loops(be, nr, iter);
1977
1978 /*
1979 * Get the number of iterations.
1980 * It's only approximation, but good enough in practice.
1981 */
1982 if (nr_loop_iter > nr)
1983 nr_loop_iter = nr_loop_iter - nr + 1;
1984 else
1985 nr_loop_iter = 0;
1986 2012
1987 for (i = 0; i < nr; i++) { 2013 for (i = 0; i < nr; i++) {
1988 if (i == nr - 1) 2014 err = add_callchain_ip(thread, cursor, parent,
1989 err = add_callchain_ip(thread, cursor, parent, 2015 root_al,
1990 root_al, 2016 NULL, be[i].to,
1991 NULL, be[i].to, 2017 true, &be[i].flags,
1992 true, &be[i].flags, 2018 NULL, be[i].from);
1993 nr_loop_iter, 1,
1994 be[i].from);
1995 else
1996 err = add_callchain_ip(thread, cursor, parent,
1997 root_al,
1998 NULL, be[i].to,
1999 true, &be[i].flags,
2000 0, 0, be[i].from);
2001 2019
2002 if (!err) 2020 if (!err)
2003 err = add_callchain_ip(thread, cursor, parent, root_al, 2021 err = add_callchain_ip(thread, cursor, parent, root_al,
2004 NULL, be[i].from, 2022 NULL, be[i].from,
2005 true, &be[i].flags, 2023 true, &be[i].flags,
2006 0, 0, 0); 2024 &iter[i], 0);
2007 if (err == -EINVAL) 2025 if (err == -EINVAL)
2008 break; 2026 break;
2009 if (err) 2027 if (err)
@@ -2037,7 +2055,7 @@ check_calls:
2037 2055
2038 err = add_callchain_ip(thread, cursor, parent, 2056 err = add_callchain_ip(thread, cursor, parent,
2039 root_al, &cpumode, ip, 2057 root_al, &cpumode, ip,
2040 false, NULL, 0, 0, 0); 2058 false, NULL, NULL, 0);
2041 2059
2042 if (err) 2060 if (err)
2043 return (err < 0) ? err : 0; 2061 return (err < 0) ? err : 0;