aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-record.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r--tools/perf/builtin-record.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 75d230fef20..1c49d4e8767 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -638,6 +638,77 @@ out_delete_session:
638 return err; 638 return err;
639} 639}
640 640
641#define BRANCH_OPT(n, m) \
642 { .name = n, .mode = (m) }
643
644#define BRANCH_END { .name = NULL }
645
646struct branch_mode {
647 const char *name;
648 int mode;
649};
650
651static const struct branch_mode branch_modes[] = {
652 BRANCH_OPT("u", PERF_SAMPLE_BRANCH_USER),
653 BRANCH_OPT("k", PERF_SAMPLE_BRANCH_KERNEL),
654 BRANCH_OPT("hv", PERF_SAMPLE_BRANCH_HV),
655 BRANCH_OPT("any", PERF_SAMPLE_BRANCH_ANY),
656 BRANCH_OPT("any_call", PERF_SAMPLE_BRANCH_ANY_CALL),
657 BRANCH_OPT("any_ret", PERF_SAMPLE_BRANCH_ANY_RETURN),
658 BRANCH_OPT("ind_call", PERF_SAMPLE_BRANCH_IND_CALL),
659 BRANCH_END
660};
661
662static int
663parse_branch_stack(const struct option *opt, const char *str, int unset __used)
664{
665#define ONLY_PLM \
666 (PERF_SAMPLE_BRANCH_USER |\
667 PERF_SAMPLE_BRANCH_KERNEL |\
668 PERF_SAMPLE_BRANCH_HV)
669
670 uint64_t *mode = (uint64_t *)opt->value;
671 const struct branch_mode *br;
672 char *s, *os, *p;
673 int ret = -1;
674
675 *mode = 0;
676
677 /* because str is read-only */
678 s = os = strdup(str);
679 if (!s)
680 return -1;
681
682 for (;;) {
683 p = strchr(s, ',');
684 if (p)
685 *p = '\0';
686
687 for (br = branch_modes; br->name; br++) {
688 if (!strcasecmp(s, br->name))
689 break;
690 }
691 if (!br->name)
692 goto error;
693
694 *mode |= br->mode;
695
696 if (!p)
697 break;
698
699 s = p + 1;
700 }
701 ret = 0;
702
703 if ((*mode & ~ONLY_PLM) == 0) {
704 error("need at least one branch type with -b\n");
705 ret = -1;
706 }
707error:
708 free(os);
709 return ret;
710}
711
641static const char * const record_usage[] = { 712static const char * const record_usage[] = {
642 "perf record [<options>] [<command>]", 713 "perf record [<options>] [<command>]",
643 "perf record [<options>] -- <command> [<options>]", 714 "perf record [<options>] -- <command> [<options>]",
@@ -727,6 +798,9 @@ const struct option record_options[] = {
727 "monitor event in cgroup name only", 798 "monitor event in cgroup name only",
728 parse_cgroups), 799 parse_cgroups),
729 OPT_STRING('u', "uid", &record.uid_str, "user", "user to profile"), 800 OPT_STRING('u', "uid", &record.uid_str, "user", "user to profile"),
801 OPT_CALLBACK('b', "branch-stack", &record.opts.branch_stack,
802 "branch mode mask", "branch stack sampling modes",
803 parse_branch_stack),
730 OPT_END() 804 OPT_END()
731}; 805};
732 806