Skip to contentSkip to conversation

perf tools: improve branch stack sampling

PATCH In review Stephane Eranian 2 participants 10 messages Mar 8, 2012 – Mar 9, 2012 perf events

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 60bddaf..a1386b2 100644
@@ -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
#2 lore raw

[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
index 60bddaf..a1386b2 100644
@@ -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

#3 lore raw

PATCH 2/4 perf record: add HEADER_BRANCH_STACK tag

In reply to Stephane Eranian

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
index a7c53a9..be4e1ee 100644
@@ -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
index c851495..0d9b6da 100644
@@ -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
index e68f617..21a6be0 100644
@@ -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
#4 lore raw

[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
index a7c53a9..be4e1ee 100644
@@ -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
index c851495..0d9b6da 100644
@@ -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
index e68f617..21a6be0 100644
@@ -27,7 +27,7 @@ enum {
 	HEADER_EVENT_DESC,
 	HEADER_CPU_TOPOLOGY,
 	HEADER_NUMA_TOPOLOGY,
-
+	HEADER_BRANCH_STACK,
 	HEADER_LAST_FEATURE,
 	HEADER_FEAT_BITS	= 256,
 };
#5 lore raw

PATCH 3/4 perf report: auto-detect branch stack sampling mode

In reply to Stephane Eranian

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
index 19b9092..87feeee 100644
@@ -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
index 2739ed1..88dbcf6 100644
@@ -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
index 7aa72a0..8505b9b 100644
@@ -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
#6 lore raw

[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
index 19b9092..87feeee 100644
@@ -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
index 2739ed1..88dbcf6 100644
@@ -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
index 7aa72a0..8505b9b 100644
@@ -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;
#7 lore raw

PATCH 4/4 perf report: enable TUI in branch view mode

In reply to Stephane Eranian

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
index 66e8523..8e91c6e 100644
@@ -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
index e650de8..002ebbf 100644
@@ -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
index 8505b9b..472aa5a 100644
@@ -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
index 5866ce6..ac49ef2 100644
@@ -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
#8 lore raw

[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
index 66e8523..8e91c6e 100644
@@ -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
index e650de8..002ebbf 100644
@@ -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
index 8505b9b..472aa5a 100644
@@ -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
index 5866ce6..ac49ef2 100644
@@ -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

#9 lore raw
In reply to Stephane Eranian
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 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

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