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>
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 1c49d4e..a7c53a9 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -660,7 +660,7 @@
};
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 \
(PERF_SAMPLE_BRANCH_USER |\
@@ -669,40 +669,53 @@
uint64_t *mode = (uint64_t *)opt->value;
const struct branch_mode *br;
- char *s, *os, *p;
+ char *s, *os = NULL, *p;
int ret = -1;
- *mode = 0;
+ if (unset)
+ return 0;
- /* because str is read-only */
- s = os = strdup(str);
- if (!s)
+ /*
+ * cannot set it twice, -b + --branch-filter for instance
+ */
+ if (*mode)
return -1;
- for (;;) {
- p = strchr(s, ',');
- if (p)
- *p = '\0';
+ /* str may be NULL in case no arg is passed to -b */
+ if (str) {
+ /* because str is read-only */
+ s = os = strdup(str);
+ if (!s)
+ return -1;
- for (br = branch_modes; br->name; br++) {
- if (!strcasecmp(s, br->name))
+ for (;;) {
+ p = strchr(s, ',');
+ if (p)
+ *p = '\0';
+
+ for (br = branch_modes; br->name; br++) {
+ if (!strcasecmp(s, br->name))
+ break;
+ }
+ if (!br->name) {
+ ui__warning("unknown branch filter %s,"
+ " check man page\n", s);
+ goto error;
+ }
+
+ *mode |= br->mode;
+
+ if (!p)
break;
+
+ s = p + 1;
}
- if (!br->name)
- goto error;
-
- *mode |= br->mode;
-
- if (!p)
- break;
-
- s = p + 1;
}
ret = 0;
+ /* default to any branch */
if ((*mode & ~ONLY_PLM) == 0) {
- error("need at least one branch type with -b\n");
- ret = -1;
+ *mode = PERF_SAMPLE_BRANCH_ANY;
}
error:
free(os);
@@ -798,8 +811,13 @@
"monitor event in cgroup name only",
parse_cgroups),
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),
OPT_END()
};