perf tools: Derive trigger class from auxtrace_snapshot
[linux-2.6-block.git] / tools / perf / builtin-record.c
CommitLineData
abaff32a 1/*
bf9e1876
IM
2 * builtin-record.c
3 *
4 * Builtin record command: Record the profile of a workload
5 * (or a CPU, or a PID) into the perf.data output file - for
6 * later analysis via perf report.
abaff32a 7 */
16f762a2 8#include "builtin.h"
bf9e1876
IM
9
10#include "perf.h"
11
6122e4e4 12#include "util/build-id.h"
6eda5838 13#include "util/util.h"
4b6ab94e 14#include <subcmd/parse-options.h>
8ad8db37 15#include "util/parse-events.h"
6eda5838 16
8f651eae 17#include "util/callchain.h"
f14d5707 18#include "util/cgroup.h"
7c6a1c65 19#include "util/header.h"
66e274f3 20#include "util/event.h"
361c99a6 21#include "util/evlist.h"
69aad6f1 22#include "util/evsel.h"
8f28827a 23#include "util/debug.h"
94c744b6 24#include "util/session.h"
45694aa7 25#include "util/tool.h"
8d06367f 26#include "util/symbol.h"
a12b51c4 27#include "util/cpumap.h"
fd78260b 28#include "util/thread_map.h"
f5fc1412 29#include "util/data.h"
bcc84ec6 30#include "util/perf_regs.h"
ef149c25 31#include "util/auxtrace.h"
46bc29b9 32#include "util/tsc.h"
f00898f4 33#include "util/parse-branch-options.h"
bcc84ec6 34#include "util/parse-regs-options.h"
71dc2326 35#include "util/llvm-utils.h"
8690a2a7 36#include "util/bpf-loader.h"
5f9cf599 37#include "util/trigger.h"
d8871ea7 38#include "asm/bug.h"
7c6a1c65 39
97124d5e 40#include <unistd.h>
de9ac07b 41#include <sched.h>
a41794cd 42#include <sys/mman.h>
de9ac07b 43
78da39fa 44
8c6f45a7 45struct record {
45694aa7 46 struct perf_tool tool;
b4006796 47 struct record_opts opts;
d20deb64 48 u64 bytes_written;
f5fc1412 49 struct perf_data_file file;
ef149c25 50 struct auxtrace_record *itr;
d20deb64
ACM
51 struct perf_evlist *evlist;
52 struct perf_session *session;
53 const char *progname;
d20deb64 54 int realtime_prio;
d20deb64 55 bool no_buildid;
d2db9a98 56 bool no_buildid_set;
d20deb64 57 bool no_buildid_cache;
d2db9a98 58 bool no_buildid_cache_set;
6156681b 59 bool buildid_all;
ecfd7a9c 60 bool timestamp_filename;
9f065194 61 unsigned long long samples;
0f82ebc4 62};
a21ca2ca 63
8c6f45a7 64static int record__write(struct record *rec, void *bf, size_t size)
f5970550 65{
cf8b2e69 66 if (perf_data_file__write(rec->session->file, bf, size) < 0) {
50a9b868
JO
67 pr_err("failed to write perf data, error: %m\n");
68 return -1;
f5970550 69 }
8d3eca20 70
cf8b2e69 71 rec->bytes_written += size;
8d3eca20 72 return 0;
f5970550
PZ
73}
74
45694aa7 75static int process_synthesized_event(struct perf_tool *tool,
d20deb64 76 union perf_event *event,
1d037ca1
IT
77 struct perf_sample *sample __maybe_unused,
78 struct machine *machine __maybe_unused)
234fbbf5 79{
8c6f45a7
ACM
80 struct record *rec = container_of(tool, struct record, tool);
81 return record__write(rec, event, event->header.size);
234fbbf5
ACM
82}
83
e5685730 84static int record__mmap_read(struct record *rec, int idx)
de9ac07b 85{
e5685730 86 struct perf_mmap *md = &rec->evlist->mmap[idx];
7b8283b5
DA
87 u64 head = perf_mmap__read_head(md);
88 u64 old = md->prev;
918512b4 89 unsigned char *data = md->base + page_size;
de9ac07b
PZ
90 unsigned long size;
91 void *buf;
8d3eca20 92 int rc = 0;
de9ac07b 93
dc82009a 94 if (old == head)
8d3eca20 95 return 0;
dc82009a 96
d20deb64 97 rec->samples++;
de9ac07b
PZ
98
99 size = head - old;
100
101 if ((old & md->mask) + size != (head & md->mask)) {
102 buf = &data[old & md->mask];
103 size = md->mask + 1 - (old & md->mask);
104 old += size;
021e9f47 105
8c6f45a7 106 if (record__write(rec, buf, size) < 0) {
8d3eca20
DA
107 rc = -1;
108 goto out;
109 }
de9ac07b
PZ
110 }
111
112 buf = &data[old & md->mask];
113 size = head - old;
114 old += size;
021e9f47 115
8c6f45a7 116 if (record__write(rec, buf, size) < 0) {
8d3eca20
DA
117 rc = -1;
118 goto out;
119 }
de9ac07b
PZ
120
121 md->prev = old;
e5685730 122 perf_evlist__mmap_consume(rec->evlist, idx);
8d3eca20
DA
123out:
124 return rc;
de9ac07b
PZ
125}
126
2dd6d8a1
AH
127static volatile int done;
128static volatile int signr = -1;
129static volatile int child_finished;
c0bdc1c4 130
2dd6d8a1 131static volatile int auxtrace_record__snapshot_started;
5f9cf599 132static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
2dd6d8a1
AH
133
134static void sig_handler(int sig)
135{
136 if (sig == SIGCHLD)
137 child_finished = 1;
138 else
139 signr = sig;
140
141 done = 1;
142}
143
144static void record__sig_exit(void)
145{
146 if (signr == -1)
147 return;
148
149 signal(signr, SIG_DFL);
150 raise(signr);
151}
152
e31f0d01
AH
153#ifdef HAVE_AUXTRACE_SUPPORT
154
ef149c25
AH
155static int record__process_auxtrace(struct perf_tool *tool,
156 union perf_event *event, void *data1,
157 size_t len1, void *data2, size_t len2)
158{
159 struct record *rec = container_of(tool, struct record, tool);
99fa2984 160 struct perf_data_file *file = &rec->file;
ef149c25
AH
161 size_t padding;
162 u8 pad[8] = {0};
163
99fa2984
AH
164 if (!perf_data_file__is_pipe(file)) {
165 off_t file_offset;
166 int fd = perf_data_file__fd(file);
167 int err;
168
169 file_offset = lseek(fd, 0, SEEK_CUR);
170 if (file_offset == -1)
171 return -1;
172 err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index,
173 event, file_offset);
174 if (err)
175 return err;
176 }
177
ef149c25
AH
178 /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */
179 padding = (len1 + len2) & 7;
180 if (padding)
181 padding = 8 - padding;
182
183 record__write(rec, event, event->header.size);
184 record__write(rec, data1, len1);
185 if (len2)
186 record__write(rec, data2, len2);
187 record__write(rec, &pad, padding);
188
189 return 0;
190}
191
192static int record__auxtrace_mmap_read(struct record *rec,
193 struct auxtrace_mmap *mm)
194{
195 int ret;
196
197 ret = auxtrace_mmap__read(mm, rec->itr, &rec->tool,
198 record__process_auxtrace);
199 if (ret < 0)
200 return ret;
201
202 if (ret)
203 rec->samples++;
204
205 return 0;
206}
207
2dd6d8a1
AH
208static int record__auxtrace_mmap_read_snapshot(struct record *rec,
209 struct auxtrace_mmap *mm)
210{
211 int ret;
212
213 ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool,
214 record__process_auxtrace,
215 rec->opts.auxtrace_snapshot_size);
216 if (ret < 0)
217 return ret;
218
219 if (ret)
220 rec->samples++;
221
222 return 0;
223}
224
225static int record__auxtrace_read_snapshot_all(struct record *rec)
226{
227 int i;
228 int rc = 0;
229
230 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
231 struct auxtrace_mmap *mm =
232 &rec->evlist->mmap[i].auxtrace_mmap;
233
234 if (!mm->base)
235 continue;
236
237 if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) {
238 rc = -1;
239 goto out;
240 }
241 }
242out:
243 return rc;
244}
245
246static void record__read_auxtrace_snapshot(struct record *rec)
247{
248 pr_debug("Recording AUX area tracing snapshot\n");
249 if (record__auxtrace_read_snapshot_all(rec) < 0) {
5f9cf599 250 trigger_error(&auxtrace_snapshot_trigger);
2dd6d8a1 251 } else {
5f9cf599
WN
252 if (auxtrace_record__snapshot_finish(rec->itr))
253 trigger_error(&auxtrace_snapshot_trigger);
254 else
255 trigger_ready(&auxtrace_snapshot_trigger);
2dd6d8a1
AH
256 }
257}
258
e31f0d01
AH
259#else
260
261static inline
262int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
263 struct auxtrace_mmap *mm __maybe_unused)
264{
265 return 0;
266}
267
2dd6d8a1
AH
268static inline
269void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
de9ac07b 270{
f7b7c26e
PZ
271}
272
2dd6d8a1
AH
273static inline
274int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
f7b7c26e 275{
2dd6d8a1 276 return 0;
de9ac07b
PZ
277}
278
2dd6d8a1
AH
279#endif
280
8c6f45a7 281static int record__open(struct record *rec)
dd7927f4 282{
56e52e85 283 char msg[512];
6a4bb04c 284 struct perf_evsel *pos;
d20deb64
ACM
285 struct perf_evlist *evlist = rec->evlist;
286 struct perf_session *session = rec->session;
b4006796 287 struct record_opts *opts = &rec->opts;
8d3eca20 288 int rc = 0;
dd7927f4 289
e68ae9cf 290 perf_evlist__config(evlist, opts, &callchain_param);
cac21425 291
0050f7aa 292 evlist__for_each(evlist, pos) {
dd7927f4 293try_again:
d988d5ee 294 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
56e52e85 295 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
d6d901c2 296 if (verbose)
c0a54341 297 ui__warning("%s\n", msg);
d6d901c2
ZY
298 goto try_again;
299 }
ca6a4258 300
56e52e85
ACM
301 rc = -errno;
302 perf_evsel__open_strerror(pos, &opts->target,
303 errno, msg, sizeof(msg));
304 ui__error("%s\n", msg);
8d3eca20 305 goto out;
c171b552
LZ
306 }
307 }
a43d3f08 308
23d4aad4
ACM
309 if (perf_evlist__apply_filters(evlist, &pos)) {
310 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
311 pos->filter, perf_evsel__name(pos), errno,
35550da3 312 strerror_r(errno, msg, sizeof(msg)));
8d3eca20
DA
313 rc = -1;
314 goto out;
0a102479
FW
315 }
316
ef149c25 317 if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
2dd6d8a1
AH
318 opts->auxtrace_mmap_pages,
319 opts->auxtrace_snapshot_mode) < 0) {
8d3eca20
DA
320 if (errno == EPERM) {
321 pr_err("Permission error mapping pages.\n"
322 "Consider increasing "
323 "/proc/sys/kernel/perf_event_mlock_kb,\n"
324 "or try again with a smaller value of -m/--mmap_pages.\n"
ef149c25
AH
325 "(current value: %u,%u)\n",
326 opts->mmap_pages, opts->auxtrace_mmap_pages);
8d3eca20 327 rc = -errno;
8d3eca20 328 } else {
35550da3
MH
329 pr_err("failed to mmap with %d (%s)\n", errno,
330 strerror_r(errno, msg, sizeof(msg)));
95c36561
WN
331 if (errno)
332 rc = -errno;
333 else
334 rc = -EINVAL;
8d3eca20
DA
335 }
336 goto out;
18e60939 337 }
0a27d7f9 338
563aecb2 339 session->evlist = evlist;
7b56cce2 340 perf_session__set_id_hdr_size(session);
8d3eca20
DA
341out:
342 return rc;
16c8a109
PZ
343}
344
e3d59112
NK
345static int process_sample_event(struct perf_tool *tool,
346 union perf_event *event,
347 struct perf_sample *sample,
348 struct perf_evsel *evsel,
349 struct machine *machine)
350{
351 struct record *rec = container_of(tool, struct record, tool);
352
353 rec->samples++;
354
355 return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
356}
357
8c6f45a7 358static int process_buildids(struct record *rec)
6122e4e4 359{
f5fc1412
JO
360 struct perf_data_file *file = &rec->file;
361 struct perf_session *session = rec->session;
6122e4e4 362
457ae94a 363 if (file->size == 0)
9f591fd7
ACM
364 return 0;
365
00dc8657
NK
366 /*
367 * During this process, it'll load kernel map and replace the
368 * dso->long_name to a real pathname it found. In this case
369 * we prefer the vmlinux path like
370 * /lib/modules/3.16.4/build/vmlinux
371 *
372 * rather than build-id path (in debug directory).
373 * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551
374 */
375 symbol_conf.ignore_vmlinux_buildid = true;
376
6156681b
NK
377 /*
378 * If --buildid-all is given, it marks all DSO regardless of hits,
379 * so no need to process samples.
380 */
381 if (rec->buildid_all)
382 rec->tool.sample = NULL;
383
b7b61cbe 384 return perf_session__process_events(session);
6122e4e4
ACM
385}
386
8115d60c 387static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
a1645ce1
ZY
388{
389 int err;
45694aa7 390 struct perf_tool *tool = data;
a1645ce1
ZY
391 /*
392 *As for guest kernel when processing subcommand record&report,
393 *we arrange module mmap prior to guest kernel mmap and trigger
394 *a preload dso because default guest module symbols are loaded
395 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
396 *method is used to avoid symbol missing when the first addr is
397 *in module instead of in guest kernel.
398 */
45694aa7 399 err = perf_event__synthesize_modules(tool, process_synthesized_event,
743eb868 400 machine);
a1645ce1
ZY
401 if (err < 0)
402 pr_err("Couldn't record guest kernel [%d]'s reference"
23346f21 403 " relocation symbol.\n", machine->pid);
a1645ce1 404
a1645ce1
ZY
405 /*
406 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
407 * have no _text sometimes.
408 */
45694aa7 409 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
0ae617be 410 machine);
a1645ce1
ZY
411 if (err < 0)
412 pr_err("Couldn't record guest kernel [%d]'s reference"
23346f21 413 " relocation symbol.\n", machine->pid);
a1645ce1
ZY
414}
415
98402807
FW
416static struct perf_event_header finished_round_event = {
417 .size = sizeof(struct perf_event_header),
418 .type = PERF_RECORD_FINISHED_ROUND,
419};
420
8c6f45a7 421static int record__mmap_read_all(struct record *rec)
98402807 422{
dcabb507 423 u64 bytes_written = rec->bytes_written;
0e2e63dd 424 int i;
8d3eca20 425 int rc = 0;
98402807 426
d20deb64 427 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
ef149c25
AH
428 struct auxtrace_mmap *mm = &rec->evlist->mmap[i].auxtrace_mmap;
429
8d3eca20 430 if (rec->evlist->mmap[i].base) {
e5685730 431 if (record__mmap_read(rec, i) != 0) {
8d3eca20
DA
432 rc = -1;
433 goto out;
434 }
435 }
ef149c25 436
2dd6d8a1 437 if (mm->base && !rec->opts.auxtrace_snapshot_mode &&
ef149c25
AH
438 record__auxtrace_mmap_read(rec, mm) != 0) {
439 rc = -1;
440 goto out;
441 }
98402807
FW
442 }
443
dcabb507
JO
444 /*
445 * Mark the round finished in case we wrote
446 * at least one event.
447 */
448 if (bytes_written != rec->bytes_written)
449 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
8d3eca20
DA
450
451out:
452 return rc;
98402807
FW
453}
454
8c6f45a7 455static void record__init_features(struct record *rec)
57706abc 456{
57706abc
DA
457 struct perf_session *session = rec->session;
458 int feat;
459
460 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
461 perf_header__set_feat(&session->header, feat);
462
463 if (rec->no_buildid)
464 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
465
3e2be2da 466 if (!have_tracepoints(&rec->evlist->entries))
57706abc
DA
467 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
468
469 if (!rec->opts.branch_stack)
470 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
ef149c25
AH
471
472 if (!rec->opts.full_auxtrace)
473 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
ffa517ad
JO
474
475 perf_header__clear_feat(&session->header, HEADER_STAT);
57706abc
DA
476}
477
e1ab48ba
WN
478static void
479record__finish_output(struct record *rec)
480{
481 struct perf_data_file *file = &rec->file;
482 int fd = perf_data_file__fd(file);
483
484 if (file->is_pipe)
485 return;
486
487 rec->session->header.data_size += rec->bytes_written;
488 file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR);
489
490 if (!rec->no_buildid) {
491 process_buildids(rec);
492
493 if (rec->buildid_all)
494 dsos__hit_all(rec->session);
495 }
496 perf_session__write_header(rec->session, rec->evlist, fd, true);
497
498 return;
499}
500
ecfd7a9c
WN
501static int
502record__switch_output(struct record *rec, bool at_exit)
503{
504 struct perf_data_file *file = &rec->file;
505 int fd, err;
506
507 /* Same Size: "2015122520103046"*/
508 char timestamp[] = "InvalidTimestamp";
509
510 rec->samples = 0;
511 record__finish_output(rec);
512 err = fetch_current_timestamp(timestamp, sizeof(timestamp));
513 if (err) {
514 pr_err("Failed to get current timestamp\n");
515 return -EINVAL;
516 }
517
518 fd = perf_data_file__switch(file, timestamp,
519 rec->session->header.data_offset,
520 at_exit);
521 if (fd >= 0 && !at_exit) {
522 rec->bytes_written = 0;
523 rec->session->header.data_size = 0;
524 }
525
526 if (!quiet)
527 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
528 file->path, timestamp);
529 return fd;
530}
531
f33cbe72
ACM
532static volatile int workload_exec_errno;
533
534/*
535 * perf_evlist__prepare_workload will send a SIGUSR1
536 * if the fork fails, since we asked by setting its
537 * want_signal to true.
538 */
45604710
NK
539static void workload_exec_failed_signal(int signo __maybe_unused,
540 siginfo_t *info,
f33cbe72
ACM
541 void *ucontext __maybe_unused)
542{
543 workload_exec_errno = info->si_value.sival_int;
544 done = 1;
f33cbe72
ACM
545 child_finished = 1;
546}
547
2dd6d8a1
AH
548static void snapshot_sig_handler(int sig);
549
46bc29b9
AH
550int __weak
551perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
552 struct perf_tool *tool __maybe_unused,
553 perf_event__handler_t process __maybe_unused,
554 struct machine *machine __maybe_unused)
555{
556 return 0;
557}
558
c45c86eb
WN
559static int record__synthesize(struct record *rec)
560{
561 struct perf_session *session = rec->session;
562 struct machine *machine = &session->machines.host;
563 struct perf_data_file *file = &rec->file;
564 struct record_opts *opts = &rec->opts;
565 struct perf_tool *tool = &rec->tool;
566 int fd = perf_data_file__fd(file);
567 int err = 0;
568
569 if (file->is_pipe) {
570 err = perf_event__synthesize_attrs(tool, session,
571 process_synthesized_event);
572 if (err < 0) {
573 pr_err("Couldn't synthesize attrs.\n");
574 goto out;
575 }
576
577 if (have_tracepoints(&rec->evlist->entries)) {
578 /*
579 * FIXME err <= 0 here actually means that
580 * there were no tracepoints so its not really
581 * an error, just that we don't need to
582 * synthesize anything. We really have to
583 * return this more properly and also
584 * propagate errors that now are calling die()
585 */
586 err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
587 process_synthesized_event);
588 if (err <= 0) {
589 pr_err("Couldn't record tracing data.\n");
590 goto out;
591 }
592 rec->bytes_written += err;
593 }
594 }
595
46bc29b9
AH
596 err = perf_event__synth_time_conv(rec->evlist->mmap[0].base, tool,
597 process_synthesized_event, machine);
598 if (err)
599 goto out;
600
c45c86eb
WN
601 if (rec->opts.full_auxtrace) {
602 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
603 session, process_synthesized_event);
604 if (err)
605 goto out;
606 }
607
608 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
609 machine);
610 WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
611 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
612 "Check /proc/kallsyms permission or run as root.\n");
613
614 err = perf_event__synthesize_modules(tool, process_synthesized_event,
615 machine);
616 WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
617 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
618 "Check /proc/modules permission or run as root.\n");
619
620 if (perf_guest) {
621 machines__process_guests(&session->machines,
622 perf_event__synthesize_guest_os, tool);
623 }
624
625 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
626 process_synthesized_event, opts->sample_address,
627 opts->proc_map_timeout);
628out:
629 return err;
630}
631
8c6f45a7 632static int __cmd_record(struct record *rec, int argc, const char **argv)
16c8a109 633{
57706abc 634 int err;
45604710 635 int status = 0;
8b412664 636 unsigned long waking = 0;
46be604b 637 const bool forks = argc > 0;
23346f21 638 struct machine *machine;
45694aa7 639 struct perf_tool *tool = &rec->tool;
b4006796 640 struct record_opts *opts = &rec->opts;
f5fc1412 641 struct perf_data_file *file = &rec->file;
d20deb64 642 struct perf_session *session;
6dcf45ef 643 bool disabled = false, draining = false;
42aa276f 644 int fd;
de9ac07b 645
d20deb64 646 rec->progname = argv[0];
33e49ea7 647
45604710 648 atexit(record__sig_exit);
f5970550
PZ
649 signal(SIGCHLD, sig_handler);
650 signal(SIGINT, sig_handler);
804f7ac7 651 signal(SIGTERM, sig_handler);
c0bdc1c4
WN
652
653 if (rec->opts.auxtrace_snapshot_mode) {
2dd6d8a1 654 signal(SIGUSR2, snapshot_sig_handler);
5f9cf599 655 trigger_on(&auxtrace_snapshot_trigger);
c0bdc1c4 656 } else {
2dd6d8a1 657 signal(SIGUSR2, SIG_IGN);
c0bdc1c4 658 }
f5970550 659
b7b61cbe 660 session = perf_session__new(file, false, tool);
94c744b6 661 if (session == NULL) {
ffa91880 662 pr_err("Perf session creation failed.\n");
a9a70bbc
ACM
663 return -1;
664 }
665
42aa276f 666 fd = perf_data_file__fd(file);
d20deb64
ACM
667 rec->session = session;
668
8c6f45a7 669 record__init_features(rec);
330aa675 670
d4db3f16 671 if (forks) {
3e2be2da 672 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
f5fc1412 673 argv, file->is_pipe,
735f7e0b 674 workload_exec_failed_signal);
35b9d88e
ACM
675 if (err < 0) {
676 pr_err("Couldn't run the workload!\n");
45604710 677 status = err;
35b9d88e 678 goto out_delete_session;
856e9660 679 }
856e9660
PZ
680 }
681
8c6f45a7 682 if (record__open(rec) != 0) {
8d3eca20 683 err = -1;
45604710 684 goto out_child;
8d3eca20 685 }
de9ac07b 686
8690a2a7
WN
687 err = bpf__apply_obj_config();
688 if (err) {
689 char errbuf[BUFSIZ];
690
691 bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
692 pr_err("ERROR: Apply config to BPF failed: %s\n",
693 errbuf);
694 goto out_child;
695 }
696
cca8482c
AH
697 /*
698 * Normally perf_session__new would do this, but it doesn't have the
699 * evlist.
700 */
701 if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
702 pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
703 rec->tool.ordered_events = false;
704 }
705
3e2be2da 706 if (!rec->evlist->nr_groups)
a8bb559b
NK
707 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
708
f5fc1412 709 if (file->is_pipe) {
42aa276f 710 err = perf_header__write_pipe(fd);
529870e3 711 if (err < 0)
45604710 712 goto out_child;
563aecb2 713 } else {
42aa276f 714 err = perf_session__write_header(session, rec->evlist, fd, false);
d5eed904 715 if (err < 0)
45604710 716 goto out_child;
56b03f3c
ACM
717 }
718
d3665498 719 if (!rec->no_buildid
e20960c0 720 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
d3665498 721 pr_err("Couldn't generate buildids. "
e20960c0 722 "Use --no-buildid to profile anyway.\n");
8d3eca20 723 err = -1;
45604710 724 goto out_child;
e20960c0
RR
725 }
726
34ba5122 727 machine = &session->machines.host;
743eb868 728
c45c86eb
WN
729 err = record__synthesize(rec);
730 if (err < 0)
45604710 731 goto out_child;
8d3eca20 732
d20deb64 733 if (rec->realtime_prio) {
de9ac07b
PZ
734 struct sched_param param;
735
d20deb64 736 param.sched_priority = rec->realtime_prio;
de9ac07b 737 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
6beba7ad 738 pr_err("Could not set realtime priority.\n");
8d3eca20 739 err = -1;
45604710 740 goto out_child;
de9ac07b
PZ
741 }
742 }
743
774cb499
JO
744 /*
745 * When perf is starting the traced process, all the events
746 * (apart from group members) have enable_on_exec=1 set,
747 * so don't spoil it by prematurely enabling them.
748 */
6619a53e 749 if (!target__none(&opts->target) && !opts->initial_delay)
3e2be2da 750 perf_evlist__enable(rec->evlist);
764e16a3 751
856e9660
PZ
752 /*
753 * Let the child rip
754 */
e803cf97 755 if (forks) {
e5bed564
NK
756 union perf_event *event;
757
758 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
759 if (event == NULL) {
760 err = -ENOMEM;
761 goto out_child;
762 }
763
e803cf97
NK
764 /*
765 * Some H/W events are generated before COMM event
766 * which is emitted during exec(), so perf script
767 * cannot see a correct process name for those events.
768 * Synthesize COMM event to prevent it.
769 */
e5bed564 770 perf_event__synthesize_comm(tool, event,
e803cf97
NK
771 rec->evlist->workload.pid,
772 process_synthesized_event,
773 machine);
e5bed564 774 free(event);
e803cf97 775
3e2be2da 776 perf_evlist__start_workload(rec->evlist);
e803cf97 777 }
856e9660 778
6619a53e
AK
779 if (opts->initial_delay) {
780 usleep(opts->initial_delay * 1000);
781 perf_evlist__enable(rec->evlist);
782 }
783
5f9cf599 784 trigger_ready(&auxtrace_snapshot_trigger);
649c48a9 785 for (;;) {
9f065194 786 unsigned long long hits = rec->samples;
de9ac07b 787
8c6f45a7 788 if (record__mmap_read_all(rec) < 0) {
5f9cf599 789 trigger_error(&auxtrace_snapshot_trigger);
8d3eca20 790 err = -1;
45604710 791 goto out_child;
8d3eca20 792 }
de9ac07b 793
2dd6d8a1
AH
794 if (auxtrace_record__snapshot_started) {
795 auxtrace_record__snapshot_started = 0;
5f9cf599 796 if (!trigger_is_error(&auxtrace_snapshot_trigger))
2dd6d8a1 797 record__read_auxtrace_snapshot(rec);
5f9cf599 798 if (trigger_is_error(&auxtrace_snapshot_trigger)) {
2dd6d8a1
AH
799 pr_err("AUX area tracing snapshot failed\n");
800 err = -1;
801 goto out_child;
802 }
803 }
804
d20deb64 805 if (hits == rec->samples) {
6dcf45ef 806 if (done || draining)
649c48a9 807 break;
f66a889d 808 err = perf_evlist__poll(rec->evlist, -1);
a515114f
JO
809 /*
810 * Propagate error, only if there's any. Ignore positive
811 * number of returned events and interrupt error.
812 */
813 if (err > 0 || (err < 0 && errno == EINTR))
45604710 814 err = 0;
8b412664 815 waking++;
6dcf45ef
ACM
816
817 if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
818 draining = true;
8b412664
PZ
819 }
820
774cb499
JO
821 /*
822 * When perf is starting the traced process, at the end events
823 * die with the process and we wait for that. Thus no need to
824 * disable events in this case.
825 */
602ad878 826 if (done && !disabled && !target__none(&opts->target)) {
5f9cf599 827 trigger_off(&auxtrace_snapshot_trigger);
3e2be2da 828 perf_evlist__disable(rec->evlist);
2711926a
JO
829 disabled = true;
830 }
de9ac07b 831 }
5f9cf599 832 trigger_off(&auxtrace_snapshot_trigger);
de9ac07b 833
f33cbe72 834 if (forks && workload_exec_errno) {
35550da3 835 char msg[STRERR_BUFSIZE];
f33cbe72
ACM
836 const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
837 pr_err("Workload failed: %s\n", emsg);
838 err = -1;
45604710 839 goto out_child;
f33cbe72
ACM
840 }
841
e3d59112 842 if (!quiet)
45604710 843 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
b44308f5 844
45604710
NK
845out_child:
846 if (forks) {
847 int exit_status;
addc2785 848
45604710
NK
849 if (!child_finished)
850 kill(rec->evlist->workload.pid, SIGTERM);
851
852 wait(&exit_status);
853
854 if (err < 0)
855 status = err;
856 else if (WIFEXITED(exit_status))
857 status = WEXITSTATUS(exit_status);
858 else if (WIFSIGNALED(exit_status))
859 signr = WTERMSIG(exit_status);
860 } else
861 status = err;
862
e3d59112
NK
863 /* this will be recalculated during process_buildids() */
864 rec->samples = 0;
865
ecfd7a9c
WN
866 if (!err) {
867 if (!rec->timestamp_filename) {
868 record__finish_output(rec);
869 } else {
870 fd = record__switch_output(rec, true);
871 if (fd < 0) {
872 status = fd;
873 goto out_delete_session;
874 }
875 }
876 }
39d17dac 877
e3d59112
NK
878 if (!err && !quiet) {
879 char samples[128];
ecfd7a9c
WN
880 const char *postfix = rec->timestamp_filename ?
881 ".<timestamp>" : "";
e3d59112 882
ef149c25 883 if (rec->samples && !rec->opts.full_auxtrace)
e3d59112
NK
884 scnprintf(samples, sizeof(samples),
885 " (%" PRIu64 " samples)", rec->samples);
886 else
887 samples[0] = '\0';
888
ecfd7a9c 889 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
e3d59112 890 perf_data_file__size(file) / 1024.0 / 1024.0,
ecfd7a9c 891 file->path, postfix, samples);
e3d59112
NK
892 }
893
39d17dac
ACM
894out_delete_session:
895 perf_session__delete(session);
45604710 896 return status;
de9ac07b 897}
0e9b20b8 898
0883e820 899static void callchain_debug(struct callchain_param *callchain)
09b0fd45 900{
aad2b21c 901 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
a601fdff 902
0883e820 903 pr_debug("callchain: type %s\n", str[callchain->record_mode]);
26d33022 904
0883e820 905 if (callchain->record_mode == CALLCHAIN_DWARF)
09b0fd45 906 pr_debug("callchain: stack dump size %d\n",
0883e820 907 callchain->dump_size);
09b0fd45
JO
908}
909
0883e820
ACM
910int record_opts__parse_callchain(struct record_opts *record,
911 struct callchain_param *callchain,
912 const char *arg, bool unset)
09b0fd45 913{
09b0fd45 914 int ret;
0883e820 915 callchain->enabled = !unset;
eb853e80 916
09b0fd45
JO
917 /* --no-call-graph */
918 if (unset) {
0883e820 919 callchain->record_mode = CALLCHAIN_NONE;
09b0fd45
JO
920 pr_debug("callchain: disabled\n");
921 return 0;
922 }
923
0883e820 924 ret = parse_callchain_record_opt(arg, callchain);
5c0cf224
JO
925 if (!ret) {
926 /* Enable data address sampling for DWARF unwind. */
0883e820 927 if (callchain->record_mode == CALLCHAIN_DWARF)
5c0cf224 928 record->sample_address = true;
0883e820 929 callchain_debug(callchain);
5c0cf224 930 }
26d33022
JO
931
932 return ret;
933}
934
0883e820
ACM
935int record_parse_callchain_opt(const struct option *opt,
936 const char *arg,
937 int unset)
938{
939 return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
940}
941
c421e80b 942int record_callchain_opt(const struct option *opt,
09b0fd45
JO
943 const char *arg __maybe_unused,
944 int unset __maybe_unused)
945{
2ddd5c04 946 struct callchain_param *callchain = opt->value;
c421e80b 947
2ddd5c04 948 callchain->enabled = true;
09b0fd45 949
2ddd5c04
ACM
950 if (callchain->record_mode == CALLCHAIN_NONE)
951 callchain->record_mode = CALLCHAIN_FP;
eb853e80 952
2ddd5c04 953 callchain_debug(callchain);
09b0fd45
JO
954 return 0;
955}
956
eb853e80
JO
957static int perf_record_config(const char *var, const char *value, void *cb)
958{
7a29c087
NK
959 struct record *rec = cb;
960
961 if (!strcmp(var, "record.build-id")) {
962 if (!strcmp(value, "cache"))
963 rec->no_buildid_cache = false;
964 else if (!strcmp(value, "no-cache"))
965 rec->no_buildid_cache = true;
966 else if (!strcmp(value, "skip"))
967 rec->no_buildid = true;
968 else
969 return -1;
970 return 0;
971 }
eb853e80 972 if (!strcmp(var, "record.call-graph"))
5a2e5e85 973 var = "call-graph.record-mode"; /* fall-through */
eb853e80
JO
974
975 return perf_default_config(var, value, cb);
976}
977
814c8c38
PZ
978struct clockid_map {
979 const char *name;
980 int clockid;
981};
982
983#define CLOCKID_MAP(n, c) \
984 { .name = n, .clockid = (c), }
985
986#define CLOCKID_END { .name = NULL, }
987
988
989/*
990 * Add the missing ones, we need to build on many distros...
991 */
992#ifndef CLOCK_MONOTONIC_RAW
993#define CLOCK_MONOTONIC_RAW 4
994#endif
995#ifndef CLOCK_BOOTTIME
996#define CLOCK_BOOTTIME 7
997#endif
998#ifndef CLOCK_TAI
999#define CLOCK_TAI 11
1000#endif
1001
1002static const struct clockid_map clockids[] = {
1003 /* available for all events, NMI safe */
1004 CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
1005 CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
1006
1007 /* available for some events */
1008 CLOCKID_MAP("realtime", CLOCK_REALTIME),
1009 CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
1010 CLOCKID_MAP("tai", CLOCK_TAI),
1011
1012 /* available for the lazy */
1013 CLOCKID_MAP("mono", CLOCK_MONOTONIC),
1014 CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
1015 CLOCKID_MAP("real", CLOCK_REALTIME),
1016 CLOCKID_MAP("boot", CLOCK_BOOTTIME),
1017
1018 CLOCKID_END,
1019};
1020
1021static int parse_clockid(const struct option *opt, const char *str, int unset)
1022{
1023 struct record_opts *opts = (struct record_opts *)opt->value;
1024 const struct clockid_map *cm;
1025 const char *ostr = str;
1026
1027 if (unset) {
1028 opts->use_clockid = 0;
1029 return 0;
1030 }
1031
1032 /* no arg passed */
1033 if (!str)
1034 return 0;
1035
1036 /* no setting it twice */
1037 if (opts->use_clockid)
1038 return -1;
1039
1040 opts->use_clockid = true;
1041
1042 /* if its a number, we're done */
1043 if (sscanf(str, "%d", &opts->clockid) == 1)
1044 return 0;
1045
1046 /* allow a "CLOCK_" prefix to the name */
1047 if (!strncasecmp(str, "CLOCK_", 6))
1048 str += 6;
1049
1050 for (cm = clockids; cm->name; cm++) {
1051 if (!strcasecmp(str, cm->name)) {
1052 opts->clockid = cm->clockid;
1053 return 0;
1054 }
1055 }
1056
1057 opts->use_clockid = false;
1058 ui__warning("unknown clockid %s, check man page\n", ostr);
1059 return -1;
1060}
1061
e9db1310
AH
1062static int record__parse_mmap_pages(const struct option *opt,
1063 const char *str,
1064 int unset __maybe_unused)
1065{
1066 struct record_opts *opts = opt->value;
1067 char *s, *p;
1068 unsigned int mmap_pages;
1069 int ret;
1070
1071 if (!str)
1072 return -EINVAL;
1073
1074 s = strdup(str);
1075 if (!s)
1076 return -ENOMEM;
1077
1078 p = strchr(s, ',');
1079 if (p)
1080 *p = '\0';
1081
1082 if (*s) {
1083 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
1084 if (ret)
1085 goto out_free;
1086 opts->mmap_pages = mmap_pages;
1087 }
1088
1089 if (!p) {
1090 ret = 0;
1091 goto out_free;
1092 }
1093
1094 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
1095 if (ret)
1096 goto out_free;
1097
1098 opts->auxtrace_mmap_pages = mmap_pages;
1099
1100out_free:
1101 free(s);
1102 return ret;
1103}
1104
e5b2c207 1105static const char * const __record_usage[] = {
9e096753
MG
1106 "perf record [<options>] [<command>]",
1107 "perf record [<options>] -- <command> [<options>]",
0e9b20b8
IM
1108 NULL
1109};
e5b2c207 1110const char * const *record_usage = __record_usage;
0e9b20b8 1111
d20deb64 1112/*
8c6f45a7
ACM
1113 * XXX Ideally would be local to cmd_record() and passed to a record__new
1114 * because we need to have access to it in record__exit, that is called
d20deb64
ACM
1115 * after cmd_record() exits, but since record_options need to be accessible to
1116 * builtin-script, leave it here.
1117 *
1118 * At least we don't ouch it in all the other functions here directly.
1119 *
1120 * Just say no to tons of global variables, sigh.
1121 */
8c6f45a7 1122static struct record record = {
d20deb64 1123 .opts = {
8affc2b8 1124 .sample_time = true,
d20deb64
ACM
1125 .mmap_pages = UINT_MAX,
1126 .user_freq = UINT_MAX,
1127 .user_interval = ULLONG_MAX,
447a6013 1128 .freq = 4000,
d1cb9fce
NK
1129 .target = {
1130 .uses_mmap = true,
3aa5939d 1131 .default_per_cpu = true,
d1cb9fce 1132 },
9d9cad76 1133 .proc_map_timeout = 500,
d20deb64 1134 },
e3d59112
NK
1135 .tool = {
1136 .sample = process_sample_event,
1137 .fork = perf_event__process_fork,
cca8482c 1138 .exit = perf_event__process_exit,
e3d59112
NK
1139 .comm = perf_event__process_comm,
1140 .mmap = perf_event__process_mmap,
1141 .mmap2 = perf_event__process_mmap2,
cca8482c 1142 .ordered_events = true,
e3d59112 1143 },
d20deb64 1144};
7865e817 1145
76a26549
NK
1146const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1147 "\n\t\t\t\tDefault: fp";
61eaa3be 1148
d20deb64
ACM
1149/*
1150 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
1151 * with it and switch to use the library functions in perf_evlist that came
b4006796 1152 * from builtin-record.c, i.e. use record_opts,
d20deb64
ACM
1153 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
1154 * using pipes, etc.
1155 */
e5b2c207 1156struct option __record_options[] = {
d20deb64 1157 OPT_CALLBACK('e', "event", &record.evlist, "event",
86847b62 1158 "event selector. use 'perf list' to list available events",
f120f9d5 1159 parse_events_option),
d20deb64 1160 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
c171b552 1161 "event filter", parse_filter),
4ba1faa1
WN
1162 OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
1163 NULL, "don't record events from perf itself",
1164 exclude_perf),
bea03405 1165 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
d6d901c2 1166 "record events on existing process id"),
bea03405 1167 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
d6d901c2 1168 "record events on existing thread id"),
d20deb64 1169 OPT_INTEGER('r', "realtime", &record.realtime_prio,
0e9b20b8 1170 "collect data with this RT SCHED_FIFO priority"),
509051ea 1171 OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
acac03fa 1172 "collect data without buffering"),
d20deb64 1173 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
daac07b2 1174 "collect raw sample records from all opened counters"),
bea03405 1175 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
0e9b20b8 1176 "system-wide collection from all CPUs"),
bea03405 1177 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
c45c6ea2 1178 "list of cpus to monitor"),
d20deb64 1179 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
f5fc1412 1180 OPT_STRING('o', "output", &record.file.path, "file",
abaff32a 1181 "output file name"),
69e7e5b0
AH
1182 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1183 &record.opts.no_inherit_set,
1184 "child tasks do not inherit counters"),
d20deb64 1185 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
e9db1310
AH
1186 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
1187 "number of mmap data pages and AUX area tracing mmap pages",
1188 record__parse_mmap_pages),
d20deb64 1189 OPT_BOOLEAN(0, "group", &record.opts.group,
43bece79 1190 "put the counters into a counter group"),
2ddd5c04 1191 OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
09b0fd45
JO
1192 NULL, "enables call-graph recording" ,
1193 &record_callchain_opt),
1194 OPT_CALLBACK(0, "call-graph", &record.opts,
76a26549 1195 "record_mode[,record_size]", record_callchain_help,
09b0fd45 1196 &record_parse_callchain_opt),
c0555642 1197 OPT_INCR('v', "verbose", &verbose,
3da297a6 1198 "be more verbose (show counter open errors, etc)"),
b44308f5 1199 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
d20deb64 1200 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
649c48a9 1201 "per thread counts"),
56100321 1202 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
3abebc55
AH
1203 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
1204 &record.opts.sample_time_set,
1205 "Record the sample timestamps"),
56100321 1206 OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
d20deb64 1207 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
649c48a9 1208 "don't sample"),
d2db9a98
WN
1209 OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
1210 &record.no_buildid_cache_set,
1211 "do not update the buildid cache"),
1212 OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
1213 &record.no_buildid_set,
1214 "do not collect buildids in perf.data"),
d20deb64 1215 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
023695d9
SE
1216 "monitor event in cgroup name only",
1217 parse_cgroups),
a6205a35 1218 OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
6619a53e 1219 "ms to wait before starting measurement after program start"),
bea03405
NK
1220 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
1221 "user to profile"),
a5aabdac
SE
1222
1223 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
1224 "branch any", "sample any taken branches",
1225 parse_branch_stack),
1226
1227 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
1228 "branch filter mask", "branch stack filter modes",
bdfebd84 1229 parse_branch_stack),
05484298
AK
1230 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
1231 "sample by weight (on special events only)"),
475eeab9
AK
1232 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
1233 "sample transaction flags (special events only)"),
3aa5939d
AH
1234 OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
1235 "use per-thread mmaps"),
bcc84ec6
SE
1236 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
1237 "sample selected machine registers on interrupt,"
1238 " use -I ? to list register names", parse_regs),
85c273d2
AK
1239 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
1240 "Record running/enabled time of read (:S) events"),
814c8c38
PZ
1241 OPT_CALLBACK('k', "clockid", &record.opts,
1242 "clockid", "clockid to use for events, see clock_gettime()",
1243 parse_clockid),
2dd6d8a1
AH
1244 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
1245 "opts", "AUX area tracing Snapshot Mode", ""),
9d9cad76
KL
1246 OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
1247 "per thread proc mmap processing timeout in ms"),
b757bb09
AH
1248 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1249 "Record context switch events"),
85723885
JO
1250 OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
1251 "Configure all used events to run in kernel space.",
1252 PARSE_OPT_EXCLUSIVE),
1253 OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
1254 "Configure all used events to run in user space.",
1255 PARSE_OPT_EXCLUSIVE),
71dc2326
WN
1256 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1257 "clang binary to use for compiling BPF scriptlets"),
1258 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1259 "options passed to clang when compiling BPF scriptlets"),
7efe0e03
HK
1260 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1261 "file", "vmlinux pathname"),
6156681b
NK
1262 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
1263 "Record build-id of all DSOs regardless of hits"),
ecfd7a9c
WN
1264 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1265 "append timestamp to output filename"),
0e9b20b8
IM
1266 OPT_END()
1267};
1268
e5b2c207
NK
1269struct option *record_options = __record_options;
1270
1d037ca1 1271int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
0e9b20b8 1272{
ef149c25 1273 int err;
8c6f45a7 1274 struct record *rec = &record;
16ad2ffb 1275 char errbuf[BUFSIZ];
0e9b20b8 1276
48e1cab1
WN
1277#ifndef HAVE_LIBBPF_SUPPORT
1278# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
1279 set_nobuild('\0', "clang-path", true);
1280 set_nobuild('\0', "clang-opt", true);
1281# undef set_nobuild
7efe0e03
HK
1282#endif
1283
1284#ifndef HAVE_BPF_PROLOGUE
1285# if !defined (HAVE_DWARF_SUPPORT)
1286# define REASON "NO_DWARF=1"
1287# elif !defined (HAVE_LIBBPF_SUPPORT)
1288# define REASON "NO_LIBBPF=1"
1289# else
1290# define REASON "this architecture doesn't support BPF prologue"
1291# endif
1292# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
1293 set_nobuild('\0', "vmlinux", true);
1294# undef set_nobuild
1295# undef REASON
48e1cab1
WN
1296#endif
1297
3e2be2da
ACM
1298 rec->evlist = perf_evlist__new();
1299 if (rec->evlist == NULL)
361c99a6
ACM
1300 return -ENOMEM;
1301
eb853e80
JO
1302 perf_config(perf_record_config, rec);
1303
bca647aa 1304 argc = parse_options(argc, argv, record_options, record_usage,
655000e7 1305 PARSE_OPT_STOP_AT_NON_OPTION);
602ad878 1306 if (!argc && target__none(&rec->opts.target))
bca647aa 1307 usage_with_options(record_usage, record_options);
0e9b20b8 1308
bea03405 1309 if (nr_cgroups && !rec->opts.target.system_wide) {
c7118369
NK
1310 usage_with_options_msg(record_usage, record_options,
1311 "cgroup monitoring only available in system-wide mode");
1312
023695d9 1313 }
b757bb09
AH
1314 if (rec->opts.record_switch_events &&
1315 !perf_can_record_switch_events()) {
c7118369
NK
1316 ui__error("kernel does not support recording context switch events\n");
1317 parse_options_usage(record_usage, record_options, "switch-events", 0);
1318 return -EINVAL;
b757bb09 1319 }
023695d9 1320
ef149c25
AH
1321 if (!rec->itr) {
1322 rec->itr = auxtrace_record__init(rec->evlist, &err);
1323 if (err)
1324 return err;
1325 }
1326
2dd6d8a1
AH
1327 err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
1328 rec->opts.auxtrace_snapshot_opts);
1329 if (err)
1330 return err;
1331
d7888573
WN
1332 err = bpf__setup_stdout(rec->evlist);
1333 if (err) {
1334 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
1335 pr_err("ERROR: Setup BPF stdout failed: %s\n",
1336 errbuf);
1337 return err;
1338 }
1339
ef149c25
AH
1340 err = -ENOMEM;
1341
0a7e6d1b 1342 symbol__init(NULL);
baa2f6ce 1343
ec80fde7 1344 if (symbol_conf.kptr_restrict)
646aaea6
ACM
1345 pr_warning(
1346"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
1347"check /proc/sys/kernel/kptr_restrict.\n\n"
1348"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
1349"file is not found in the buildid cache or in the vmlinux path.\n\n"
1350"Samples in kernel modules won't be resolved at all.\n\n"
1351"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
1352"even with a suitable vmlinux or kallsyms file.\n\n");
ec80fde7 1353
d20deb64 1354 if (rec->no_buildid_cache || rec->no_buildid)
a1ac1d3c 1355 disable_buildid_cache();
655000e7 1356
3e2be2da
ACM
1357 if (rec->evlist->nr_entries == 0 &&
1358 perf_evlist__add_default(rec->evlist) < 0) {
69aad6f1
ACM
1359 pr_err("Not enough memory for event selector list\n");
1360 goto out_symbol_exit;
bbd36e5e 1361 }
0e9b20b8 1362
69e7e5b0
AH
1363 if (rec->opts.target.tid && !rec->opts.no_inherit_set)
1364 rec->opts.no_inherit = true;
1365
602ad878 1366 err = target__validate(&rec->opts.target);
16ad2ffb 1367 if (err) {
602ad878 1368 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
16ad2ffb
NK
1369 ui__warning("%s", errbuf);
1370 }
1371
602ad878 1372 err = target__parse_uid(&rec->opts.target);
16ad2ffb
NK
1373 if (err) {
1374 int saved_errno = errno;
4bd0f2d2 1375
602ad878 1376 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
3780f488 1377 ui__error("%s", errbuf);
16ad2ffb
NK
1378
1379 err = -saved_errno;
8fa60e1f 1380 goto out_symbol_exit;
16ad2ffb 1381 }
0d37aa34 1382
16ad2ffb 1383 err = -ENOMEM;
3e2be2da 1384 if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
dd7927f4 1385 usage_with_options(record_usage, record_options);
69aad6f1 1386
ef149c25
AH
1387 err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
1388 if (err)
1389 goto out_symbol_exit;
1390
6156681b
NK
1391 /*
1392 * We take all buildids when the file contains
1393 * AUX area tracing data because we do not decode the
1394 * trace because it would take too long.
1395 */
1396 if (rec->opts.full_auxtrace)
1397 rec->buildid_all = true;
1398
b4006796 1399 if (record_opts__config(&rec->opts)) {
39d17dac 1400 err = -EINVAL;
03ad9747 1401 goto out_symbol_exit;
7e4ff9e3
MG
1402 }
1403
d20deb64 1404 err = __cmd_record(&record, argc, argv);
d65a458b 1405out_symbol_exit:
45604710 1406 perf_evlist__delete(rec->evlist);
d65a458b 1407 symbol__exit();
ef149c25 1408 auxtrace_record__free(rec->itr);
39d17dac 1409 return err;
0e9b20b8 1410}
2dd6d8a1
AH
1411
1412static void snapshot_sig_handler(int sig __maybe_unused)
1413{
5f9cf599
WN
1414 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1415 trigger_hit(&auxtrace_snapshot_trigger);
1416 auxtrace_record__snapshot_started = 1;
1417 if (auxtrace_record__snapshot_start(record.itr))
1418 trigger_error(&auxtrace_snapshot_trigger);
1419 }
2dd6d8a1 1420}