[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190221160652.1788-4-jonas.rabenstein@studium.uni-erlangen.de>
Date: Thu, 21 Feb 2019 17:06:52 +0100
From: Jonas Rabenstein <jonas.rabenstein@...dium.uni-erlangen.de>
To: linux-perf-users@...r.kernel.org
Cc: Adrian Hunter <adrian.hunter@...el.com>,
Alexander Shishkin <alexander.shishkin@...ux.intel.com>,
Andi Kleen <ak@...ux.intel.com>,
Arnaldo Carvalho de Melo <acme@...nel.org>,
David Miller <davem@...emloft.net>,
Eric Saint-Etienne <eric.saint.etienne@...cle.com>,
Ingo Molnar <mingo@...hat.com>, Jiri Olsa <jolsa@...hat.com>,
Kim Phillips <kim.phillips@....com>,
Konstantin Khlebnikov <khlebnikov@...dex-team.ru>,
Milian Wolff <milian.wolff@...b.com>,
Namhyung Kim <namhyung@...nel.org>,
Peter Zijlstra <peterz@...radead.org>,
Rob Gardner <rob.gardner@...cle.com>,
Sandipan Das <sandipan@...ux.ibm.com>,
linux-kernel@...r.kernel.org,
Jonas Rabenstein <jonas.rabenstein@...dium.uni-erlangen.de>
Subject: [PATCH 3/3] perf machine: add inline symbols to callchains
Use map__inlines to resolve inlined functions for every entry with
an symbol that should be added to a callchain.
Signed-off-by: Jonas Rabenstein <jonas.rabenstein@...dium.uni-erlangen.de>
---
tools/perf/util/machine.c | 115 ++++++++++++++++++++++++++++----------
1 file changed, 87 insertions(+), 28 deletions(-)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index dce29c21e4ea..070d074482b4 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1908,6 +1908,91 @@ struct iterations {
u64 cycles;
};
+static int __add_callchain_location(struct callchain_cursor *cursor,
+ struct symbol **parent,
+ struct addr_location *root_al,
+ u64 addr, struct addr_location *al,
+ bool branch, struct branch_flags *flags,
+ u64 branch_from, struct iterations *iter)
+{
+ int nr_loop_iter = 0;
+ u64 iter_cycles = 0;
+
+ if (symbol_conf.hide_unresolved && al->sym == NULL)
+ return 0;
+
+ if (al->sym) {
+ if (perf_hpp_list.parent && !*parent &&
+ symbol__match_regex(al->sym, &parent_regex))
+ *parent = al->sym;
+ else if (have_ignore_callees && root_al &&
+ symbol__match_regex(al->sym, &ignore_callees_regex)) {
+ /* Treat this symbol as the root,
+ forgetting its callees. */
+ *root_al = *al;
+ callchain_cursor_reset(cursor);
+ }
+ }
+
+ if (iter) {
+ nr_loop_iter = iter->nr_loop_iter;
+ iter_cycles = iter->cycles;
+ }
+ return callchain_cursor_append(cursor, addr, al->map, al->sym, branch,
+ flags, nr_loop_iter, iter_cycles,
+ branch_from, al->srcline);
+}
+
+static int __add_callchain_ip(struct callchain_cursor *cursor, u64 ip,
+ struct addr_location *al, bool branch,
+ struct branch_flags *flags, u64 branch_from,
+ struct iterations *iter, struct symbol **parent,
+ struct addr_location *root_al)
+{
+ struct inline_node *inline_node;
+ struct inline_list *inline_list;
+ const char *srcline;
+ struct symbol *symbol;
+ int err = 0;
+
+ al->srcline = callchain_srcline(al->map, al->sym, al->addr);
+ if (callchain_param.order == ORDER_CALLER)
+ err = __add_callchain_location(cursor, parent, root_al, ip, al,
+ branch, flags, branch_from, iter);
+ if (err || !al->map || !al->sym)
+ goto no_inline;
+
+ inline_node = map__inlines(al->map, ip, al->sym);
+ if (!inline_node || list_empty(&inline_node->val))
+ goto no_inline;
+
+ symbol = al->sym;
+ srcline = al->srcline;
+ list_for_each_entry(inline_list, &inline_node->val, list) {
+ if (inline_list->symbol == symbol)
+ continue;
+ al->sym = inline_list->symbol;
+ al->srcline = inline_list->srcline;
+ err = __add_callchain_location(cursor, parent, root_al, ip,
+ al, branch, flags,
+ branch_from, iter);
+ if (err)
+ break;
+ }
+
+ if (callchain_param.order == ORDER_CALLEE) {
+ al->srcline = srcline;
+ al->sym = symbol;
+ }
+
+no_inline:
+ if (!err && callchain_param.order == ORDER_CALLEE)
+ err = __add_callchain_location(cursor, parent, root_al, ip, al,
+ branch, flags, branch_from, iter);
+ return err;
+}
+
+
static int add_callchain_ip(struct thread *thread,
struct callchain_cursor *cursor,
struct symbol **parent,
@@ -1920,9 +2005,6 @@ static int add_callchain_ip(struct thread *thread,
u64 branch_from)
{
struct addr_location al;
- int nr_loop_iter = 0;
- u64 iter_cycles = 0;
- const char *srcline = NULL;
al.filtered = 0;
al.sym = NULL;
@@ -1955,31 +2037,8 @@ static int add_callchain_ip(struct thread *thread,
thread__find_symbol(thread, *cpumode, ip, &al);
}
- if (al.sym != NULL) {
- if (perf_hpp_list.parent && !*parent &&
- symbol__match_regex(al.sym, &parent_regex))
- *parent = al.sym;
- else if (have_ignore_callees && root_al &&
- symbol__match_regex(al.sym, &ignore_callees_regex)) {
- /* Treat this symbol as the root,
- forgetting its callees. */
- *root_al = al;
- callchain_cursor_reset(cursor);
- }
- }
-
- if (symbol_conf.hide_unresolved && al.sym == NULL)
- return 0;
-
- if (iter) {
- nr_loop_iter = iter->nr_loop_iter;
- iter_cycles = iter->cycles;
- }
-
- srcline = callchain_srcline(al.map, al.sym, al.addr);
- return callchain_cursor_append(cursor, ip, al.map, al.sym,
- branch, flags, nr_loop_iter,
- iter_cycles, branch_from, srcline);
+ return __add_callchain_ip(cursor, ip, &al, branch, flags, branch_from,
+ iter, parent, root_al);
}
struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
--
2.19.2
Powered by blists - more mailing lists