aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-record.c88
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/util/callchain.c84
-rw-r--r--tools/perf/util/callchain.h2
4 files changed, 88 insertions, 88 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index fde0df72beaa..0ee647bcd2ec 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -624,90 +624,6 @@ error:
624 return ret; 624 return ret;
625} 625}
626 626
627#ifdef HAVE_DWARF_UNWIND_SUPPORT
628static int get_stack_size(char *str, unsigned long *_size)
629{
630 char *endptr;
631 unsigned long size;
632 unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
633
634 size = strtoul(str, &endptr, 0);
635
636 do {
637 if (*endptr)
638 break;
639
640 size = round_up(size, sizeof(u64));
641 if (!size || size > max_size)
642 break;
643
644 *_size = size;
645 return 0;
646
647 } while (0);
648
649 pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
650 max_size, str);
651 return -1;
652}
653#endif /* HAVE_DWARF_UNWIND_SUPPORT */
654
655int record_parse_callchain(const char *arg)
656{
657 char *tok, *name, *saveptr = NULL;
658 char *buf;
659 int ret = -1;
660
661 /* We need buffer that we know we can write to. */
662 buf = malloc(strlen(arg) + 1);
663 if (!buf)
664 return -ENOMEM;
665
666 strcpy(buf, arg);
667
668 tok = strtok_r((char *)buf, ",", &saveptr);
669 name = tok ? : (char *)buf;
670
671 do {
672 /* Framepointer style */
673 if (!strncmp(name, "fp", sizeof("fp"))) {
674 if (!strtok_r(NULL, ",", &saveptr)) {
675 callchain_param.record_mode = CALLCHAIN_FP;
676 ret = 0;
677 } else
678 pr_err("callchain: No more arguments "
679 "needed for -g fp\n");
680 break;
681
682#ifdef HAVE_DWARF_UNWIND_SUPPORT
683 /* Dwarf style */
684 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
685 const unsigned long default_stack_dump_size = 8192;
686
687 ret = 0;
688 callchain_param.record_mode = CALLCHAIN_DWARF;
689 callchain_param.dump_size = default_stack_dump_size;
690
691 tok = strtok_r(NULL, ",", &saveptr);
692 if (tok) {
693 unsigned long size = 0;
694
695 ret = get_stack_size(tok, &size);
696 callchain_param.dump_size = size;
697 }
698#endif /* HAVE_DWARF_UNWIND_SUPPORT */
699 } else {
700 pr_err("callchain: Unknown --call-graph option "
701 "value: %s\n", arg);
702 break;
703 }
704
705 } while (0);
706
707 free(buf);
708 return ret;
709}
710
711static void callchain_debug(void) 627static void callchain_debug(void)
712{ 628{
713 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF" }; 629 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF" };
@@ -734,7 +650,7 @@ int record_parse_callchain_opt(const struct option *opt __maybe_unused,
734 return 0; 650 return 0;
735 } 651 }
736 652
737 ret = record_parse_callchain(arg); 653 ret = parse_callchain_record_opt(arg);
738 if (!ret) 654 if (!ret)
739 callchain_debug(); 655 callchain_debug();
740 656
@@ -757,7 +673,7 @@ int record_callchain_opt(const struct option *opt __maybe_unused,
757static int perf_record_config(const char *var, const char *value, void *cb) 673static int perf_record_config(const char *var, const char *value, void *cb)
758{ 674{
759 if (!strcmp(var, "record.call-graph")) 675 if (!strcmp(var, "record.call-graph"))
760 return record_parse_callchain(value); 676 return parse_callchain_record_opt(value);
761 677
762 return perf_default_config(var, value, cb); 678 return perf_default_config(var, value, cb);
763} 679}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index f7003fc0c5f0..9d647a079d02 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1021,7 +1021,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
1021static int perf_top_config(const char *var, const char *value, void *cb) 1021static int perf_top_config(const char *var, const char *value, void *cb)
1022{ 1022{
1023 if (!strcmp(var, "top.call-graph")) 1023 if (!strcmp(var, "top.call-graph"))
1024 return record_parse_callchain(value); 1024 return parse_callchain_record_opt(value);
1025 if (!strcmp(var, "top.children")) { 1025 if (!strcmp(var, "top.children")) {
1026 symbol_conf.cumulate_callchain = perf_config_bool(var, value); 1026 symbol_conf.cumulate_callchain = perf_config_bool(var, value);
1027 return 0; 1027 return 0;
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 08f0fbf5527c..ba7297230143 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -25,6 +25,90 @@
25 25
26__thread struct callchain_cursor callchain_cursor; 26__thread struct callchain_cursor callchain_cursor;
27 27
28#ifdef HAVE_DWARF_UNWIND_SUPPORT
29static int get_stack_size(const char *str, unsigned long *_size)
30{
31 char *endptr;
32 unsigned long size;
33 unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
34
35 size = strtoul(str, &endptr, 0);
36
37 do {
38 if (*endptr)
39 break;
40
41 size = round_up(size, sizeof(u64));
42 if (!size || size > max_size)
43 break;
44
45 *_size = size;
46 return 0;
47
48 } while (0);
49
50 pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
51 max_size, str);
52 return -1;
53}
54#endif /* HAVE_DWARF_UNWIND_SUPPORT */
55
56int parse_callchain_record_opt(const char *arg)
57{
58 char *tok, *name, *saveptr = NULL;
59 char *buf;
60 int ret = -1;
61
62 /* We need buffer that we know we can write to. */
63 buf = malloc(strlen(arg) + 1);
64 if (!buf)
65 return -ENOMEM;
66
67 strcpy(buf, arg);
68
69 tok = strtok_r((char *)buf, ",", &saveptr);
70 name = tok ? : (char *)buf;
71
72 do {
73 /* Framepointer style */
74 if (!strncmp(name, "fp", sizeof("fp"))) {
75 if (!strtok_r(NULL, ",", &saveptr)) {
76 callchain_param.record_mode = CALLCHAIN_FP;
77 ret = 0;
78 } else
79 pr_err("callchain: No more arguments "
80 "needed for -g fp\n");
81 break;
82
83#ifdef HAVE_DWARF_UNWIND_SUPPORT
84 /* Dwarf style */
85 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
86 const unsigned long default_stack_dump_size = 8192;
87
88 ret = 0;
89 callchain_param.record_mode = CALLCHAIN_DWARF;
90 callchain_param.dump_size = default_stack_dump_size;
91
92 tok = strtok_r(NULL, ",", &saveptr);
93 if (tok) {
94 unsigned long size = 0;
95
96 ret = get_stack_size(tok, &size);
97 callchain_param.dump_size = size;
98 }
99#endif /* HAVE_DWARF_UNWIND_SUPPORT */
100 } else {
101 pr_err("callchain: Unknown --call-graph option "
102 "value: %s\n", arg);
103 break;
104 }
105
106 } while (0);
107
108 free(buf);
109 return ret;
110}
111
28int 112int
29parse_callchain_report_opt(const char *arg) 113parse_callchain_report_opt(const char *arg)
30{ 114{
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 819ae4f61e08..8adfbf0bab5c 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -157,7 +157,6 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
157struct option; 157struct option;
158struct hist_entry; 158struct hist_entry;
159 159
160int record_parse_callchain(const char *arg);
161int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); 160int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
162int record_callchain_opt(const struct option *opt, const char *arg, int unset); 161int record_callchain_opt(const struct option *opt, const char *arg, int unset);
163 162
@@ -169,6 +168,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
169 bool hide_unresolved); 168 bool hide_unresolved);
170 169
171extern const char record_callchain_help[]; 170extern const char record_callchain_help[];
171int parse_callchain_record_opt(const char *arg);
172int parse_callchain_report_opt(const char *arg); 172int parse_callchain_report_opt(const char *arg);
173 173
174static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, 174static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,