perf tools: Rename 'perf_record_opts' to 'record_opts
[firefly-linux-kernel-4.4.55.git] / tools / perf / builtin-record.c
1 /*
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.
7  */
8 #include "builtin.h"
9
10 #include "perf.h"
11
12 #include "util/build-id.h"
13 #include "util/util.h"
14 #include "util/parse-options.h"
15 #include "util/parse-events.h"
16
17 #include "util/header.h"
18 #include "util/event.h"
19 #include "util/evlist.h"
20 #include "util/evsel.h"
21 #include "util/debug.h"
22 #include "util/session.h"
23 #include "util/tool.h"
24 #include "util/symbol.h"
25 #include "util/cpumap.h"
26 #include "util/thread_map.h"
27 #include "util/data.h"
28
29 #include <unistd.h>
30 #include <sched.h>
31 #include <sys/mman.h>
32
33 #ifndef HAVE_ON_EXIT_SUPPORT
34 #ifndef ATEXIT_MAX
35 #define ATEXIT_MAX 32
36 #endif
37 static int __on_exit_count = 0;
38 typedef void (*on_exit_func_t) (int, void *);
39 static on_exit_func_t __on_exit_funcs[ATEXIT_MAX];
40 static void *__on_exit_args[ATEXIT_MAX];
41 static int __exitcode = 0;
42 static void __handle_on_exit_funcs(void);
43 static int on_exit(on_exit_func_t function, void *arg);
44 #define exit(x) (exit)(__exitcode = (x))
45
46 static int on_exit(on_exit_func_t function, void *arg)
47 {
48         if (__on_exit_count == ATEXIT_MAX)
49                 return -ENOMEM;
50         else if (__on_exit_count == 0)
51                 atexit(__handle_on_exit_funcs);
52         __on_exit_funcs[__on_exit_count] = function;
53         __on_exit_args[__on_exit_count++] = arg;
54         return 0;
55 }
56
57 static void __handle_on_exit_funcs(void)
58 {
59         int i;
60         for (i = 0; i < __on_exit_count; i++)
61                 __on_exit_funcs[i] (__exitcode, __on_exit_args[i]);
62 }
63 #endif
64
65 struct record {
66         struct perf_tool        tool;
67         struct record_opts      opts;
68         u64                     bytes_written;
69         struct perf_data_file   file;
70         struct perf_evlist      *evlist;
71         struct perf_session     *session;
72         const char              *progname;
73         int                     realtime_prio;
74         bool                    no_buildid;
75         bool                    no_buildid_cache;
76         long                    samples;
77 };
78
79 static int record__write(struct record *rec, void *bf, size_t size)
80 {
81         if (perf_data_file__write(rec->session->file, bf, size) < 0) {
82                 pr_err("failed to write perf data, error: %m\n");
83                 return -1;
84         }
85
86         rec->bytes_written += size;
87         return 0;
88 }
89
90 static int process_synthesized_event(struct perf_tool *tool,
91                                      union perf_event *event,
92                                      struct perf_sample *sample __maybe_unused,
93                                      struct machine *machine __maybe_unused)
94 {
95         struct record *rec = container_of(tool, struct record, tool);
96         return record__write(rec, event, event->header.size);
97 }
98
99 static int record__mmap_read(struct record *rec, struct perf_mmap *md)
100 {
101         unsigned int head = perf_mmap__read_head(md);
102         unsigned int old = md->prev;
103         unsigned char *data = md->base + page_size;
104         unsigned long size;
105         void *buf;
106         int rc = 0;
107
108         if (old == head)
109                 return 0;
110
111         rec->samples++;
112
113         size = head - old;
114
115         if ((old & md->mask) + size != (head & md->mask)) {
116                 buf = &data[old & md->mask];
117                 size = md->mask + 1 - (old & md->mask);
118                 old += size;
119
120                 if (record__write(rec, buf, size) < 0) {
121                         rc = -1;
122                         goto out;
123                 }
124         }
125
126         buf = &data[old & md->mask];
127         size = head - old;
128         old += size;
129
130         if (record__write(rec, buf, size) < 0) {
131                 rc = -1;
132                 goto out;
133         }
134
135         md->prev = old;
136         perf_mmap__write_tail(md, old);
137
138 out:
139         return rc;
140 }
141
142 static volatile int done = 0;
143 static volatile int signr = -1;
144 static volatile int child_finished = 0;
145
146 static void sig_handler(int sig)
147 {
148         if (sig == SIGCHLD)
149                 child_finished = 1;
150
151         done = 1;
152         signr = sig;
153 }
154
155 static void record__sig_exit(int exit_status __maybe_unused, void *arg)
156 {
157         struct record *rec = arg;
158         int status;
159
160         if (rec->evlist->workload.pid > 0) {
161                 if (!child_finished)
162                         kill(rec->evlist->workload.pid, SIGTERM);
163
164                 wait(&status);
165                 if (WIFSIGNALED(status))
166                         psignal(WTERMSIG(status), rec->progname);
167         }
168
169         if (signr == -1 || signr == SIGUSR1)
170                 return;
171
172         signal(signr, SIG_DFL);
173 }
174
175 static int record__open(struct record *rec)
176 {
177         char msg[512];
178         struct perf_evsel *pos;
179         struct perf_evlist *evlist = rec->evlist;
180         struct perf_session *session = rec->session;
181         struct record_opts *opts = &rec->opts;
182         int rc = 0;
183
184         perf_evlist__config(evlist, opts);
185
186         list_for_each_entry(pos, &evlist->entries, node) {
187 try_again:
188                 if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) {
189                         if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
190                                 if (verbose)
191                                         ui__warning("%s\n", msg);
192                                 goto try_again;
193                         }
194
195                         rc = -errno;
196                         perf_evsel__open_strerror(pos, &opts->target,
197                                                   errno, msg, sizeof(msg));
198                         ui__error("%s\n", msg);
199                         goto out;
200                 }
201         }
202
203         if (perf_evlist__apply_filters(evlist)) {
204                 error("failed to set filter with %d (%s)\n", errno,
205                         strerror(errno));
206                 rc = -1;
207                 goto out;
208         }
209
210         if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) {
211                 if (errno == EPERM) {
212                         pr_err("Permission error mapping pages.\n"
213                                "Consider increasing "
214                                "/proc/sys/kernel/perf_event_mlock_kb,\n"
215                                "or try again with a smaller value of -m/--mmap_pages.\n"
216                                "(current value: %u)\n", opts->mmap_pages);
217                         rc = -errno;
218                 } else {
219                         pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno));
220                         rc = -errno;
221                 }
222                 goto out;
223         }
224
225         session->evlist = evlist;
226         perf_session__set_id_hdr_size(session);
227 out:
228         return rc;
229 }
230
231 static int process_buildids(struct record *rec)
232 {
233         struct perf_data_file *file  = &rec->file;
234         struct perf_session *session = rec->session;
235         u64 start = session->header.data_offset;
236
237         u64 size = lseek(file->fd, 0, SEEK_CUR);
238         if (size == 0)
239                 return 0;
240
241         return __perf_session__process_events(session, start,
242                                               size - start,
243                                               size, &build_id__mark_dso_hit_ops);
244 }
245
246 static void record__exit(int status, void *arg)
247 {
248         struct record *rec = arg;
249         struct perf_data_file *file = &rec->file;
250
251         if (status != 0)
252                 return;
253
254         if (!file->is_pipe) {
255                 rec->session->header.data_size += rec->bytes_written;
256
257                 if (!rec->no_buildid)
258                         process_buildids(rec);
259                 perf_session__write_header(rec->session, rec->evlist,
260                                            file->fd, true);
261                 perf_session__delete(rec->session);
262                 perf_evlist__delete(rec->evlist);
263                 symbol__exit();
264         }
265 }
266
267 static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
268 {
269         int err;
270         struct perf_tool *tool = data;
271         /*
272          *As for guest kernel when processing subcommand record&report,
273          *we arrange module mmap prior to guest kernel mmap and trigger
274          *a preload dso because default guest module symbols are loaded
275          *from guest kallsyms instead of /lib/modules/XXX/XXX. This
276          *method is used to avoid symbol missing when the first addr is
277          *in module instead of in guest kernel.
278          */
279         err = perf_event__synthesize_modules(tool, process_synthesized_event,
280                                              machine);
281         if (err < 0)
282                 pr_err("Couldn't record guest kernel [%d]'s reference"
283                        " relocation symbol.\n", machine->pid);
284
285         /*
286          * We use _stext for guest kernel because guest kernel's /proc/kallsyms
287          * have no _text sometimes.
288          */
289         err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
290                                                  machine, "_text");
291         if (err < 0)
292                 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
293                                                          machine, "_stext");
294         if (err < 0)
295                 pr_err("Couldn't record guest kernel [%d]'s reference"
296                        " relocation symbol.\n", machine->pid);
297 }
298
299 static struct perf_event_header finished_round_event = {
300         .size = sizeof(struct perf_event_header),
301         .type = PERF_RECORD_FINISHED_ROUND,
302 };
303
304 static int record__mmap_read_all(struct record *rec)
305 {
306         int i;
307         int rc = 0;
308
309         for (i = 0; i < rec->evlist->nr_mmaps; i++) {
310                 if (rec->evlist->mmap[i].base) {
311                         if (record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) {
312                                 rc = -1;
313                                 goto out;
314                         }
315                 }
316         }
317
318         if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA))
319                 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
320
321 out:
322         return rc;
323 }
324
325 static void record__init_features(struct record *rec)
326 {
327         struct perf_evlist *evsel_list = rec->evlist;
328         struct perf_session *session = rec->session;
329         int feat;
330
331         for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
332                 perf_header__set_feat(&session->header, feat);
333
334         if (rec->no_buildid)
335                 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
336
337         if (!have_tracepoints(&evsel_list->entries))
338                 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
339
340         if (!rec->opts.branch_stack)
341                 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
342 }
343
344 static int __cmd_record(struct record *rec, int argc, const char **argv)
345 {
346         int err;
347         unsigned long waking = 0;
348         const bool forks = argc > 0;
349         struct machine *machine;
350         struct perf_tool *tool = &rec->tool;
351         struct record_opts *opts = &rec->opts;
352         struct perf_evlist *evsel_list = rec->evlist;
353         struct perf_data_file *file = &rec->file;
354         struct perf_session *session;
355         bool disabled = false;
356
357         rec->progname = argv[0];
358
359         on_exit(record__sig_exit, rec);
360         signal(SIGCHLD, sig_handler);
361         signal(SIGINT, sig_handler);
362         signal(SIGUSR1, sig_handler);
363         signal(SIGTERM, sig_handler);
364
365         session = perf_session__new(file, false, NULL);
366         if (session == NULL) {
367                 pr_err("Not enough memory for reading perf file header\n");
368                 return -1;
369         }
370
371         rec->session = session;
372
373         record__init_features(rec);
374
375         if (forks) {
376                 err = perf_evlist__prepare_workload(evsel_list, &opts->target,
377                                                     argv, file->is_pipe,
378                                                     true);
379                 if (err < 0) {
380                         pr_err("Couldn't run the workload!\n");
381                         goto out_delete_session;
382                 }
383         }
384
385         if (record__open(rec) != 0) {
386                 err = -1;
387                 goto out_delete_session;
388         }
389
390         if (!evsel_list->nr_groups)
391                 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
392
393         /*
394          * perf_session__delete(session) will be called at record__exit()
395          */
396         on_exit(record__exit, rec);
397
398         if (file->is_pipe) {
399                 err = perf_header__write_pipe(file->fd);
400                 if (err < 0)
401                         goto out_delete_session;
402         } else {
403                 err = perf_session__write_header(session, evsel_list,
404                                                  file->fd, false);
405                 if (err < 0)
406                         goto out_delete_session;
407         }
408
409         if (!rec->no_buildid
410             && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
411                 pr_err("Couldn't generate buildids. "
412                        "Use --no-buildid to profile anyway.\n");
413                 err = -1;
414                 goto out_delete_session;
415         }
416
417         machine = &session->machines.host;
418
419         if (file->is_pipe) {
420                 err = perf_event__synthesize_attrs(tool, session,
421                                                    process_synthesized_event);
422                 if (err < 0) {
423                         pr_err("Couldn't synthesize attrs.\n");
424                         goto out_delete_session;
425                 }
426
427                 if (have_tracepoints(&evsel_list->entries)) {
428                         /*
429                          * FIXME err <= 0 here actually means that
430                          * there were no tracepoints so its not really
431                          * an error, just that we don't need to
432                          * synthesize anything.  We really have to
433                          * return this more properly and also
434                          * propagate errors that now are calling die()
435                          */
436                         err = perf_event__synthesize_tracing_data(tool, file->fd, evsel_list,
437                                                                   process_synthesized_event);
438                         if (err <= 0) {
439                                 pr_err("Couldn't record tracing data.\n");
440                                 goto out_delete_session;
441                         }
442                         rec->bytes_written += err;
443                 }
444         }
445
446         err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
447                                                  machine, "_text");
448         if (err < 0)
449                 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
450                                                          machine, "_stext");
451         if (err < 0)
452                 pr_err("Couldn't record kernel reference relocation symbol\n"
453                        "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
454                        "Check /proc/kallsyms permission or run as root.\n");
455
456         err = perf_event__synthesize_modules(tool, process_synthesized_event,
457                                              machine);
458         if (err < 0)
459                 pr_err("Couldn't record kernel module information.\n"
460                        "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
461                        "Check /proc/modules permission or run as root.\n");
462
463         if (perf_guest) {
464                 machines__process_guests(&session->machines,
465                                          perf_event__synthesize_guest_os, tool);
466         }
467
468         err = __machine__synthesize_threads(machine, tool, &opts->target, evsel_list->threads,
469                                             process_synthesized_event, opts->sample_address);
470         if (err != 0)
471                 goto out_delete_session;
472
473         if (rec->realtime_prio) {
474                 struct sched_param param;
475
476                 param.sched_priority = rec->realtime_prio;
477                 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
478                         pr_err("Could not set realtime priority.\n");
479                         err = -1;
480                         goto out_delete_session;
481                 }
482         }
483
484         /*
485          * When perf is starting the traced process, all the events
486          * (apart from group members) have enable_on_exec=1 set,
487          * so don't spoil it by prematurely enabling them.
488          */
489         if (!target__none(&opts->target))
490                 perf_evlist__enable(evsel_list);
491
492         /*
493          * Let the child rip
494          */
495         if (forks)
496                 perf_evlist__start_workload(evsel_list);
497
498         for (;;) {
499                 int hits = rec->samples;
500
501                 if (record__mmap_read_all(rec) < 0) {
502                         err = -1;
503                         goto out_delete_session;
504                 }
505
506                 if (hits == rec->samples) {
507                         if (done)
508                                 break;
509                         err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1);
510                         waking++;
511                 }
512
513                 /*
514                  * When perf is starting the traced process, at the end events
515                  * die with the process and we wait for that. Thus no need to
516                  * disable events in this case.
517                  */
518                 if (done && !disabled && !target__none(&opts->target)) {
519                         perf_evlist__disable(evsel_list);
520                         disabled = true;
521                 }
522         }
523
524         if (quiet || signr == SIGUSR1)
525                 return 0;
526
527         fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
528
529         /*
530          * Approximate RIP event size: 24 bytes.
531          */
532         fprintf(stderr,
533                 "[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64 " samples) ]\n",
534                 (double)rec->bytes_written / 1024.0 / 1024.0,
535                 file->path,
536                 rec->bytes_written / 24);
537
538         return 0;
539
540 out_delete_session:
541         perf_session__delete(session);
542         return err;
543 }
544
545 #define BRANCH_OPT(n, m) \
546         { .name = n, .mode = (m) }
547
548 #define BRANCH_END { .name = NULL }
549
550 struct branch_mode {
551         const char *name;
552         int mode;
553 };
554
555 static const struct branch_mode branch_modes[] = {
556         BRANCH_OPT("u", PERF_SAMPLE_BRANCH_USER),
557         BRANCH_OPT("k", PERF_SAMPLE_BRANCH_KERNEL),
558         BRANCH_OPT("hv", PERF_SAMPLE_BRANCH_HV),
559         BRANCH_OPT("any", PERF_SAMPLE_BRANCH_ANY),
560         BRANCH_OPT("any_call", PERF_SAMPLE_BRANCH_ANY_CALL),
561         BRANCH_OPT("any_ret", PERF_SAMPLE_BRANCH_ANY_RETURN),
562         BRANCH_OPT("ind_call", PERF_SAMPLE_BRANCH_IND_CALL),
563         BRANCH_OPT("abort_tx", PERF_SAMPLE_BRANCH_ABORT_TX),
564         BRANCH_OPT("in_tx", PERF_SAMPLE_BRANCH_IN_TX),
565         BRANCH_OPT("no_tx", PERF_SAMPLE_BRANCH_NO_TX),
566         BRANCH_END
567 };
568
569 static int
570 parse_branch_stack(const struct option *opt, const char *str, int unset)
571 {
572 #define ONLY_PLM \
573         (PERF_SAMPLE_BRANCH_USER        |\
574          PERF_SAMPLE_BRANCH_KERNEL      |\
575          PERF_SAMPLE_BRANCH_HV)
576
577         uint64_t *mode = (uint64_t *)opt->value;
578         const struct branch_mode *br;
579         char *s, *os = NULL, *p;
580         int ret = -1;
581
582         if (unset)
583                 return 0;
584
585         /*
586          * cannot set it twice, -b + --branch-filter for instance
587          */
588         if (*mode)
589                 return -1;
590
591         /* str may be NULL in case no arg is passed to -b */
592         if (str) {
593                 /* because str is read-only */
594                 s = os = strdup(str);
595                 if (!s)
596                         return -1;
597
598                 for (;;) {
599                         p = strchr(s, ',');
600                         if (p)
601                                 *p = '\0';
602
603                         for (br = branch_modes; br->name; br++) {
604                                 if (!strcasecmp(s, br->name))
605                                         break;
606                         }
607                         if (!br->name) {
608                                 ui__warning("unknown branch filter %s,"
609                                             " check man page\n", s);
610                                 goto error;
611                         }
612
613                         *mode |= br->mode;
614
615                         if (!p)
616                                 break;
617
618                         s = p + 1;
619                 }
620         }
621         ret = 0;
622
623         /* default to any branch */
624         if ((*mode & ~ONLY_PLM) == 0) {
625                 *mode = PERF_SAMPLE_BRANCH_ANY;
626         }
627 error:
628         free(os);
629         return ret;
630 }
631
632 #ifdef HAVE_LIBUNWIND_SUPPORT
633 static int get_stack_size(char *str, unsigned long *_size)
634 {
635         char *endptr;
636         unsigned long size;
637         unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
638
639         size = strtoul(str, &endptr, 0);
640
641         do {
642                 if (*endptr)
643                         break;
644
645                 size = round_up(size, sizeof(u64));
646                 if (!size || size > max_size)
647                         break;
648
649                 *_size = size;
650                 return 0;
651
652         } while (0);
653
654         pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
655                max_size, str);
656         return -1;
657 }
658 #endif /* HAVE_LIBUNWIND_SUPPORT */
659
660 int record_parse_callchain(const char *arg, struct record_opts *opts)
661 {
662         char *tok, *name, *saveptr = NULL;
663         char *buf;
664         int ret = -1;
665
666         /* We need buffer that we know we can write to. */
667         buf = malloc(strlen(arg) + 1);
668         if (!buf)
669                 return -ENOMEM;
670
671         strcpy(buf, arg);
672
673         tok = strtok_r((char *)buf, ",", &saveptr);
674         name = tok ? : (char *)buf;
675
676         do {
677                 /* Framepointer style */
678                 if (!strncmp(name, "fp", sizeof("fp"))) {
679                         if (!strtok_r(NULL, ",", &saveptr)) {
680                                 opts->call_graph = CALLCHAIN_FP;
681                                 ret = 0;
682                         } else
683                                 pr_err("callchain: No more arguments "
684                                        "needed for -g fp\n");
685                         break;
686
687 #ifdef HAVE_LIBUNWIND_SUPPORT
688                 /* Dwarf style */
689                 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
690                         const unsigned long default_stack_dump_size = 8192;
691
692                         ret = 0;
693                         opts->call_graph = CALLCHAIN_DWARF;
694                         opts->stack_dump_size = default_stack_dump_size;
695
696                         tok = strtok_r(NULL, ",", &saveptr);
697                         if (tok) {
698                                 unsigned long size = 0;
699
700                                 ret = get_stack_size(tok, &size);
701                                 opts->stack_dump_size = size;
702                         }
703 #endif /* HAVE_LIBUNWIND_SUPPORT */
704                 } else {
705                         pr_err("callchain: Unknown --call-graph option "
706                                "value: %s\n", arg);
707                         break;
708                 }
709
710         } while (0);
711
712         free(buf);
713         return ret;
714 }
715
716 static void callchain_debug(struct record_opts *opts)
717 {
718         pr_debug("callchain: type %d\n", opts->call_graph);
719
720         if (opts->call_graph == CALLCHAIN_DWARF)
721                 pr_debug("callchain: stack dump size %d\n",
722                          opts->stack_dump_size);
723 }
724
725 int record_parse_callchain_opt(const struct option *opt,
726                                const char *arg,
727                                int unset)
728 {
729         struct record_opts *opts = opt->value;
730         int ret;
731
732         /* --no-call-graph */
733         if (unset) {
734                 opts->call_graph = CALLCHAIN_NONE;
735                 pr_debug("callchain: disabled\n");
736                 return 0;
737         }
738
739         ret = record_parse_callchain(arg, opts);
740         if (!ret)
741                 callchain_debug(opts);
742
743         return ret;
744 }
745
746 int record_callchain_opt(const struct option *opt,
747                          const char *arg __maybe_unused,
748                          int unset __maybe_unused)
749 {
750         struct record_opts *opts = opt->value;
751
752         if (opts->call_graph == CALLCHAIN_NONE)
753                 opts->call_graph = CALLCHAIN_FP;
754
755         callchain_debug(opts);
756         return 0;
757 }
758
759 static const char * const record_usage[] = {
760         "perf record [<options>] [<command>]",
761         "perf record [<options>] -- <command> [<options>]",
762         NULL
763 };
764
765 /*
766  * XXX Ideally would be local to cmd_record() and passed to a record__new
767  * because we need to have access to it in record__exit, that is called
768  * after cmd_record() exits, but since record_options need to be accessible to
769  * builtin-script, leave it here.
770  *
771  * At least we don't ouch it in all the other functions here directly.
772  *
773  * Just say no to tons of global variables, sigh.
774  */
775 static struct record record = {
776         .opts = {
777                 .mmap_pages          = UINT_MAX,
778                 .user_freq           = UINT_MAX,
779                 .user_interval       = ULLONG_MAX,
780                 .freq                = 4000,
781                 .target              = {
782                         .uses_mmap   = true,
783                         .default_per_cpu = true,
784                 },
785         },
786 };
787
788 #define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace) recording: "
789
790 #ifdef HAVE_LIBUNWIND_SUPPORT
791 const char record_callchain_help[] = CALLCHAIN_HELP "fp dwarf";
792 #else
793 const char record_callchain_help[] = CALLCHAIN_HELP "fp";
794 #endif
795
796 /*
797  * XXX Will stay a global variable till we fix builtin-script.c to stop messing
798  * with it and switch to use the library functions in perf_evlist that came
799  * from builtin-record.c, i.e. use record_opts,
800  * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
801  * using pipes, etc.
802  */
803 const struct option record_options[] = {
804         OPT_CALLBACK('e', "event", &record.evlist, "event",
805                      "event selector. use 'perf list' to list available events",
806                      parse_events_option),
807         OPT_CALLBACK(0, "filter", &record.evlist, "filter",
808                      "event filter", parse_filter),
809         OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
810                     "record events on existing process id"),
811         OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
812                     "record events on existing thread id"),
813         OPT_INTEGER('r', "realtime", &record.realtime_prio,
814                     "collect data with this RT SCHED_FIFO priority"),
815         OPT_BOOLEAN('D', "no-delay", &record.opts.no_delay,
816                     "collect data without buffering"),
817         OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
818                     "collect raw sample records from all opened counters"),
819         OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
820                             "system-wide collection from all CPUs"),
821         OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
822                     "list of cpus to monitor"),
823         OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
824         OPT_STRING('o', "output", &record.file.path, "file",
825                     "output file name"),
826         OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
827                         &record.opts.no_inherit_set,
828                         "child tasks do not inherit counters"),
829         OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
830         OPT_CALLBACK('m', "mmap-pages", &record.opts.mmap_pages, "pages",
831                      "number of mmap data pages",
832                      perf_evlist__parse_mmap_pages),
833         OPT_BOOLEAN(0, "group", &record.opts.group,
834                     "put the counters into a counter group"),
835         OPT_CALLBACK_NOOPT('g', NULL, &record.opts,
836                            NULL, "enables call-graph recording" ,
837                            &record_callchain_opt),
838         OPT_CALLBACK(0, "call-graph", &record.opts,
839                      "mode[,dump_size]", record_callchain_help,
840                      &record_parse_callchain_opt),
841         OPT_INCR('v', "verbose", &verbose,
842                     "be more verbose (show counter open errors, etc)"),
843         OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
844         OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
845                     "per thread counts"),
846         OPT_BOOLEAN('d', "data", &record.opts.sample_address,
847                     "Sample addresses"),
848         OPT_BOOLEAN('T', "timestamp", &record.opts.sample_time, "Sample timestamps"),
849         OPT_BOOLEAN('P', "period", &record.opts.period, "Sample period"),
850         OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
851                     "don't sample"),
852         OPT_BOOLEAN('N', "no-buildid-cache", &record.no_buildid_cache,
853                     "do not update the buildid cache"),
854         OPT_BOOLEAN('B', "no-buildid", &record.no_buildid,
855                     "do not collect buildids in perf.data"),
856         OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
857                      "monitor event in cgroup name only",
858                      parse_cgroups),
859         OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
860                    "user to profile"),
861
862         OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
863                      "branch any", "sample any taken branches",
864                      parse_branch_stack),
865
866         OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
867                      "branch filter mask", "branch stack filter modes",
868                      parse_branch_stack),
869         OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
870                     "sample by weight (on special events only)"),
871         OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
872                     "sample transaction flags (special events only)"),
873         OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
874                     "use per-thread mmaps"),
875         OPT_END()
876 };
877
878 int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
879 {
880         int err = -ENOMEM;
881         struct perf_evlist *evsel_list;
882         struct record *rec = &record;
883         char errbuf[BUFSIZ];
884
885         evsel_list = perf_evlist__new();
886         if (evsel_list == NULL)
887                 return -ENOMEM;
888
889         rec->evlist = evsel_list;
890
891         argc = parse_options(argc, argv, record_options, record_usage,
892                             PARSE_OPT_STOP_AT_NON_OPTION);
893         if (!argc && target__none(&rec->opts.target))
894                 usage_with_options(record_usage, record_options);
895
896         if (nr_cgroups && !rec->opts.target.system_wide) {
897                 ui__error("cgroup monitoring only available in"
898                           " system-wide mode\n");
899                 usage_with_options(record_usage, record_options);
900         }
901
902         symbol__init();
903
904         if (symbol_conf.kptr_restrict)
905                 pr_warning(
906 "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
907 "check /proc/sys/kernel/kptr_restrict.\n\n"
908 "Samples in kernel functions may not be resolved if a suitable vmlinux\n"
909 "file is not found in the buildid cache or in the vmlinux path.\n\n"
910 "Samples in kernel modules won't be resolved at all.\n\n"
911 "If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
912 "even with a suitable vmlinux or kallsyms file.\n\n");
913
914         if (rec->no_buildid_cache || rec->no_buildid)
915                 disable_buildid_cache();
916
917         if (evsel_list->nr_entries == 0 &&
918             perf_evlist__add_default(evsel_list) < 0) {
919                 pr_err("Not enough memory for event selector list\n");
920                 goto out_symbol_exit;
921         }
922
923         if (rec->opts.target.tid && !rec->opts.no_inherit_set)
924                 rec->opts.no_inherit = true;
925
926         err = target__validate(&rec->opts.target);
927         if (err) {
928                 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
929                 ui__warning("%s", errbuf);
930         }
931
932         err = target__parse_uid(&rec->opts.target);
933         if (err) {
934                 int saved_errno = errno;
935
936                 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
937                 ui__error("%s", errbuf);
938
939                 err = -saved_errno;
940                 goto out_symbol_exit;
941         }
942
943         err = -ENOMEM;
944         if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
945                 usage_with_options(record_usage, record_options);
946
947         if (record_opts__config(&rec->opts)) {
948                 err = -EINVAL;
949                 goto out_free_fd;
950         }
951
952         err = __cmd_record(&record, argc, argv);
953
954         perf_evlist__munmap(evsel_list);
955         perf_evlist__close(evsel_list);
956 out_free_fd:
957         perf_evlist__delete_maps(evsel_list);
958 out_symbol_exit:
959         symbol__exit();
960         return err;
961 }