Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S944747AbcJSQYA (ORCPT ); Wed, 19 Oct 2016 12:24:00 -0400 Received: from mga03.intel.com ([134.134.136.65]:30265 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S938889AbcJSOOz (ORCPT ); Wed, 19 Oct 2016 10:14:55 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,514,1473145200"; d="scan'208";a="21673783" From: Jin Yao To: acme@kernel.org, jolsa@kernel.org Cc: Linux-kernel@vger.kernel.org, ak@linux.intel.com, kan.liang@intel.com, yao.jin@linux.intel.com Subject: [PATCH v2 1/6] perf report: Add branch flag to callchain cursor node Date: Thu, 20 Oct 2016 06:01:12 +0800 Message-Id: <1476914477-25420-2-git-send-email-yao.jin@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1476914477-25420-1-git-send-email-yao.jin@linux.intel.com> References: <1476914477-25420-1-git-send-email-yao.jin@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6322 Lines: 196 Since the branch ip has been added to call stack for easier browsing, this patch adds more branch information. For example, add a flag to indicate if this ip is a branch, and also add with the branch flag. Then we can know if the cursor node represents a branch and know what the branch flag it has. Signed-off-by: Jin Yao --- tools/perf/util/callchain.c | 11 +++++++-- tools/perf/util/callchain.h | 5 +++- tools/perf/util/machine.c | 56 +++++++++++++++++++++++++++++++++------------ 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 07fd30b..342ef20 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -730,7 +730,8 @@ merge_chain_branch(struct callchain_cursor *cursor, list_for_each_entry_safe(list, next_list, &src->val, list) { callchain_cursor_append(cursor, list->ip, - list->ms.map, list->ms.sym); + list->ms.map, list->ms.sym, + false, NULL); list_del(&list->list); free(list); } @@ -767,7 +768,8 @@ int callchain_merge(struct callchain_cursor *cursor, } int callchain_cursor_append(struct callchain_cursor *cursor, - u64 ip, struct map *map, struct symbol *sym) + u64 ip, struct map *map, struct symbol *sym, + bool branch, struct branch_flags *flags) { struct callchain_cursor_node *node = *cursor->last; @@ -782,6 +784,11 @@ int callchain_cursor_append(struct callchain_cursor *cursor, node->ip = ip; node->map = map; node->sym = sym; + node->branch = branch; + + if (flags) + memcpy(&node->branch_flags, flags, + sizeof(struct branch_flags)); cursor->nr++; diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 13e7554..40ecf25 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -129,6 +129,8 @@ struct callchain_cursor_node { u64 ip; struct map *map; struct symbol *sym; + bool branch; + struct branch_flags branch_flags; struct callchain_cursor_node *next; }; @@ -183,7 +185,8 @@ static inline void callchain_cursor_reset(struct callchain_cursor *cursor) } int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip, - struct map *map, struct symbol *sym); + struct map *map, struct symbol *sym, + bool branch, struct branch_flags *flags); /* Close a cursor writing session. Initialize for the reader */ static inline void callchain_cursor_commit(struct callchain_cursor *cursor) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index df85b9e..c2d9d9f 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1616,7 +1616,9 @@ static int add_callchain_ip(struct thread *thread, struct symbol **parent, struct addr_location *root_al, u8 *cpumode, - u64 ip) + u64 ip, + bool branch, + struct branch_flags *flags) { struct addr_location al; @@ -1668,7 +1670,8 @@ static int add_callchain_ip(struct thread *thread, if (symbol_conf.hide_unresolved && al.sym == NULL) return 0; - return callchain_cursor_append(cursor, al.addr, al.map, al.sym); + return callchain_cursor_append(cursor, al.addr, al.map, al.sym, + branch, flags); } struct branch_info *sample__resolve_bstack(struct perf_sample *sample, @@ -1757,7 +1760,9 @@ static int resolve_lbr_callchain_sample(struct thread *thread, /* LBR only affects the user callchain */ if (i != chain_nr) { struct branch_stack *lbr_stack = sample->branch_stack; - int lbr_nr = lbr_stack->nr, j; + int lbr_nr = lbr_stack->nr, j, k; + bool branch; + struct branch_flags *flags; /* * LBR callstack can only get user call chain. * The mix_chain_nr is kernel call chain @@ -1772,23 +1777,41 @@ static int resolve_lbr_callchain_sample(struct thread *thread, for (j = 0; j < mix_chain_nr; j++) { int err; + branch = false; + flags = NULL; + if (callchain_param.order == ORDER_CALLEE) { if (j < i + 1) ip = chain->ips[j]; - else if (j > i + 1) - ip = lbr_stack->entries[j - i - 2].from; - else + else if (j > i + 1) { + k = j - i - 2; + ip = lbr_stack->entries[k].from; + branch = true; + flags = &lbr_stack->entries[k].flags; + } else { ip = lbr_stack->entries[0].to; + branch = true; + flags = &lbr_stack->entries[0].flags; + } } else { - if (j < lbr_nr) - ip = lbr_stack->entries[lbr_nr - j - 1].from; + if (j < lbr_nr) { + k = lbr_nr - j - 1; + ip = lbr_stack->entries[k].from; + branch = true; + flags = &lbr_stack->entries[k].flags; + } else if (j > lbr_nr) ip = chain->ips[i + 1 - (j - lbr_nr)]; - else + else { ip = lbr_stack->entries[0].to; + branch = true; + flags = &lbr_stack->entries[0].flags; + } } - err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip); + err = add_callchain_ip(thread, cursor, parent, + root_al, &cpumode, ip, + branch, flags); if (err) return (err < 0) ? err : 0; } @@ -1872,10 +1895,12 @@ static int thread__resolve_callchain_sample(struct thread *thread, for (i = 0; i < nr; i++) { err = add_callchain_ip(thread, cursor, parent, root_al, - NULL, be[i].to); + NULL, be[i].to, + true, &be[i].flags); if (!err) err = add_callchain_ip(thread, cursor, parent, root_al, - NULL, be[i].from); + NULL, be[i].from, + true, &be[i].flags); if (err == -EINVAL) break; if (err) @@ -1903,7 +1928,9 @@ check_calls: if (ip < PERF_CONTEXT_MAX) ++nr_entries; - err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip); + err = add_callchain_ip(thread, cursor, parent, + root_al, &cpumode, ip, + false, NULL); if (err) return (err < 0) ? err : 0; @@ -1919,7 +1946,8 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) if (symbol_conf.hide_unresolved && entry->sym == NULL) return 0; return callchain_cursor_append(cursor, entry->ip, - entry->map, entry->sym); + entry->map, entry->sym, + false, NULL); } static int thread__resolve_callchain_unwind(struct thread *thread, -- 2.7.4