diff options
author | Jiri Olsa <jolsa@redhat.com> | 2014-02-03 06:44:42 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-02-18 07:34:47 -0500 |
commit | eb853e80324fa87faf7ae7e1a763ad643f908f2d (patch) | |
tree | 0ff0e6febc540a9dee0edc4dcca63dcaf5db6e32 | |
parent | bc5290869d0a7f7abbde76ac95a7f7b6f5d7bb7b (diff) |
perf tools: Add call-graph option support into .perfconfig
Adding call-graph option support into .perfconfig file, so it's now
possible use call-graph option like:
[top]
call-graph = fp
[record]
call-graph = dwarf,8192
Above options ONLY setup the unwind method. To enable perf record/top to
actually use it the command line option -g/-G must be specified.
The --call-graph option overloads .perfconfig setup.
Assuming above configuration:
$ perf record -g ls
- enables dwarf unwind with user stack size dump 8192 bytes
$ perf top -G
- enables frame pointer unwind
$ perf record --call-graph=fp ls
- enables frame pointer unwind
$ perf top --call-graph=dwarf,4096 ls
- enables dwarf unwind with user stack size dump 4096 bytes
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1391427883-13443-2-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/builtin-record.c | 16 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 12 | ||||
-rw-r--r-- | tools/perf/perf.h | 1 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 2 |
4 files changed, 30 insertions, 1 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index af47531b82ec..be9e8bc0c4aa 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -749,6 +749,8 @@ int record_parse_callchain_opt(const struct option *opt, | |||
749 | struct record_opts *opts = opt->value; | 749 | struct record_opts *opts = opt->value; |
750 | int ret; | 750 | int ret; |
751 | 751 | ||
752 | opts->call_graph_enabled = !unset; | ||
753 | |||
752 | /* --no-call-graph */ | 754 | /* --no-call-graph */ |
753 | if (unset) { | 755 | if (unset) { |
754 | opts->call_graph = CALLCHAIN_NONE; | 756 | opts->call_graph = CALLCHAIN_NONE; |
@@ -769,6 +771,8 @@ int record_callchain_opt(const struct option *opt, | |||
769 | { | 771 | { |
770 | struct record_opts *opts = opt->value; | 772 | struct record_opts *opts = opt->value; |
771 | 773 | ||
774 | opts->call_graph_enabled = !unset; | ||
775 | |||
772 | if (opts->call_graph == CALLCHAIN_NONE) | 776 | if (opts->call_graph == CALLCHAIN_NONE) |
773 | opts->call_graph = CALLCHAIN_FP; | 777 | opts->call_graph = CALLCHAIN_FP; |
774 | 778 | ||
@@ -776,6 +780,16 @@ int record_callchain_opt(const struct option *opt, | |||
776 | return 0; | 780 | return 0; |
777 | } | 781 | } |
778 | 782 | ||
783 | static int perf_record_config(const char *var, const char *value, void *cb) | ||
784 | { | ||
785 | struct record *rec = cb; | ||
786 | |||
787 | if (!strcmp(var, "record.call-graph")) | ||
788 | return record_parse_callchain(value, &rec->opts); | ||
789 | |||
790 | return perf_default_config(var, value, cb); | ||
791 | } | ||
792 | |||
779 | static const char * const record_usage[] = { | 793 | static const char * const record_usage[] = { |
780 | "perf record [<options>] [<command>]", | 794 | "perf record [<options>] [<command>]", |
781 | "perf record [<options>] -- <command> [<options>]", | 795 | "perf record [<options>] -- <command> [<options>]", |
@@ -907,6 +921,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | |||
907 | if (rec->evlist == NULL) | 921 | if (rec->evlist == NULL) |
908 | return -ENOMEM; | 922 | return -ENOMEM; |
909 | 923 | ||
924 | perf_config(perf_record_config, rec); | ||
925 | |||
910 | argc = parse_options(argc, argv, record_options, record_usage, | 926 | argc = parse_options(argc, argv, record_options, record_usage, |
911 | PARSE_OPT_STOP_AT_NON_OPTION); | 927 | PARSE_OPT_STOP_AT_NON_OPTION); |
912 | if (!argc && target__none(&rec->opts.target)) | 928 | if (!argc && target__none(&rec->opts.target)) |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 76cd510d34d0..ed99ec4a309f 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -991,6 +991,16 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset) | |||
991 | return record_parse_callchain_opt(opt, arg, unset); | 991 | return record_parse_callchain_opt(opt, arg, unset); |
992 | } | 992 | } |
993 | 993 | ||
994 | static int perf_top_config(const char *var, const char *value, void *cb) | ||
995 | { | ||
996 | struct perf_top *top = cb; | ||
997 | |||
998 | if (!strcmp(var, "top.call-graph")) | ||
999 | return record_parse_callchain(value, &top->record_opts); | ||
1000 | |||
1001 | return perf_default_config(var, value, cb); | ||
1002 | } | ||
1003 | |||
994 | static int | 1004 | static int |
995 | parse_percent_limit(const struct option *opt, const char *arg, | 1005 | parse_percent_limit(const struct option *opt, const char *arg, |
996 | int unset __maybe_unused) | 1006 | int unset __maybe_unused) |
@@ -1115,6 +1125,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1115 | if (top.evlist == NULL) | 1125 | if (top.evlist == NULL) |
1116 | return -ENOMEM; | 1126 | return -ENOMEM; |
1117 | 1127 | ||
1128 | perf_config(perf_top_config, &top); | ||
1129 | |||
1118 | argc = parse_options(argc, argv, options, top_usage, 0); | 1130 | argc = parse_options(argc, argv, options, top_usage, 0); |
1119 | if (argc) | 1131 | if (argc) |
1120 | usage_with_options(top_usage, options); | 1132 | usage_with_options(top_usage, options); |
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index e84fa26bc1be..2078f334617c 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -257,6 +257,7 @@ enum perf_call_graph_mode { | |||
257 | struct record_opts { | 257 | struct record_opts { |
258 | struct target target; | 258 | struct target target; |
259 | int call_graph; | 259 | int call_graph; |
260 | bool call_graph_enabled; | ||
260 | bool group; | 261 | bool group; |
261 | bool inherit_stat; | 262 | bool inherit_stat; |
262 | bool no_buffering; | 263 | bool no_buffering; |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index c6f8ce9972e7..8201abe0925e 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -595,7 +595,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) | |||
595 | attr->mmap_data = track; | 595 | attr->mmap_data = track; |
596 | } | 596 | } |
597 | 597 | ||
598 | if (opts->call_graph) { | 598 | if (opts->call_graph_enabled) { |
599 | perf_evsel__set_sample_bit(evsel, CALLCHAIN); | 599 | perf_evsel__set_sample_bit(evsel, CALLCHAIN); |
600 | 600 | ||
601 | if (opts->call_graph == CALLCHAIN_DWARF) { | 601 | if (opts->call_graph == CALLCHAIN_DWARF) { |