diff options
author | Stephane Eranian <eranian@google.com> | 2012-03-08 17:47:45 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2012-03-09 02:26:07 -0500 |
commit | a5aabdacde9caff54886ae454e0fad2f26929753 (patch) | |
tree | 6784617e8e37edf1ac25763bfc7481eef83d74ae /tools/perf | |
parent | 114382a0aea97974803c942f106d462cbca5c64d (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.txt | 23 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 68 |
2 files changed, 57 insertions, 34 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 60bddaf0e5bd..a1386b2fff00 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 | |||
153 | line. | 153 | line. |
154 | 154 | ||
155 | -b:: | 155 | -b:: |
156 | --branch-stack:: | 156 | --branch-any:: |
157 | Enable taken branch stack sampling. Any type of taken branch may be sampled. | ||
158 | This is a shortcut for --branch-filter any. See --branch-filter for more infos. | ||
159 | |||
160 | -j:: | ||
161 | --branch-filter:: | ||
157 | Enable taken branch stack sampling. Each sample captures a series of consecutive | 162 | Enable taken branch stack sampling. Each sample captures a series of consecutive |
158 | taken branches. The number of branches captured with each sample depends on the | 163 | taken branches. The number of branches captured with each sample depends on the |
159 | underlying hardware, the type of branches of interest, and the executed code. | 164 | underlying hardware, the type of branches of interest, and the executed code. |
160 | It is possible to select the types of branches captured by enabling filters. The | 165 | It is possible to select the types of branches captured by enabling filters. The |
161 | following filters are defined: | 166 | following 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 | + |
172 | At least one of any, any_call, any_ret, any_ind must be provided. The privilege levels may | 177 | The option requires at least one branch type among any, any_call, any_ret, ind_call. |
173 | be ommitted, in which case, the privilege levels of the associated event are applied to the | 178 | The privilege levels may be ommitted, in which case, the privilege levels of the associated |
174 | branch filter. Both kernel (k) and hypervisor (hv) privilege levels are subject to | 179 | event are applied to the branch filter. Both kernel (k) and hypervisor (hv) privilege |
175 | permissions. When sampling on multiple events, branch stack sampling is enabled for all | 180 | levels are subject to permissions. When sampling on multiple events, branch stack sampling |
176 | the sampling events. The sampled branch type is the same for all events. | 181 | is enabled for all the sampling events. The sampled branch type is the same for all events. |
177 | Note that taken branch sampling may not be available on all processors. | 182 | The various filters must be specified as a comma separated list: --branch-filter any_ret,u,k |
178 | The various filters must be specified as a comma separated list: -b any_ret,u,k | 183 | Note that this feature may not be available on all processors. |
179 | 184 | ||
180 | SEE ALSO | 185 | SEE ALSO |
181 | -------- | 186 | -------- |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 1c49d4e8767c..a7c53a9ef372 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 | ||
662 | static int | 662 | static int |
663 | parse_branch_stack(const struct option *opt, const char *str, int unset __used) | 663 | parse_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 | } |
707 | error: | 720 | error: |
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 | }; |