From a5aabdacde9caff54886ae454e0fad2f26929753 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 8 Mar 2012 23:47:45 +0100 Subject: 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 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 --- tools/perf/builtin-record.c | 68 ++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 25 deletions(-) (limited to 'tools/perf/builtin-record.c') 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 const struct branch_mode branch_modes[] = { }; 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 @@ parse_branch_stack(const struct option *opt, const char *str, int unset __used) 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'; - - for (br = branch_modes; br->name; br++) { - if (!strcasecmp(s, br->name)) - break; - } - if (!br->name) - goto error; + /* 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 (;;) { + 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; + *mode |= br->mode; - if (!p) - break; + if (!p) + break; - s = p + 1; + 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 @@ const struct option record_options[] = { "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() }; -- cgit v1.1