[PATCH v2 1/6] perf report: Add branch flag to callchain cursor node
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, >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); 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(>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; + boolbranch; + 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]; -
[PATCH v2 1/6] perf report: Add branch flag to callchain cursor node
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, >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); 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(>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; + boolbranch; + 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