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