mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-22 23:04:43 +00:00
perf tools: Implement branch_type event parameter
It can be useful to specify branch type state per event, for example if we want to collect both software trace points and last branch PMU events in a single collection. Currently this doesn't work because the software trace point errors out with -b. There was already a branch-type parameter to configure branch sample types per event in the parser, but it was stubbed out. This patch implements the necessary plumbing to actually enable it. Now: $ perf record -e sched:sched_switch,cpu/cpu-cycles,branch_type=any/ ... works. Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: http://lkml.kernel.org/r/1476306127-19721-1-git-send-email-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
84ee74affc
commit
ac12f6764c
5 changed files with 77 additions and 49 deletions
|
@ -31,18 +31,65 @@ static const struct branch_mode branch_modes[] = {
|
|||
BRANCH_END
|
||||
};
|
||||
|
||||
int
|
||||
parse_branch_stack(const struct option *opt, const char *str, int unset)
|
||||
int parse_branch_str(const char *str, __u64 *mode)
|
||||
{
|
||||
#define ONLY_PLM \
|
||||
(PERF_SAMPLE_BRANCH_USER |\
|
||||
PERF_SAMPLE_BRANCH_KERNEL |\
|
||||
PERF_SAMPLE_BRANCH_HV)
|
||||
|
||||
uint64_t *mode = (uint64_t *)opt->value;
|
||||
int ret = 0;
|
||||
char *p, *s;
|
||||
char *os = NULL;
|
||||
const struct branch_mode *br;
|
||||
char *s, *os = NULL, *p;
|
||||
int ret = -1;
|
||||
|
||||
if (str == NULL) {
|
||||
*mode = PERF_SAMPLE_BRANCH_ANY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
ret = -1;
|
||||
ui__warning("unknown branch filter %s,"
|
||||
" check man page\n", s);
|
||||
goto error;
|
||||
}
|
||||
|
||||
*mode |= br->mode;
|
||||
|
||||
if (!p)
|
||||
break;
|
||||
|
||||
s = p + 1;
|
||||
}
|
||||
|
||||
/* default to any branch */
|
||||
if ((*mode & ~ONLY_PLM) == 0) {
|
||||
*mode = PERF_SAMPLE_BRANCH_ANY;
|
||||
}
|
||||
error:
|
||||
free(os);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
parse_branch_stack(const struct option *opt, const char *str, int unset)
|
||||
{
|
||||
__u64 *mode = (__u64 *)opt->value;
|
||||
|
||||
if (unset)
|
||||
return 0;
|
||||
|
@ -53,43 +100,5 @@ parse_branch_stack(const struct option *opt, const char *str, int unset)
|
|||
if (*mode)
|
||||
return -1;
|
||||
|
||||
/* 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;
|
||||
|
||||
if (!p)
|
||||
break;
|
||||
|
||||
s = p + 1;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
/* default to any branch */
|
||||
if ((*mode & ~ONLY_PLM) == 0) {
|
||||
*mode = PERF_SAMPLE_BRANCH_ANY;
|
||||
}
|
||||
error:
|
||||
free(os);
|
||||
return ret;
|
||||
return parse_branch_str(str, mode);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue