perf tools: improve branch stack sampling
cover perf tools: improve branch stack sampling
This patch set improves upon my LBR v6 patch series posted on LKML several weeks ago. It needs to be applied on top of it.
This series improves perf report and perf record when used with taken branch stack sampling.
For perf record, and based on users' feedback, it is possible to omit the branch type with the -b option. In that case, the filter is set to the default value of any branch type. The branch-filter option is now used to specify more precise branch types and privilege levels:
$ perf record -b foo equivalent to: $ perf record --branch-filter any foo
To filter on specific branch types:
$ perf record --branch-filter any_call foo
For perf report, it is now possible to omit the -b option and yet get branch view mode. Perf report is able to auto-detect if the perf.data file contains samples with branch stack and to switch to the branch mode. It is possible to override this by passing --no-branch-stack.
Furthermore, perf report now supports TUI in branch mode. It is possible to naviguate to both the source and destination functions of branches.
Stephane Eranian (4):
perf record: provide default branch stack sampling mode option perf record: add HEADER_BRANCH_STACK tag
perf report: auto-detect branch stack sampling mode perf report: enable TUI in branch view mode
tools/perf/Documentation/perf-record.txt | 23 ++++-- tools/perf/Documentation/perf-report.txt | 7 +- tools/perf/builtin-record.c | 71 +++++++++++------ tools/perf/builtin-report.c | 121 ++++++++++++++++++++--------- tools/perf/util/header.c | 13 +++ tools/perf/util/header.h | 2 +- tools/perf/util/session.c | 1 + tools/perf/util/sort.c | 2 +- tools/perf/util/sort.h | 8 +- tools/perf/util/symbol.h | 7 ++- tools/perf/util/ui/browsers/hists.c | 62 ++++++++++++--- 11 files changed, 225 insertions(+), 92 deletions(-)
Signature · 1 line
1.7.4.1
PATCH 1/4 perf record: provide default branch stack sampling mode option
This patch chanegs the logic of the -b, --branch-stack options of perf record.
Based on users' request, the patch provides a default filter mode with the -b (or --branch-any) option. With the option, any type of taken branches is sampled.
With -j (or --branch-filter), the user can specify any valid combination of branch types and privilege levels if supported by the underlying hardware.
The -b (--branch any) is a shortcut for: --branch-filter any.
$ perf record -b foo or $ perf record --branch-filter any foo
For more specific filtering:
$ perf record --branch-filter ind_call,u foo
--- tools/perf/Documentation/perf-record.txt | 23 ++++++---- tools/perf/builtin-record.c | 68 +++++++++++++++++++----------- 2 files changed, 57 insertions(+), 34 deletions(-)
tools/perf/Documentation/perf-record.txt +14 -9
@@ -153,14 +153,19 @@ corresponding events, i.e., they always refer to events defined earlier on the c line. -b:: ---branch-stack:: +--branch-any:: +Enable taken branch stack sampling. Any type of taken branch may be sampled. +This is a shortcut for --branch-filter any. See --branch-filter for more infos. + +-j:: +--branch-filter:: Enable taken branch stack sampling. Each sample captures a series of consecutive taken branches. The number of branches captured with each sample depends on the underlying hardware, the type of branches of interest, and the executed code. It is possible to select the types of branches captured by enabling filters. The following filters are defined: - - any : any type of branches + - any: any type of branches - any_call: any function call or system call - any_ret: any function return or system call return - any_ind: any indirect branch
@@ -169,13 +174,13 @@ It is possible to select the types of branches captured by enabling filters. The - hv: only when the target is at the hypervisor level + -At least one of any, any_call, any_ret, any_ind must be provided. The privilege levels may -be ommitted, in which case, the privilege levels of the associated event are applied to the -branch filter. Both kernel (k) and hypervisor (hv) privilege levels are subject to -permissions. When sampling on multiple events, branch stack sampling is enabled for all -the sampling events. The sampled branch type is the same for all events. -Note that taken branch sampling may not be available on all processors. -The various filters must be specified as a comma separated list: -b any_ret,u,k +The option requires at least one branch type among any, any_call, any_ret, ind_call. +The privilege levels may be ommitted, in which case, the privilege levels of the associated +event are applied to the branch filter. Both kernel (k) and hypervisor (hv) privilege +levels are subject to permissions. When sampling on multiple events, branch stack sampling +is enabled for all the sampling events. The sampled branch type is the same for all events. +The various filters must be specified as a comma separated list: --branch-filter any_ret,u,k +Note that this feature may not be available on all processors. SEE ALSO --------
tools/perf/builtin-record.c +43 -25
98 lines not on this page · raw message
Signature · 1 line
1.7.4.1
[tip:perf/hw-branch-sampling] perf record: Provide default branch stack sampling mode option
Commit-ID: a5aabdacde9caff54886ae454e0fad2f26929753 Gitweb: http://git.kernel.org/tip/a5aabdacde9caff54886ae454e0fad2f26929753 Author: Stephane Eranian <[email protected]> AuthorDate: Thu, 8 Mar 2012 23:47:45 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 9 Mar 2012 08:26:07 +0100
perf record: Provide default branch stack sampling mode option
This patch chanegs the logic of the -b, --branch-stack options of perf record.
Based on users' request, the patch provides a default filter mode with the -b (or --branch-any) option. With the option, any type of taken branches is sampled.
With -j (or --branch-filter), the user can specify any valid combination of branch types and privilege levels if supported by the underlying hardware.
The -b (--branch any) is a shortcut for: --branch-filter any.
$ perf record -b foo
or:
$ perf record --branch-filter any foo
For more specific filtering:
$ perf record --branch-filter ind_call,u foo
--- tools/perf/Documentation/perf-record.txt | 23 ++++++---- tools/perf/builtin-record.c | 68 +++++++++++++++++++----------- 2 files changed, 57 insertions(+), 34 deletions(-)
tools/perf/Documentation/perf-record.txt +14 -9
@@ -153,14 +153,19 @@ corresponding events, i.e., they always refer to events defined earlier on the c line. -b:: ---branch-stack:: +--branch-any:: +Enable taken branch stack sampling. Any type of taken branch may be sampled. +This is a shortcut for --branch-filter any. See --branch-filter for more infos. + +-j:: +--branch-filter:: Enable taken branch stack sampling. Each sample captures a series of consecutive taken branches. The number of branches captured with each sample depends on the underlying hardware, the type of branches of interest, and the executed code. It is possible to select the types of branches captured by enabling filters. The following filters are defined: - - any : any type of branches + - any: any type of branches - any_call: any function call or system call - any_ret: any function return or system call return - any_ind: any indirect branch
@@ -169,13 +174,13 @@ following filters are defined: - hv: only when the target is at the hypervisor level + -At least one of any, any_call, any_ret, any_ind must be provided. The privilege levels may -be ommitted, in which case, the privilege levels of the associated event are applied to the -branch filter. Both kernel (k) and hypervisor (hv) privilege levels are subject to -permissions. When sampling on multiple events, branch stack sampling is enabled for all -the sampling events. The sampled branch type is the same for all events. -Note that taken branch sampling may not be available on all processors. -The various filters must be specified as a comma separated list: -b any_ret,u,k +The option requires at least one branch type among any, any_call, any_ret, ind_call. +The privilege levels may be ommitted, in which case, the privilege levels of the associated +event are applied to the branch filter. Both kernel (k) and hypervisor (hv) privilege +levels are subject to permissions. When sampling on multiple events, branch stack sampling +is enabled for all the sampling events. The sampled branch type is the same for all events. +The various filters must be specified as a comma separated list: --branch-filter any_ret,u,k +Note that this feature may not be available on all processors. SEE ALSO --------
tools/perf/builtin-record.c +43 -25
98 lines not on this page · raw message
PATCH 2/4 perf record: add HEADER_BRANCH_STACK tag
In reply to Stephane EranianThis patch adds a new feature bit, namely, HEADER_BRANCH_STACK. When present, it indicates that sample records may contain branch stack.
This could be useful to a viewer to switch to branch mode without having to parse all the samples or without a specific cmdline option.
This will be used in a subsequent patch to enhance perf report with branch stacks.
--- tools/perf/builtin-record.c | 3 +++ tools/perf/util/header.c | 13 +++++++++++++ tools/perf/util/header.h | 2 +- 3 files changed, 17 insertions(+), 1 deletions(-)
tools/perf/builtin-record.c +3 -0
@@ -473,6 +473,9 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)if (!have_tracepoints (&evsel_list->entries))perf_header__clear_feat (&session->header,HEADER_TRACE_INFO ); +if (!rec->opts.branch_stack) +perf_header__clear_feat (&session->header,HEADER_BRANCH_STACK ); +if (!rec->file_new) { err =perf_session__read_header (session, output);if (err <0 )
tools/perf/util/header.c +13 -0
@@ -1023,6 +1023,12 @@ static int write_cpuid(int fd, struct perf_header *h __used,return do_write_string (fd, buffer); } +static int write_branch_stack (int fd__used ,struct perf_header *h__used , +struct perf_evlist *evlist__used ) +{ +return 0 ; +} +static void print_hostname (struct perf_header *ph,int fd,FILE *fp) {char *str =do_read_string (fd, ph);
@@ -1315,6 +1321,12 @@ static void print_cpuid(struct perf_header *ph, int fd, FILE *fp)free (str); } +static void print_branch_stack (struct perf_header *ph__used ,int fd__used , +FILE *fp) +{ +fprintf (fp,"# contains samples with branch stack\n" ); +} +static int __event_process_build_id (struct build_id_event *bev,char *filename,struct perf_session *session)
@@ -1519,6 +1531,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {FEAT_OPA (HEADER_CMDLINE , cmdline),FEAT_OPF (HEADER_CPU_TOPOLOGY , cpu_topology),FEAT_OPF (HEADER_NUMA_TOPOLOGY , numa_topology), + FEAT_OPA(HEADER_BRANCH_STACK, branch_stack), }; struct header_print_data {
tools/perf/util/header.h +1 -1
@@ -27,7 +27,7 @@ enum {HEADER_EVENT_DESC ,HEADER_CPU_TOPOLOGY ,HEADER_NUMA_TOPOLOGY , - +HEADER_BRANCH_STACK ,HEADER_LAST_FEATURE , HEADER_FEAT_BITS = 256, };
Signature · 1 line
1.7.4.1
[tip:perf/hw-branch-sampling] perf record: Add HEADER_BRANCH_STACK tag
Commit-ID: 330aa675b4f92a422cb6d3acbbfd16a628017520 Gitweb: http://git.kernel.org/tip/330aa675b4f92a422cb6d3acbbfd16a628017520 Author: Stephane Eranian <[email protected]> AuthorDate: Thu, 8 Mar 2012 23:47:46 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 9 Mar 2012 08:26:08 +0100
perf record: Add HEADER_BRANCH_STACK tag
This patch adds a new feature bit, namely, HEADER_BRANCH_STACK. When present, it indicates that sample records may contain branch stack.
This could be useful to a viewer to switch to branch mode without having to parse all the samples or without a specific cmdline option.
This will be used in a subsequent patch to enhance perf report with branch stacks.
--- tools/perf/builtin-record.c | 3 +++ tools/perf/util/header.c | 13 +++++++++++++ tools/perf/util/header.h | 2 +- 3 files changed, 17 insertions(+), 1 deletions(-)
tools/perf/builtin-record.c +3 -0
@@ -473,6 +473,9 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)if (!have_tracepoints (&evsel_list->entries))perf_header__clear_feat (&session->header,HEADER_TRACE_INFO ); +if (!rec->opts.branch_stack) +perf_header__clear_feat (&session->header,HEADER_BRANCH_STACK ); +if (!rec->file_new) { err =perf_session__read_header (session, output);if (err <0 )
tools/perf/util/header.c +13 -0
@@ -1023,6 +1023,12 @@ write_it:return do_write_string (fd, buffer); } +static int write_branch_stack (int fd__used ,struct perf_header *h__used , +struct perf_evlist *evlist__used ) +{ +return 0 ; +} +static void print_hostname (struct perf_header *ph,int fd,FILE *fp) {char *str =do_read_string (fd, ph);
@@ -1315,6 +1321,12 @@ static void print_cpuid(struct perf_header *ph, int fd, FILE *fp)free (str); } +static void print_branch_stack (struct perf_header *ph__used ,int fd__used , +FILE *fp) +{ +fprintf (fp,"# contains samples with branch stack\n" ); +} +static int __event_process_build_id (struct build_id_event *bev,char *filename,struct perf_session *session)
@@ -1519,6 +1531,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {FEAT_OPA (HEADER_CMDLINE , cmdline),FEAT_OPF (HEADER_CPU_TOPOLOGY , cpu_topology),FEAT_OPF (HEADER_NUMA_TOPOLOGY , numa_topology), + FEAT_OPA(HEADER_BRANCH_STACK, branch_stack), }; struct header_print_data {
tools/perf/util/header.h +1 -1
@@ -27,7 +27,7 @@ enum {HEADER_EVENT_DESC ,HEADER_CPU_TOPOLOGY ,HEADER_NUMA_TOPOLOGY , - +HEADER_BRANCH_STACK ,HEADER_LAST_FEATURE , HEADER_FEAT_BITS = 256, };
PATCH 3/4 perf report: auto-detect branch stack sampling mode
In reply to Stephane EranianThis patch enhances perf report to auto-detect when the perf.data file contains samples with branch stacks. That way it is not necessary to use the -b option.
To force branch view mode to off, simply use --no-branch-stack.
--- tools/perf/Documentation/perf-report.txt | 7 +++- tools/perf/builtin-report.c | 50 ++++++++++++++++++++--------- tools/perf/util/sort.c | 2 +- tools/perf/util/sort.h | 2 +- 4 files changed, 41 insertions(+), 20 deletions(-)
tools/perf/Documentation/perf-report.txt +5 -2
@@ -157,8 +157,11 @@ OPTIONS --branch-stack:: Use the addresses of sampled taken branches instead of the instruction address to build the histograms. To generate meaningful output, the - perf.data file must have been obtained using perf record -b xxx where - xxx is a branch filter option. + perf.data file must have been obtained using perf record -b or + perf record --branch-filter xxx where xxx is a branch filter option. + perf report is able to auto-detect whether a perf.data file contains + branch stacks and it will automatically switch to the branch view mode, + unless --no-branch-stack is used. SEE ALSO --------
tools/perf/builtin-report.c +34 -16
111 lines not on this page · raw message
tools/perf/util/sort.c +1 -1
@@ -8,7 +8,7 @@ const char default_sort_order[] = "comm,dso,symbol";const char *sort_order = default_sort_order;int sort__need_collapse =0 ;int sort__has_parent =0 ; -bool sort__branch_mode; +int sort__branch_mode =-1 ;/* -1 = means not set */ enum sort_type sort__first_dimension;
tools/perf/util/sort.h +1 -1
@@ -31,7 +31,7 @@ extern const char *parent_pattern;extern const char default_sort_order[];extern int sort__need_collapse;extern int sort__has_parent; -extern bool sort__branch_mode; +extern int sort__branch_mode;extern char *field_sep;extern struct sort_entry sort_comm;extern struct sort_entry sort_dso;
Signature · 1 line
1.7.4.1
[tip:perf/hw-branch-sampling] perf report: Auto-detect branch stack sampling mode
Commit-ID: 993ac88d5892629fbe1f8a54857f9947f49f0d96 Gitweb: http://git.kernel.org/tip/993ac88d5892629fbe1f8a54857f9947f49f0d96 Author: Stephane Eranian <[email protected]> AuthorDate: Thu, 8 Mar 2012 23:47:47 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 9 Mar 2012 08:26:08 +0100
perf report: Auto-detect branch stack sampling mode
This patch enhances perf report to auto-detect when the perf.data file contains samples with branch stacks. That way it is not necessary to use the -b option.
To force branch view mode to off, simply use --no-branch-stack.
--- tools/perf/Documentation/perf-report.txt | 7 +++- tools/perf/builtin-report.c | 50 ++++++++++++++++++++--------- tools/perf/util/sort.c | 2 +- tools/perf/util/sort.h | 2 +- 4 files changed, 41 insertions(+), 20 deletions(-)
tools/perf/Documentation/perf-report.txt +5 -2
@@ -157,8 +157,11 @@ OPTIONS --branch-stack:: Use the addresses of sampled taken branches instead of the instruction address to build the histograms. To generate meaningful output, the - perf.data file must have been obtained using perf record -b xxx where - xxx is a branch filter option. + perf.data file must have been obtained using perf record -b or + perf record --branch-filter xxx where xxx is a branch filter option. + perf report is able to auto-detect whether a perf.data file contains + branch stacks and it will automatically switch to the branch view mode, + unless --no-branch-stack is used. SEE ALSO --------
tools/perf/builtin-report.c +34 -16
111 lines not on this page · raw message
tools/perf/util/sort.c +1 -1
@@ -8,7 +8,7 @@ const char default_sort_order[] = "comm,dso,symbol";const char *sort_order = default_sort_order;int sort__need_collapse =0 ;int sort__has_parent =0 ; -bool sort__branch_mode; +int sort__branch_mode =-1 ;/* -1 = means not set */ enum sort_type sort__first_dimension;
tools/perf/util/sort.h +1 -1
@@ -31,7 +31,7 @@ extern const char *parent_pattern;extern const char default_sort_order[];extern int sort__need_collapse;extern int sort__has_parent; -extern bool sort__branch_mode; +extern int sort__branch_mode;extern char *field_sep;extern struct sort_entry sort_comm;extern struct sort_entry sort_dso;
PATCH 4/4 perf report: enable TUI in branch view mode
In reply to Stephane EranianThis patch updates perf report to support TUI mode when the perf.data file contains samples with branch stacks.
For each row in the report, it is possible to annotate either the source or target of each branch.
--- tools/perf/builtin-report.c | 73 ++++++++++++++++++++++++----------- tools/perf/util/session.c | 1 + tools/perf/util/sort.h | 6 ++- tools/perf/util/symbol.h | 7 +++- tools/perf/util/ui/browsers/hists.c | 62 ++++++++++++++++++++++++------ 5 files changed, 111 insertions(+), 38 deletions(-)
tools/perf/builtin-report.c +50 -23
@@ -64,7 +64,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,int err =0 ;unsigned i;struct hist_entry *he; -struct branch_info *bi; +struct branch_info *bi, *bx;if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) {
@@ -87,13 +87,45 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,* and not events sampled. Thus we use a pseudo period of 1. */ he =__hists__add_branch_entry (&evsel->hists, al, parent, - &bi[i],1 ); + &bi[i],1 );if (he) { +struct annotation *notes; + err = -ENOMEM ; + bx = he->branch_info; +if (bx->from.sym && use_browser >0 ) { + notes =symbol__annotation (bx->from.sym); +if (!notes->src + &&symbol__alloc_hist (bx->from.sym) <0 ) + goto out; + + err =symbol__inc_addr_samples (bx->from.sym, + bx->from.map, + evsel->idx, + bx->from.al_addr); +if (err) + goto out; + } + +if (bx->to.sym && use_browser >0 ) { + notes =symbol__annotation (bx->to.sym); +if (!notes->src + &&symbol__alloc_hist (bx->to.sym) <0 ) + goto out; + + err =symbol__inc_addr_samples (bx->to.sym, + bx->to.map, + evsel->idx, + bx->to.al_addr); +if (err) + goto out; + } evsel->hists.stats.total_period +=1 ;hists__inc_nr_events (&evsel->hists,PERF_RECORD_SAMPLE ); + err =0 ; }else return -ENOMEM ; } +out:return err; }
@@ -615,32 +647,19 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)if (sort__branch_mode ==-1 && has_br_stack) sort__branch_mode =1 ; +/* sort__branch_mode could be 0 if --no-branch-stack */ if (sort__branch_mode ==1 ) { -if (use_browser) -fprintf (stderr,"Warning: TUI interface not supported" -" in branch mode\n" ); -if (symbol_conf.dso_list_str !=NULL ) -fprintf (stderr,"Warning: dso filtering not supported" -" in branch mode\n" ); -if (symbol_conf.sym_list_str !=NULL ) -fprintf (stderr,"Warning: symbol filtering not" -" supported in branch mode\n" ); - - report.use_stdio = true; - use_browser =0 ; -setup_browser (true); - symbol_conf.dso_list_str =NULL ; - symbol_conf.sym_list_str =NULL ; -/* -* if no sort_order is provided, then specify branch-mode -* specific order +* if no sort_order is provided, then specify +* branch-mode specific order */ if (sort_order == default_sort_order) sort_order ="comm,dso_from,symbol_from," "dso_to,symbol_to" ; - }else if (strcmp (report.input_name,"-" ) !=0 ) { + } + +if (strcmp (report.input_name,"-" ) !=0 ) {setup_browser (true); }else { use_browser =0 ;
@@ -696,9 +715,17 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)if (argc)usage_with_options (report_usage, options); -sort_entry__setup_elide (&sort_dso, symbol_conf.dso_list,"dso" , stdout);sort_entry__setup_elide (&sort_comm, symbol_conf.comm_list,"comm" , stdout); -sort_entry__setup_elide (&sort_sym, symbol_conf.sym_list,"symbol" , stdout); + +if (sort__branch_mode ==1 ) { +sort_entry__setup_elide (&sort_dso_from, symbol_conf.dso_from_list,"dso_from" , stdout); +sort_entry__setup_elide (&sort_dso_to, symbol_conf.dso_to_list,"dso_to" , stdout); +sort_entry__setup_elide (&sort_sym_from, symbol_conf.sym_from_list,"sym_from" , stdout); +sort_entry__setup_elide (&sort_sym_to, symbol_conf.sym_to_list,"sym_to" , stdout); + }else { +sort_entry__setup_elide (&sort_dso, symbol_conf.dso_list,"dso" , stdout); +sort_entry__setup_elide (&sort_sym, symbol_conf.sym_list,"symbol" , stdout); + } ret =__cmd_report (&report); error:
tools/perf/util/session.c +1 -0
@@ -263,6 +263,7 @@ static void ip__resolve_ams(struct machine *self, struct thread *thread, } found: ams->addr = ip; + ams->al_addr = al.addr; ams->sym = al.sym; ams->map = al.map; }
tools/perf/util/sort.h +4 -2
@@ -37,8 +37,10 @@ extern struct sort_entry sort_comm;extern struct sort_entry sort_dso;extern struct sort_entry sort_sym;extern struct sort_entry sort_parent; -extern struct sort_entry sort_lbr_dso; -extern struct sort_entry sort_lbr_sym; +extern struct sort_entry sort_dso_from; +extern struct sort_entry sort_dso_to; +extern struct sort_entry sort_sym_from; +extern struct sort_entry sort_sym_to;extern enum sort_type sort__first_dimension;/**
tools/perf/util/symbol.h +6 -1
@@ -97,7 +97,11 @@ struct symbol_conf { *col_width_list_str;struct strlist *dso_list, *comm_list, - *sym_list; + *sym_list, + *dso_from_list, + *dso_to_list, + *sym_from_list, + *sym_to_list;const char *symfs; };
@@ -125,6 +129,7 @@ struct addr_map_symbol {struct map *map;struct symbol *sym;u64 addr; +u64 al_addr; };struct branch_info {
tools/perf/util/ui/browsers/hists.c +50 -12
110 lines not on this page · raw message
Signature · 1 line
1.7.4.1
[tip:perf/hw-branch-sampling] perf report: Enable TUI in branch view mode
Commit-ID: a68c2c58171391ef368fced32a555b2f0ff106e5 Gitweb: http://git.kernel.org/tip/a68c2c58171391ef368fced32a555b2f0ff106e5 Author: Stephane Eranian <[email protected]> AuthorDate: Thu, 8 Mar 2012 23:47:48 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 9 Mar 2012 08:26:08 +0100
perf report: Enable TUI in branch view mode
This patch updates perf report to support TUI mode when the perf.data file contains samples with branch stacks.
For each row in the report, it is possible to annotate either the source or target of each branch.
--- tools/perf/builtin-report.c | 73 ++++++++++++++++++++++++----------- tools/perf/util/session.c | 1 + tools/perf/util/sort.h | 6 ++- tools/perf/util/symbol.h | 7 +++- tools/perf/util/ui/browsers/hists.c | 62 ++++++++++++++++++++++++------ 5 files changed, 111 insertions(+), 38 deletions(-)
tools/perf/builtin-report.c +50 -23
@@ -64,7 +64,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,int err =0 ;unsigned i;struct hist_entry *he; -struct branch_info *bi; +struct branch_info *bi, *bx;if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) {
@@ -87,13 +87,45 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,* and not events sampled. Thus we use a pseudo period of 1. */ he =__hists__add_branch_entry (&evsel->hists, al, parent, - &bi[i],1 ); + &bi[i],1 );if (he) { +struct annotation *notes; + err = -ENOMEM ; + bx = he->branch_info; +if (bx->from.sym && use_browser >0 ) { + notes =symbol__annotation (bx->from.sym); +if (!notes->src + &&symbol__alloc_hist (bx->from.sym) <0 ) + goto out; + + err =symbol__inc_addr_samples (bx->from.sym, + bx->from.map, + evsel->idx, + bx->from.al_addr); +if (err) + goto out; + } + +if (bx->to.sym && use_browser >0 ) { + notes =symbol__annotation (bx->to.sym); +if (!notes->src + &&symbol__alloc_hist (bx->to.sym) <0 ) + goto out; + + err =symbol__inc_addr_samples (bx->to.sym, + bx->to.map, + evsel->idx, + bx->to.al_addr); +if (err) + goto out; + } evsel->hists.stats.total_period +=1 ;hists__inc_nr_events (&evsel->hists,PERF_RECORD_SAMPLE ); + err =0 ; }else return -ENOMEM ; } +out:return err; }
@@ -615,32 +647,19 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)if (sort__branch_mode ==-1 && has_br_stack) sort__branch_mode =1 ; +/* sort__branch_mode could be 0 if --no-branch-stack */ if (sort__branch_mode ==1 ) { -if (use_browser) -fprintf (stderr,"Warning: TUI interface not supported" -" in branch mode\n" ); -if (symbol_conf.dso_list_str !=NULL ) -fprintf (stderr,"Warning: dso filtering not supported" -" in branch mode\n" ); -if (symbol_conf.sym_list_str !=NULL ) -fprintf (stderr,"Warning: symbol filtering not" -" supported in branch mode\n" ); - - report.use_stdio = true; - use_browser =0 ; -setup_browser (true); - symbol_conf.dso_list_str =NULL ; - symbol_conf.sym_list_str =NULL ; -/* -* if no sort_order is provided, then specify branch-mode -* specific order +* if no sort_order is provided, then specify +* branch-mode specific order */ if (sort_order == default_sort_order) sort_order ="comm,dso_from,symbol_from," "dso_to,symbol_to" ; - }else if (strcmp (report.input_name,"-" ) !=0 ) { + } + +if (strcmp (report.input_name,"-" ) !=0 ) {setup_browser (true); }else { use_browser =0 ;
@@ -696,9 +715,17 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)if (argc)usage_with_options (report_usage, options); -sort_entry__setup_elide (&sort_dso, symbol_conf.dso_list,"dso" , stdout);sort_entry__setup_elide (&sort_comm, symbol_conf.comm_list,"comm" , stdout); -sort_entry__setup_elide (&sort_sym, symbol_conf.sym_list,"symbol" , stdout); + +if (sort__branch_mode ==1 ) { +sort_entry__setup_elide (&sort_dso_from, symbol_conf.dso_from_list,"dso_from" , stdout); +sort_entry__setup_elide (&sort_dso_to, symbol_conf.dso_to_list,"dso_to" , stdout); +sort_entry__setup_elide (&sort_sym_from, symbol_conf.sym_from_list,"sym_from" , stdout); +sort_entry__setup_elide (&sort_sym_to, symbol_conf.sym_to_list,"sym_to" , stdout); + }else { +sort_entry__setup_elide (&sort_dso, symbol_conf.dso_list,"dso" , stdout); +sort_entry__setup_elide (&sort_sym, symbol_conf.sym_list,"symbol" , stdout); + } ret =__cmd_report (&report); error:
tools/perf/util/session.c +1 -0
@@ -263,6 +263,7 @@ static void ip__resolve_ams(struct machine *self, struct thread *thread, } found: ams->addr = ip; + ams->al_addr = al.addr; ams->sym = al.sym; ams->map = al.map; }
tools/perf/util/sort.h +4 -2
@@ -37,8 +37,10 @@ extern struct sort_entry sort_comm;extern struct sort_entry sort_dso;extern struct sort_entry sort_sym;extern struct sort_entry sort_parent; -extern struct sort_entry sort_lbr_dso; -extern struct sort_entry sort_lbr_sym; +extern struct sort_entry sort_dso_from; +extern struct sort_entry sort_dso_to; +extern struct sort_entry sort_sym_from; +extern struct sort_entry sort_sym_to;extern enum sort_type sort__first_dimension;/**
tools/perf/util/symbol.h +6 -1
@@ -97,7 +97,11 @@ struct symbol_conf { *col_width_list_str;struct strlist *dso_list, *comm_list, - *sym_list; + *sym_list, + *dso_from_list, + *dso_to_list, + *sym_from_list, + *sym_to_list;const char *symfs; };
@@ -125,6 +129,7 @@ struct addr_map_symbol {struct map *map;struct symbol *sym;u64 addr; +u64 al_addr; };struct branch_info {
tools/perf/util/ui/browsers/hists.c +50 -12
110 lines not on this page · raw message
Quoted 37 lines · Stephane Eranian
This patch set improves upon my LBR v6 patch series posted on LKML several weeks ago. It needs to be applied on top of it.
This series improves perf report and perf record when used with taken branch stack sampling.
For perf record, and based on users' feedback, it is possible to omit the branch type with the -b option. In that case, the filter is set to the default value of any branch type. The branch-filter option is now used to specify more precise branch types and privilege levels:
$ perf record -b foo equivalent to: $ perf record --branch-filter any fooTo filter on specific branch types:
$ perf record --branch-filter any_call fooFor perf report, it is now possible to omit the -b option and yet get branch view mode. Perf report is able to auto-detect if the perf.data file contains samples with branch stack and to switch to the branch mode. It is possible to override this by passing --no-branch-stack.
Furthermore, perf report now supports TUI in branch mode. It is possible to naviguate to both the source and destination functions of branches.
Signed-off-by Stephane Eranian <[email protected]>Stephane Eranian (4):
perf record: provide default branch stack sampling mode option perf record: addHEADER_BRANCH_STACKtag
perf report: auto-detect branch stack sampling mode perf report: enable TUI in branch view mode
Quoted 12 lines
tools/perf/Documentation/perf-record.txt | 23 ++++-- tools/perf/Documentation/perf-report.txt | 7 +- tools/perf/builtin-record.c | 71 +++++++++++------ tools/perf/builtin-report.c | 121 ++++++++++++++++++++--------- tools/perf/util/header.c | 13 +++ tools/perf/util/header.h | 2 +- tools/perf/util/session.c | 1 + tools/perf/util/sort.c | 2 +- tools/perf/util/sort.h | 8 +- tools/perf/util/symbol.h | 7 ++- tools/perf/util/ui/browsers/hists.c | 62 ++++++++++++--- 11 files changed, 225 insertions(+), 92 deletions(-)
Ok, I tried it out and this is now very usable. I particularly liked the detail how the TUI now allows annotation of both the source and the target symbols.
I've noticed two small usability glitches:
1) when annotating a symbol and typing 'q' to go back one level, it goes back *two* levels. This is intuitive when just one symbol is annotated, but confusing when there are two
symbols: I frequently want to go back to annotate the other symbol as well.
2) two symbols are offered for annotation even when the source RIP and target RIP is within the same symbol.
Anyway, I've applied all your patches to tip:perf/hw-branch-sampling branch, and if the remaining issues are resolved will merge them into tip:perf/core for upstream merging. Depending on when the fixes arrive this could be v3.4 or v3.5.
Thanks,
Ingo