aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorStephane Eranian <eranian@google.com>2012-03-08 17:47:45 -0500
committerIngo Molnar <mingo@elte.hu>2012-03-09 02:26:07 -0500
commita5aabdacde9caff54886ae454e0fad2f26929753 (patch)
tree6784617e8e37edf1ac25763bfc7481eef83d74ae /tools/perf
parent114382a0aea97974803c942f106d462cbca5c64d (diff)
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 Signed-off-by: Stephane Eranian <eranian@google.com> Cc: peterz@infradead.org Cc: acme@redhat.com Cc: asharma@fb.com Cc: ravitillo@lbl.gov Cc: vweaver1@eecs.utk.edu Cc: khandual@linux.vnet.ibm.com Cc: dsahern@gmail.com Link: http://lkml.kernel.org/r/1331246868-19905-2-git-send-email-eranian@google.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-record.txt23
-rw-r--r--tools/perf/builtin-record.c68
2 files changed, 57 insertions, 34 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 60bddaf0e5b..a1386b2fff0 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -153,14 +153,19 @@ corresponding events, i.e., they always refer to events defined earlier on the c
153line. 153line.
154 154
155-b:: 155-b::
156--branch-stack:: 156--branch-any::
157Enable taken branch stack sampling. Any type of taken branch may be sampled.
158This is a shortcut for --branch-filter any. See --branch-filter for more infos.
159
160-j::
161--branch-filter::
157Enable taken branch stack sampling. Each sample captures a series of consecutive 162Enable taken branch stack sampling. Each sample captures a series of consecutive
158taken branches. The number of branches captured with each sample depends on the 163taken branches. The number of branches captured with each sample depends on the
159underlying hardware, the type of branches of interest, and the executed code. 164underlying hardware, the type of branches of interest, and the executed code.
160It is possible to select the types of branches captured by enabling filters. The 165It is possible to select the types of branches captured by enabling filters. The
161following filters are defined: 166following filters are defined:
162 167
163 - any : any type of branches 168 - any: any type of branches
164 - any_call: any function call or system call 169 - any_call: any function call or system call
165 - any_ret: any function return or system call return 170 - any_ret: any function return or system call return
166 - any_ind: any indirect branch 171 - any_ind: any indirect branch
@@ -169,13 +174,13 @@ following filters are defined:
169 - hv: only when the target is at the hypervisor level 174 - hv: only when the target is at the hypervisor level
170 175
171+ 176+
172At least one of any, any_call, any_ret, any_ind must be provided. The privilege levels may 177The option requires at least one branch type among any, any_call, any_ret, ind_call.
173be ommitted, in which case, the privilege levels of the associated event are applied to the 178The privilege levels may be ommitted, in which case, the privilege levels of the associated
174branch filter. Both kernel (k) and hypervisor (hv) privilege levels are subject to 179event are applied to the branch filter. Both kernel (k) and hypervisor (hv) privilege
175permissions. When sampling on multiple events, branch stack sampling is enabled for all 180levels are subject to permissions. When sampling on multiple events, branch stack sampling
176the sampling events. The sampled branch type is the same for all events. 181is enabled for all the sampling events. The sampled branch type is the same for all events.
177Note that taken branch sampling may not be available on all processors. 182The various filters must be specified as a comma separated list: --branch-filter any_ret,u,k
178The various filters must be specified as a comma separated list: -b any_ret,u,k 183Note that this feature may not be available on all processors.
179 184
180SEE ALSO 185SEE ALSO
181-------- 186--------
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 1c49d4e8767..a7c53a9ef37 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -660,7 +660,7 @@ static const struct branch_mode branch_modes[] = {
660}; 660};
661 661
662static int 662static int
663parse_branch_stack(const struct option *opt, const char *str, int unset __used) 663parse_branch_stack(const struct option *opt, const char *str, int unset)
664{ 664{
665#define ONLY_PLM \ 665#define ONLY_PLM \
666 (PERF_SAMPLE_BRANCH_USER |\ 666 (PERF_SAMPLE_BRANCH_USER |\
@@ -669,40 +669,53 @@ parse_branch_stack(const struct option *opt, const char *str, int unset __used)
669 669
670 uint64_t *mode = (uint64_t *)opt->value; 670 uint64_t *mode = (uint64_t *)opt->value;
671 const struct branch_mode *br; 671 const struct branch_mode *br;
672 char *s, *os, *p; 672 char *s, *os = NULL, *p;
673 int ret = -1; 673 int ret = -1;
674 674
675 *mode = 0; 675 if (unset)
676 return 0;
676 677
677 /* because str is read-only */ 678 /*
678 s = os = strdup(str); 679 * cannot set it twice, -b + --branch-filter for instance
679 if (!s) 680 */
681 if (*mode)
680 return -1; 682 return -1;
681 683
682 for (;;) { 684 /* str may be NULL in case no arg is passed to -b */
683 p = strchr(s, ','); 685 if (str) {
684 if (p) 686 /* because str is read-only */
685 *p = '\0'; 687 s = os = strdup(str);
686 688 if (!s)
687 for (br = branch_modes; br->name; br++) { 689 return -1;
688 if (!strcasecmp(s, br->name)) 690
689 break; 691 for (;;) {
690 } 692 p = strchr(s, ',');
691 if (!br->name) 693 if (p)
692 goto error; 694 *p = '\0';
695
696 for (br = branch_modes; br->name; br++) {
697 if (!strcasecmp(s, br->name))
698 break;
699 }
700 if (!br->name) {
701 ui__warning("unknown branch filter %s,"
702 " check man page\n", s);
703 goto error;
704 }
693 705
694 *mode |= br->mode; 706 *mode |= br->mode;
695 707
696 if (!p) 708 if (!p)
697 break; 709 break;
698 710
699 s = p + 1; 711 s = p + 1;
712 }
700 } 713 }
701 ret = 0; 714 ret = 0;
702 715
716 /* default to any branch */
703 if ((*mode & ~ONLY_PLM) == 0) { 717 if ((*mode & ~ONLY_PLM) == 0) {
704 error("need at least one branch type with -b\n"); 718 *mode = PERF_SAMPLE_BRANCH_ANY;
705 ret = -1;
706 } 719 }
707error: 720error:
708 free(os); 721 free(os);
@@ -798,8 +811,13 @@ const struct option record_options[] = {
798 "monitor event in cgroup name only", 811 "monitor event in cgroup name only",
799 parse_cgroups), 812 parse_cgroups),
800 OPT_STRING('u', "uid", &record.uid_str, "user", "user to profile"), 813 OPT_STRING('u', "uid", &record.uid_str, "user", "user to profile"),
801 OPT_CALLBACK('b', "branch-stack", &record.opts.branch_stack, 814
802 "branch mode mask", "branch stack sampling modes", 815 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
816 "branch any", "sample any taken branches",
817 parse_branch_stack),
818
819 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
820 "branch filter mask", "branch stack filter modes",
803 parse_branch_stack), 821 parse_branch_stack),
804 OPT_END() 822 OPT_END()
805}; 823};