Commit a5aabdac authored by Stephane Eranian's avatar Stephane Eranian Committed by Ingo Molnar

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: default avatarStephane 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.comSigned-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 114382a0
...@@ -153,14 +153,19 @@ corresponding events, i.e., they always refer to events defined earlier on the c ...@@ -153,14 +153,19 @@ corresponding events, i.e., they always refer to events defined earlier on the c
line. line.
-b:: -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 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 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. 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 It is possible to select the types of branches captured by enabling filters. The
following filters are defined: following filters are defined:
- any : any type of branches - any: any type of branches
- any_call: any function call or system call - any_call: any function call or system call
- any_ret: any function return or system call return - any_ret: any function return or system call return
- any_ind: any indirect branch - any_ind: any indirect branch
...@@ -169,13 +174,13 @@ following filters are defined: ...@@ -169,13 +174,13 @@ following filters are defined:
- hv: only when the target is at the hypervisor level - 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 The option requires at least one branch type among any, any_call, any_ret, ind_call.
be ommitted, in which case, the privilege levels of the associated event are applied to the The privilege levels may be ommitted, in which case, the privilege levels of the associated
branch filter. Both kernel (k) and hypervisor (hv) privilege levels are subject to event are applied to the branch filter. Both kernel (k) and hypervisor (hv) privilege
permissions. When sampling on multiple events, branch stack sampling is enabled for all levels are subject to permissions. When sampling on multiple events, branch stack sampling
the sampling events. The sampled branch type is the same for all events. 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: --branch-filter any_ret,u,k
The various filters must be specified as a comma separated list: -b any_ret,u,k Note that this feature may not be available on all processors.
SEE ALSO SEE ALSO
-------- --------
......
...@@ -660,7 +660,7 @@ static const struct branch_mode branch_modes[] = { ...@@ -660,7 +660,7 @@ static const struct branch_mode branch_modes[] = {
}; };
static int static int
parse_branch_stack(const struct option *opt, const char *str, int unset __used) parse_branch_stack(const struct option *opt, const char *str, int unset)
{ {
#define ONLY_PLM \ #define ONLY_PLM \
(PERF_SAMPLE_BRANCH_USER |\ (PERF_SAMPLE_BRANCH_USER |\
...@@ -669,11 +669,20 @@ parse_branch_stack(const struct option *opt, const char *str, int unset __used) ...@@ -669,11 +669,20 @@ parse_branch_stack(const struct option *opt, const char *str, int unset __used)
uint64_t *mode = (uint64_t *)opt->value; uint64_t *mode = (uint64_t *)opt->value;
const struct branch_mode *br; const struct branch_mode *br;
char *s, *os, *p; char *s, *os = NULL, *p;
int ret = -1; int ret = -1;
*mode = 0; if (unset)
return 0;
/*
* cannot set it twice, -b + --branch-filter for instance
*/
if (*mode)
return -1;
/* str may be NULL in case no arg is passed to -b */
if (str) {
/* because str is read-only */ /* because str is read-only */
s = os = strdup(str); s = os = strdup(str);
if (!s) if (!s)
...@@ -688,8 +697,11 @@ parse_branch_stack(const struct option *opt, const char *str, int unset __used) ...@@ -688,8 +697,11 @@ parse_branch_stack(const struct option *opt, const char *str, int unset __used)
if (!strcasecmp(s, br->name)) if (!strcasecmp(s, br->name))
break; break;
} }
if (!br->name) if (!br->name) {
ui__warning("unknown branch filter %s,"
" check man page\n", s);
goto error; goto error;
}
*mode |= br->mode; *mode |= br->mode;
...@@ -698,11 +710,12 @@ parse_branch_stack(const struct option *opt, const char *str, int unset __used) ...@@ -698,11 +710,12 @@ parse_branch_stack(const struct option *opt, const char *str, int unset __used)
s = p + 1; s = p + 1;
} }
}
ret = 0; ret = 0;
/* default to any branch */
if ((*mode & ~ONLY_PLM) == 0) { if ((*mode & ~ONLY_PLM) == 0) {
error("need at least one branch type with -b\n"); *mode = PERF_SAMPLE_BRANCH_ANY;
ret = -1;
} }
error: error:
free(os); free(os);
...@@ -798,8 +811,13 @@ const struct option record_options[] = { ...@@ -798,8 +811,13 @@ const struct option record_options[] = {
"monitor event in cgroup name only", "monitor event in cgroup name only",
parse_cgroups), parse_cgroups),
OPT_STRING('u', "uid", &record.uid_str, "user", "user to profile"), OPT_STRING('u', "uid", &record.uid_str, "user", "user to profile"),
OPT_CALLBACK('b', "branch-stack", &record.opts.branch_stack,
"branch mode mask", "branch stack sampling modes", OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
"branch any", "sample any taken branches",
parse_branch_stack),
OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
"branch filter mask", "branch stack filter modes",
parse_branch_stack), parse_branch_stack),
OPT_END() OPT_END()
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment