diff options
Diffstat (limited to 'tools/perf/builtin-record.c')
| -rw-r--r-- | tools/perf/builtin-record.c | 74 |
1 files changed, 64 insertions, 10 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 199fc31e3919..319712a4e02b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include "util/build-id.h" | 12 | #include "util/build-id.h" |
| 13 | #include "util/util.h" | 13 | #include "util/util.h" |
| 14 | #include "util/parse-options.h" | 14 | #include <subcmd/parse-options.h> |
| 15 | #include "util/parse-events.h" | 15 | #include "util/parse-events.h" |
| 16 | 16 | ||
| 17 | #include "util/callchain.h" | 17 | #include "util/callchain.h" |
| @@ -50,6 +50,7 @@ struct record { | |||
| 50 | int realtime_prio; | 50 | int realtime_prio; |
| 51 | bool no_buildid; | 51 | bool no_buildid; |
| 52 | bool no_buildid_cache; | 52 | bool no_buildid_cache; |
| 53 | bool buildid_all; | ||
| 53 | unsigned long long samples; | 54 | unsigned long long samples; |
| 54 | }; | 55 | }; |
| 55 | 56 | ||
| @@ -362,6 +363,13 @@ static int process_buildids(struct record *rec) | |||
| 362 | */ | 363 | */ |
| 363 | symbol_conf.ignore_vmlinux_buildid = true; | 364 | symbol_conf.ignore_vmlinux_buildid = true; |
| 364 | 365 | ||
| 366 | /* | ||
| 367 | * If --buildid-all is given, it marks all DSO regardless of hits, | ||
| 368 | * so no need to process samples. | ||
| 369 | */ | ||
| 370 | if (rec->buildid_all) | ||
| 371 | rec->tool.sample = NULL; | ||
| 372 | |||
| 365 | return perf_session__process_events(session); | 373 | return perf_session__process_events(session); |
| 366 | } | 374 | } |
| 367 | 375 | ||
| @@ -452,6 +460,8 @@ static void record__init_features(struct record *rec) | |||
| 452 | 460 | ||
| 453 | if (!rec->opts.full_auxtrace) | 461 | if (!rec->opts.full_auxtrace) |
| 454 | perf_header__clear_feat(&session->header, HEADER_AUXTRACE); | 462 | perf_header__clear_feat(&session->header, HEADER_AUXTRACE); |
| 463 | |||
| 464 | perf_header__clear_feat(&session->header, HEADER_STAT); | ||
| 455 | } | 465 | } |
| 456 | 466 | ||
| 457 | static volatile int workload_exec_errno; | 467 | static volatile int workload_exec_errno; |
| @@ -754,12 +764,8 @@ out_child: | |||
| 754 | 764 | ||
| 755 | if (!rec->no_buildid) { | 765 | if (!rec->no_buildid) { |
| 756 | process_buildids(rec); | 766 | process_buildids(rec); |
| 757 | /* | 767 | |
| 758 | * We take all buildids when the file contains | 768 | if (rec->buildid_all) |
| 759 | * AUX area tracing data because we do not decode the | ||
| 760 | * trace because it would take too long. | ||
| 761 | */ | ||
| 762 | if (rec->opts.full_auxtrace) | ||
| 763 | dsos__hit_all(rec->session); | 769 | dsos__hit_all(rec->session); |
| 764 | } | 770 | } |
| 765 | perf_session__write_header(rec->session, rec->evlist, fd, true); | 771 | perf_session__write_header(rec->session, rec->evlist, fd, true); |
| @@ -813,8 +819,12 @@ int record_parse_callchain_opt(const struct option *opt, | |||
| 813 | } | 819 | } |
| 814 | 820 | ||
| 815 | ret = parse_callchain_record_opt(arg, &callchain_param); | 821 | ret = parse_callchain_record_opt(arg, &callchain_param); |
| 816 | if (!ret) | 822 | if (!ret) { |
| 823 | /* Enable data address sampling for DWARF unwind. */ | ||
| 824 | if (callchain_param.record_mode == CALLCHAIN_DWARF) | ||
| 825 | record->sample_address = true; | ||
| 817 | callchain_debug(); | 826 | callchain_debug(); |
| 827 | } | ||
| 818 | 828 | ||
| 819 | return ret; | 829 | return ret; |
| 820 | } | 830 | } |
| @@ -837,6 +847,19 @@ int record_callchain_opt(const struct option *opt, | |||
| 837 | 847 | ||
| 838 | static int perf_record_config(const char *var, const char *value, void *cb) | 848 | static int perf_record_config(const char *var, const char *value, void *cb) |
| 839 | { | 849 | { |
| 850 | struct record *rec = cb; | ||
| 851 | |||
| 852 | if (!strcmp(var, "record.build-id")) { | ||
| 853 | if (!strcmp(value, "cache")) | ||
| 854 | rec->no_buildid_cache = false; | ||
| 855 | else if (!strcmp(value, "no-cache")) | ||
| 856 | rec->no_buildid_cache = true; | ||
| 857 | else if (!strcmp(value, "skip")) | ||
| 858 | rec->no_buildid = true; | ||
| 859 | else | ||
| 860 | return -1; | ||
| 861 | return 0; | ||
| 862 | } | ||
| 840 | if (!strcmp(var, "record.call-graph")) | 863 | if (!strcmp(var, "record.call-graph")) |
| 841 | var = "call-graph.record-mode"; /* fall-through */ | 864 | var = "call-graph.record-mode"; /* fall-through */ |
| 842 | 865 | ||
| @@ -1113,12 +1136,14 @@ struct option __record_options[] = { | |||
| 1113 | "per thread proc mmap processing timeout in ms"), | 1136 | "per thread proc mmap processing timeout in ms"), |
| 1114 | OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events, | 1137 | OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events, |
| 1115 | "Record context switch events"), | 1138 | "Record context switch events"), |
| 1116 | #ifdef HAVE_LIBBPF_SUPPORT | ||
| 1117 | OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", | 1139 | OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", |
| 1118 | "clang binary to use for compiling BPF scriptlets"), | 1140 | "clang binary to use for compiling BPF scriptlets"), |
| 1119 | OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", | 1141 | OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", |
| 1120 | "options passed to clang when compiling BPF scriptlets"), | 1142 | "options passed to clang when compiling BPF scriptlets"), |
| 1121 | #endif | 1143 | OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, |
| 1144 | "file", "vmlinux pathname"), | ||
| 1145 | OPT_BOOLEAN(0, "buildid-all", &record.buildid_all, | ||
| 1146 | "Record build-id of all DSOs regardless of hits"), | ||
| 1122 | OPT_END() | 1147 | OPT_END() |
| 1123 | }; | 1148 | }; |
| 1124 | 1149 | ||
| @@ -1130,6 +1155,27 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 1130 | struct record *rec = &record; | 1155 | struct record *rec = &record; |
| 1131 | char errbuf[BUFSIZ]; | 1156 | char errbuf[BUFSIZ]; |
| 1132 | 1157 | ||
| 1158 | #ifndef HAVE_LIBBPF_SUPPORT | ||
| 1159 | # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c) | ||
| 1160 | set_nobuild('\0', "clang-path", true); | ||
| 1161 | set_nobuild('\0', "clang-opt", true); | ||
| 1162 | # undef set_nobuild | ||
| 1163 | #endif | ||
| 1164 | |||
| 1165 | #ifndef HAVE_BPF_PROLOGUE | ||
| 1166 | # if !defined (HAVE_DWARF_SUPPORT) | ||
| 1167 | # define REASON "NO_DWARF=1" | ||
| 1168 | # elif !defined (HAVE_LIBBPF_SUPPORT) | ||
| 1169 | # define REASON "NO_LIBBPF=1" | ||
| 1170 | # else | ||
| 1171 | # define REASON "this architecture doesn't support BPF prologue" | ||
| 1172 | # endif | ||
| 1173 | # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c) | ||
| 1174 | set_nobuild('\0', "vmlinux", true); | ||
| 1175 | # undef set_nobuild | ||
| 1176 | # undef REASON | ||
| 1177 | #endif | ||
| 1178 | |||
| 1133 | rec->evlist = perf_evlist__new(); | 1179 | rec->evlist = perf_evlist__new(); |
| 1134 | if (rec->evlist == NULL) | 1180 | if (rec->evlist == NULL) |
| 1135 | return -ENOMEM; | 1181 | return -ENOMEM; |
| @@ -1215,6 +1261,14 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 1215 | if (err) | 1261 | if (err) |
| 1216 | goto out_symbol_exit; | 1262 | goto out_symbol_exit; |
| 1217 | 1263 | ||
| 1264 | /* | ||
| 1265 | * We take all buildids when the file contains | ||
| 1266 | * AUX area tracing data because we do not decode the | ||
| 1267 | * trace because it would take too long. | ||
| 1268 | */ | ||
| 1269 | if (rec->opts.full_auxtrace) | ||
| 1270 | rec->buildid_all = true; | ||
| 1271 | |||
| 1218 | if (record_opts__config(&rec->opts)) { | 1272 | if (record_opts__config(&rec->opts)) { |
| 1219 | err = -EINVAL; | 1273 | err = -EINVAL; |
| 1220 | goto out_symbol_exit; | 1274 | goto out_symbol_exit; |
