Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[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
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 static void callchain_debug(void)
628 {
629         static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF" };
630
631         pr_debug("callchain: type %s\n", str[callchain_param.record_mode]);
632
633         if (callchain_param.record_mode == CALLCHAIN_DWARF)
634                 pr_debug("callchain: stack dump size %d\n",
635                          callchain_param.dump_size);
636 }
637
638 int record_parse_callchain_opt(const struct option *opt __maybe_unused,
639                                const char *arg,
640                                int unset)
641 {
642         int ret;
643
644         callchain_param.enabled = !unset;
645
646         /* --no-call-graph */
647         if (unset) {
648                 callchain_param.record_mode = CALLCHAIN_NONE;
649                 pr_debug("callchain: disabled\n");
650                 return 0;
651         }
652
653         ret = parse_callchain_record_opt(arg);
654         if (!ret)
655                 callchain_debug();
656
657         return ret;
658 }
659
660 int record_callchain_opt(const struct option *opt __maybe_unused,
661                          const char *arg __maybe_unused,
662                          int unset __maybe_unused)
663 {
664         callchain_param.enabled = true;
665
666         if (callchain_param.record_mode == CALLCHAIN_NONE)
667                 callchain_param.record_mode = CALLCHAIN_FP;
668
669         callchain_debug();
670         return 0;
671 }
672
673 static int perf_record_config(const char *var, const char *value, void *cb)
674 {
675         if (!strcmp(var, "record.call-graph"))
676                 var = "call-graph.record-mode"; /* fall-through */
677
678         return perf_default_config(var, value, cb);
679 }
680
681 static const char * const record_usage[] = {
682         "perf record [<options>] [<command>]",
683         "perf record [<options>] -- <command> [<options>]",
684         NULL
685 };
686
687 /*
688  * XXX Ideally would be local to cmd_record() and passed to a record__new
689  * because we need to have access to it in record__exit, that is called
690  * after cmd_record() exits, but since record_options need to be accessible to
691  * builtin-script, leave it here.
692  *
693  * At least we don't ouch it in all the other functions here directly.
694  *
695  * Just say no to tons of global variables, sigh.
696  */
697 static struct record record = {
698         .opts = {
699                 .sample_time         = true,
700                 .mmap_pages          = UINT_MAX,
701                 .user_freq           = UINT_MAX,
702                 .user_interval       = ULLONG_MAX,
703                 .freq                = 4000,
704                 .target              = {
705                         .uses_mmap   = true,
706                         .default_per_cpu = true,
707                 },
708         },
709 };
710
711 #define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace) recording: "
712
713 #ifdef HAVE_DWARF_UNWIND_SUPPORT
714 const char record_callchain_help[] = CALLCHAIN_HELP "fp dwarf";
715 #else
716 const char record_callchain_help[] = CALLCHAIN_HELP "fp";
717 #endif
718
719 /*
720  * XXX Will stay a global variable till we fix builtin-script.c to stop messing
721  * with it and switch to use the library functions in perf_evlist that came
722  * from builtin-record.c, i.e. use record_opts,
723  * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
724  * using pipes, etc.
725  */
726 const struct option record_options[] = {
727         OPT_CALLBACK('e', "event", &record.evlist, "event",
728                      "event selector. use 'perf list' to list available events",
729                      parse_events_option),
730         OPT_CALLBACK(0, "filter", &record.evlist, "filter",
731                      "event filter", parse_filter),
732         OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
733                     "record events on existing process id"),
734         OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
735                     "record events on existing thread id"),
736         OPT_INTEGER('r', "realtime", &record.realtime_prio,
737                     "collect data with this RT SCHED_FIFO priority"),
738         OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
739                     "collect data without buffering"),
740         OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
741                     "collect raw sample records from all opened counters"),
742         OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
743                             "system-wide collection from all CPUs"),
744         OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
745                     "list of cpus to monitor"),
746         OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
747         OPT_STRING('o', "output", &record.file.path, "file",
748                     "output file name"),
749         OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
750                         &record.opts.no_inherit_set,
751                         "child tasks do not inherit counters"),
752         OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
753         OPT_CALLBACK('m', "mmap-pages", &record.opts.mmap_pages, "pages",
754                      "number of mmap data pages",
755                      perf_evlist__parse_mmap_pages),
756         OPT_BOOLEAN(0, "group", &record.opts.group,
757                     "put the counters into a counter group"),
758         OPT_CALLBACK_NOOPT('g', NULL, &record.opts,
759                            NULL, "enables call-graph recording" ,
760                            &record_callchain_opt),
761         OPT_CALLBACK(0, "call-graph", &record.opts,
762                      "mode[,dump_size]", record_callchain_help,
763                      &record_parse_callchain_opt),
764         OPT_INCR('v', "verbose", &verbose,
765                     "be more verbose (show counter open errors, etc)"),
766         OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
767         OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
768                     "per thread counts"),
769         OPT_BOOLEAN('d', "data", &record.opts.sample_address,
770                     "Sample addresses"),
771         OPT_BOOLEAN('T', "timestamp", &record.opts.sample_time, "Sample timestamps"),
772         OPT_BOOLEAN('P', "period", &record.opts.period, "Sample period"),
773         OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
774                     "don't sample"),
775         OPT_BOOLEAN('N', "no-buildid-cache", &record.no_buildid_cache,
776                     "do not update the buildid cache"),
777         OPT_BOOLEAN('B', "no-buildid", &record.no_buildid,
778                     "do not collect buildids in perf.data"),
779         OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
780                      "monitor event in cgroup name only",
781                      parse_cgroups),
782         OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
783                   "ms to wait before starting measurement after program start"),
784         OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
785                    "user to profile"),
786
787         OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
788                      "branch any", "sample any taken branches",
789                      parse_branch_stack),
790
791         OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
792                      "branch filter mask", "branch stack filter modes",
793                      parse_branch_stack),
794         OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
795                     "sample by weight (on special events only)"),
796         OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
797                     "sample transaction flags (special events only)"),
798         OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
799                     "use per-thread mmaps"),
800         OPT_END()
801 };
802
803 int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
804 {
805         int err = -ENOMEM;
806         struct record *rec = &record;
807         char errbuf[BUFSIZ];
808
809         rec->evlist = perf_evlist__new();
810         if (rec->evlist == NULL)
811                 return -ENOMEM;
812
813         perf_config(perf_record_config, rec);
814
815         argc = parse_options(argc, argv, record_options, record_usage,
816                             PARSE_OPT_STOP_AT_NON_OPTION);
817         if (!argc && target__none(&rec->opts.target))
818                 usage_with_options(record_usage, record_options);
819
820         if (nr_cgroups && !rec->opts.target.system_wide) {
821                 ui__error("cgroup monitoring only available in"
822                           " system-wide mode\n");
823                 usage_with_options(record_usage, record_options);
824         }
825
826         symbol__init(NULL);
827
828         if (symbol_conf.kptr_restrict)
829                 pr_warning(
830 "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
831 "check /proc/sys/kernel/kptr_restrict.\n\n"
832 "Samples in kernel functions may not be resolved if a suitable vmlinux\n"
833 "file is not found in the buildid cache or in the vmlinux path.\n\n"
834 "Samples in kernel modules won't be resolved at all.\n\n"
835 "If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
836 "even with a suitable vmlinux or kallsyms file.\n\n");
837
838         if (rec->no_buildid_cache || rec->no_buildid)
839                 disable_buildid_cache();
840
841         if (rec->evlist->nr_entries == 0 &&
842             perf_evlist__add_default(rec->evlist) < 0) {
843                 pr_err("Not enough memory for event selector list\n");
844                 goto out_symbol_exit;
845         }
846
847         if (rec->opts.target.tid && !rec->opts.no_inherit_set)
848                 rec->opts.no_inherit = true;
849
850         err = target__validate(&rec->opts.target);
851         if (err) {
852                 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
853                 ui__warning("%s", errbuf);
854         }
855
856         err = target__parse_uid(&rec->opts.target);
857         if (err) {
858                 int saved_errno = errno;
859
860                 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
861                 ui__error("%s", errbuf);
862
863                 err = -saved_errno;
864                 goto out_symbol_exit;
865         }
866
867         err = -ENOMEM;
868         if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
869                 usage_with_options(record_usage, record_options);
870
871         if (record_opts__config(&rec->opts)) {
872                 err = -EINVAL;
873                 goto out_symbol_exit;
874         }
875
876         err = __cmd_record(&record, argc, argv);
877 out_symbol_exit:
878         perf_evlist__delete(rec->evlist);
879         symbol__exit();
880         return err;
881 }