OSDN Git Service

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