perf evlist: Don't use globals where not needed to
[deliverable/linux.git] / tools / perf / builtin-record.c
CommitLineData
abaff32a 1/*
bf9e1876
IM
2 * builtin-record.c
3 *
4 * Builtin record command: Record the profile of a workload
5 * (or a CPU, or a PID) into the perf.data output file - for
6 * later analysis via perf report.
abaff32a 7 */
b8f46c5a
XG
8#define _FILE_OFFSET_BITS 64
9
16f762a2 10#include "builtin.h"
bf9e1876
IM
11
12#include "perf.h"
13
6122e4e4 14#include "util/build-id.h"
6eda5838 15#include "util/util.h"
0e9b20b8 16#include "util/parse-options.h"
8ad8db37 17#include "util/parse-events.h"
6eda5838 18
7c6a1c65 19#include "util/header.h"
66e274f3 20#include "util/event.h"
361c99a6 21#include "util/evlist.h"
69aad6f1 22#include "util/evsel.h"
8f28827a 23#include "util/debug.h"
94c744b6 24#include "util/session.h"
45694aa7 25#include "util/tool.h"
8d06367f 26#include "util/symbol.h"
a12b51c4 27#include "util/cpumap.h"
fd78260b 28#include "util/thread_map.h"
7c6a1c65 29
97124d5e 30#include <unistd.h>
de9ac07b 31#include <sched.h>
a41794cd 32#include <sys/mman.h>
de9ac07b 33
26d33022
JO
34#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: "
35
95485b1c 36#ifdef LIBUNWIND_SUPPORT
26d33022
JO
37static unsigned long default_stack_dump_size = 8192;
38static char callchain_help[] = CALLCHAIN_HELP "[fp] dwarf";
95485b1c
NK
39#else
40static char callchain_help[] = CALLCHAIN_HELP "[fp]";
26d33022
JO
41#endif
42
7865e817
FW
43enum write_mode_t {
44 WRITE_FORCE,
45 WRITE_APPEND
46};
47
d20deb64 48struct perf_record {
45694aa7 49 struct perf_tool tool;
d20deb64
ACM
50 struct perf_record_opts opts;
51 u64 bytes_written;
52 const char *output_name;
53 struct perf_evlist *evlist;
54 struct perf_session *session;
55 const char *progname;
56 int output;
57 unsigned int page_size;
58 int realtime_prio;
59 enum write_mode_t write_mode;
60 bool no_buildid;
61 bool no_buildid_cache;
62 bool force;
63 bool file_new;
64 bool append_file;
65 long samples;
66 off_t post_processing_offset;
0f82ebc4 67};
a21ca2ca 68
d20deb64 69static void advance_output(struct perf_record *rec, size_t size)
9215545e 70{
d20deb64 71 rec->bytes_written += size;
9215545e
TZ
72}
73
8d3eca20 74static int write_output(struct perf_record *rec, void *buf, size_t size)
f5970550
PZ
75{
76 while (size) {
d20deb64 77 int ret = write(rec->output, buf, size);
f5970550 78
8d3eca20
DA
79 if (ret < 0) {
80 pr_err("failed to write\n");
81 return -1;
82 }
f5970550
PZ
83
84 size -= ret;
85 buf += ret;
86
d20deb64 87 rec->bytes_written += ret;
f5970550 88 }
8d3eca20
DA
89
90 return 0;
f5970550
PZ
91}
92
45694aa7 93static int process_synthesized_event(struct perf_tool *tool,
d20deb64 94 union perf_event *event,
1d037ca1
IT
95 struct perf_sample *sample __maybe_unused,
96 struct machine *machine __maybe_unused)
234fbbf5 97{
45694aa7 98 struct perf_record *rec = container_of(tool, struct perf_record, tool);
8d3eca20
DA
99 if (write_output(rec, event, event->header.size) < 0)
100 return -1;
101
234fbbf5
ACM
102 return 0;
103}
104
8d3eca20 105static int perf_record__mmap_read(struct perf_record *rec,
d20deb64 106 struct perf_mmap *md)
de9ac07b 107{
744bd8aa 108 unsigned int head = perf_mmap__read_head(md);
de9ac07b 109 unsigned int old = md->prev;
d20deb64 110 unsigned char *data = md->base + rec->page_size;
de9ac07b
PZ
111 unsigned long size;
112 void *buf;
8d3eca20 113 int rc = 0;
de9ac07b 114
dc82009a 115 if (old == head)
8d3eca20 116 return 0;
dc82009a 117
d20deb64 118 rec->samples++;
de9ac07b
PZ
119
120 size = head - old;
121
122 if ((old & md->mask) + size != (head & md->mask)) {
123 buf = &data[old & md->mask];
124 size = md->mask + 1 - (old & md->mask);
125 old += size;
021e9f47 126
8d3eca20
DA
127 if (write_output(rec, buf, size) < 0) {
128 rc = -1;
129 goto out;
130 }
de9ac07b
PZ
131 }
132
133 buf = &data[old & md->mask];
134 size = head - old;
135 old += size;
021e9f47 136
8d3eca20
DA
137 if (write_output(rec, buf, size) < 0) {
138 rc = -1;
139 goto out;
140 }
de9ac07b
PZ
141
142 md->prev = old;
115d2d89 143 perf_mmap__write_tail(md, old);
8d3eca20
DA
144
145out:
146 return rc;
de9ac07b
PZ
147}
148
149static volatile int done = 0;
f7b7c26e 150static volatile int signr = -1;
33e49ea7 151static volatile int child_finished = 0;
de9ac07b 152
16c8a109 153static void sig_handler(int sig)
de9ac07b 154{
33e49ea7
AK
155 if (sig == SIGCHLD)
156 child_finished = 1;
157
16c8a109 158 done = 1;
f7b7c26e
PZ
159 signr = sig;
160}
161
1d037ca1 162static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
f7b7c26e 163{
d20deb64 164 struct perf_record *rec = arg;
33e49ea7
AK
165 int status;
166
d20deb64 167 if (rec->evlist->workload.pid > 0) {
33e49ea7 168 if (!child_finished)
d20deb64 169 kill(rec->evlist->workload.pid, SIGTERM);
33e49ea7
AK
170
171 wait(&status);
172 if (WIFSIGNALED(status))
d20deb64 173 psignal(WTERMSIG(status), rec->progname);
33e49ea7 174 }
933da83a 175
18483b81 176 if (signr == -1 || signr == SIGUSR1)
f7b7c26e
PZ
177 return;
178
179 signal(signr, SIG_DFL);
180 kill(getpid(), signr);
de9ac07b
PZ
181}
182
a91e5431
ACM
183static bool perf_evlist__equal(struct perf_evlist *evlist,
184 struct perf_evlist *other)
185{
186 struct perf_evsel *pos, *pair;
187
188 if (evlist->nr_entries != other->nr_entries)
189 return false;
190
0c21f736 191 pair = perf_evlist__first(other);
a91e5431
ACM
192
193 list_for_each_entry(pos, &evlist->entries, node) {
194 if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0))
195 return false;
0c21f736 196 pair = perf_evsel__next(pair);
a91e5431
ACM
197 }
198
199 return true;
200}
201
8d3eca20 202static int perf_record__open(struct perf_record *rec)
dd7927f4 203{
6a4bb04c 204 struct perf_evsel *pos;
d20deb64
ACM
205 struct perf_evlist *evlist = rec->evlist;
206 struct perf_session *session = rec->session;
207 struct perf_record_opts *opts = &rec->opts;
8d3eca20 208 int rc = 0;
dd7927f4 209
d20deb64 210 perf_evlist__config_attrs(evlist, opts);
0f82ebc4 211
6a4bb04c 212 if (opts->group)
63dab225 213 perf_evlist__set_leader(evlist);
6a4bb04c 214
dd7927f4
ACM
215 list_for_each_entry(pos, &evlist->entries, node) {
216 struct perf_event_attr *attr = &pos->attr;
217 /*
218 * Check if parse_single_tracepoint_event has already asked for
219 * PERF_SAMPLE_TIME.
220 *
221 * XXX this is kludgy but short term fix for problems introduced by
222 * eac23d1c that broke 'perf script' by having different sample_types
223 * when using multiple tracepoint events when we use a perf binary
224 * that tries to use sample_id_all on an older kernel.
225 *
226 * We need to move counter creation to perf_session, support
227 * different sample_types, etc.
228 */
229 bool time_needed = attr->sample_type & PERF_SAMPLE_TIME;
d6d901c2 230
0c978128
ACM
231fallback_missing_features:
232 if (opts->exclude_guest_missing)
233 attr->exclude_guest = attr->exclude_host = 0;
dd7927f4 234retry_sample_id:
808e1226 235 attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1;
dd7927f4 236try_again:
6a4bb04c 237 if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) {
d6d901c2
ZY
238 int err = errno;
239
c286c419 240 if (err == EPERM || err == EACCES) {
b8631e6e 241 ui__error_paranoid();
8d3eca20
DA
242 rc = -err;
243 goto out;
bea03405 244 } else if (err == ENODEV && opts->target.cpu_list) {
8d3eca20
DA
245 pr_err("No such device - did you specify"
246 " an out-of-range profile CPU?\n");
247 rc = -err;
248 goto out;
0c978128
ACM
249 } else if (err == EINVAL) {
250 if (!opts->exclude_guest_missing &&
251 (attr->exclude_guest || attr->exclude_host)) {
252 pr_debug("Old kernel, cannot exclude "
253 "guest or host samples.\n");
254 opts->exclude_guest_missing = true;
255 goto fallback_missing_features;
808e1226 256 } else if (!opts->sample_id_all_missing) {
0c978128
ACM
257 /*
258 * Old kernel, no attr->sample_id_type_all field
259 */
808e1226 260 opts->sample_id_all_missing = true;
0c978128
ACM
261 if (!opts->sample_time && !opts->raw_samples && !time_needed)
262 attr->sample_type &= ~PERF_SAMPLE_TIME;
263
264 goto retry_sample_id;
265 }
d6d901c2 266 }
3da297a6 267
d6d901c2
ZY
268 /*
269 * If it's cycles then fall back to hrtimer
270 * based cpu-clock-tick sw counter, which
028d455b
DA
271 * is always available even if no PMU support.
272 *
273 * PPC returns ENXIO until 2.6.37 (behavior changed
274 * with commit b0a873e).
d6d901c2 275 */
028d455b
DA
276 if ((err == ENOENT || err == ENXIO)
277 && attr->type == PERF_TYPE_HARDWARE
d6d901c2
ZY
278 && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
279
280 if (verbose)
ca6a4258
DA
281 ui__warning("The cycles event is not supported, "
282 "trying to fall back to cpu-clock-ticks\n");
d6d901c2
ZY
283 attr->type = PERF_TYPE_SOFTWARE;
284 attr->config = PERF_COUNT_SW_CPU_CLOCK;
d1cae34d
DA
285 if (pos->name) {
286 free(pos->name);
287 pos->name = NULL;
288 }
d6d901c2
ZY
289 goto try_again;
290 }
ca6a4258
DA
291
292 if (err == ENOENT) {
3780f488 293 ui__error("The %s event is not supported.\n",
7289f83c 294 perf_evsel__name(pos));
8d3eca20
DA
295 rc = -err;
296 goto out;
ca6a4258
DA
297 }
298
d6d901c2 299 printf("\n");
1863fbbb
SE
300 error("sys_perf_event_open() syscall returned with %d "
301 "(%s) for event %s. /bin/dmesg may provide "
302 "additional information.\n",
303 err, strerror(err), perf_evsel__name(pos));
bfd45118
SK
304
305#if defined(__i386__) || defined(__x86_64__)
8d3eca20
DA
306 if (attr->type == PERF_TYPE_HARDWARE &&
307 err == EOPNOTSUPP) {
308 pr_err("No hardware sampling interrupt available."
309 " No APIC? If so then you can boot the kernel"
310 " with the \"lapic\" boot parameter to"
311 " force-enable it.\n");
312 rc = -err;
313 goto out;
314 }
bfd45118
SK
315#endif
316
8d3eca20
DA
317 pr_err("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
318 rc = -err;
319 goto out;
c171b552
LZ
320 }
321 }
a43d3f08 322
1491a632 323 if (perf_evlist__apply_filters(evlist)) {
0a102479
FW
324 error("failed to set filter with %d (%s)\n", errno,
325 strerror(errno));
8d3eca20
DA
326 rc = -1;
327 goto out;
0a102479
FW
328 }
329
18e60939 330 if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) {
8d3eca20
DA
331 if (errno == EPERM) {
332 pr_err("Permission error mapping pages.\n"
333 "Consider increasing "
334 "/proc/sys/kernel/perf_event_mlock_kb,\n"
335 "or try again with a smaller value of -m/--mmap_pages.\n"
336 "(current value: %d)\n", opts->mmap_pages);
337 rc = -errno;
338 } else if (!is_power_of_2(opts->mmap_pages)) {
339 pr_err("--mmap_pages/-m value must be a power of two.");
340 rc = -EINVAL;
341 } else {
342 pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno));
343 rc = -errno;
344 }
345 goto out;
18e60939 346 }
0a27d7f9 347
d20deb64 348 if (rec->file_new)
a91e5431
ACM
349 session->evlist = evlist;
350 else {
351 if (!perf_evlist__equal(session->evlist, evlist)) {
352 fprintf(stderr, "incompatible append\n");
8d3eca20
DA
353 rc = -1;
354 goto out;
a91e5431
ACM
355 }
356 }
357
7b56cce2 358 perf_session__set_id_hdr_size(session);
8d3eca20
DA
359out:
360 return rc;
16c8a109
PZ
361}
362
d20deb64 363static int process_buildids(struct perf_record *rec)
6122e4e4 364{
d20deb64 365 u64 size = lseek(rec->output, 0, SEEK_CUR);
6122e4e4 366
9f591fd7
ACM
367 if (size == 0)
368 return 0;
369
d20deb64
ACM
370 rec->session->fd = rec->output;
371 return __perf_session__process_events(rec->session, rec->post_processing_offset,
372 size - rec->post_processing_offset,
6122e4e4
ACM
373 size, &build_id__mark_dso_hit_ops);
374}
375
8d3eca20 376static void perf_record__exit(int status, void *arg)
f5970550 377{
d20deb64
ACM
378 struct perf_record *rec = arg;
379
8d3eca20
DA
380 if (status != 0)
381 return;
382
d20deb64
ACM
383 if (!rec->opts.pipe_output) {
384 rec->session->header.data_size += rec->bytes_written;
385
386 if (!rec->no_buildid)
387 process_buildids(rec);
388 perf_session__write_header(rec->session, rec->evlist,
389 rec->output, true);
390 perf_session__delete(rec->session);
391 perf_evlist__delete(rec->evlist);
d65a458b 392 symbol__exit();
c7929e47 393 }
f5970550
PZ
394}
395
8115d60c 396static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
a1645ce1
ZY
397{
398 int err;
45694aa7 399 struct perf_tool *tool = data;
a1645ce1 400
23346f21 401 if (machine__is_host(machine))
a1645ce1
ZY
402 return;
403
404 /*
405 *As for guest kernel when processing subcommand record&report,
406 *we arrange module mmap prior to guest kernel mmap and trigger
407 *a preload dso because default guest module symbols are loaded
408 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
409 *method is used to avoid symbol missing when the first addr is
410 *in module instead of in guest kernel.
411 */
45694aa7 412 err = perf_event__synthesize_modules(tool, process_synthesized_event,
743eb868 413 machine);
a1645ce1
ZY
414 if (err < 0)
415 pr_err("Couldn't record guest kernel [%d]'s reference"
23346f21 416 " relocation symbol.\n", machine->pid);
a1645ce1 417
a1645ce1
ZY
418 /*
419 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
420 * have no _text sometimes.
421 */
45694aa7 422 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
743eb868 423 machine, "_text");
a1645ce1 424 if (err < 0)
45694aa7 425 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
743eb868 426 machine, "_stext");
a1645ce1
ZY
427 if (err < 0)
428 pr_err("Couldn't record guest kernel [%d]'s reference"
23346f21 429 " relocation symbol.\n", machine->pid);
a1645ce1
ZY
430}
431
98402807
FW
432static struct perf_event_header finished_round_event = {
433 .size = sizeof(struct perf_event_header),
434 .type = PERF_RECORD_FINISHED_ROUND,
435};
436
8d3eca20 437static int perf_record__mmap_read_all(struct perf_record *rec)
98402807 438{
0e2e63dd 439 int i;
8d3eca20 440 int rc = 0;
98402807 441
d20deb64 442 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
8d3eca20
DA
443 if (rec->evlist->mmap[i].base) {
444 if (perf_record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) {
445 rc = -1;
446 goto out;
447 }
448 }
98402807
FW
449 }
450
2eeaaa09 451 if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA))
8d3eca20
DA
452 rc = write_output(rec, &finished_round_event,
453 sizeof(finished_round_event));
454
455out:
456 return rc;
98402807
FW
457}
458
d20deb64 459static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
16c8a109 460{
abaff32a 461 struct stat st;
abaff32a 462 int flags;
781ba9d2 463 int err, output, feat;
8b412664 464 unsigned long waking = 0;
46be604b 465 const bool forks = argc > 0;
23346f21 466 struct machine *machine;
45694aa7 467 struct perf_tool *tool = &rec->tool;
d20deb64
ACM
468 struct perf_record_opts *opts = &rec->opts;
469 struct perf_evlist *evsel_list = rec->evlist;
470 const char *output_name = rec->output_name;
471 struct perf_session *session;
de9ac07b 472
d20deb64 473 rec->progname = argv[0];
33e49ea7 474
d20deb64 475 rec->page_size = sysconf(_SC_PAGE_SIZE);
de9ac07b 476
d20deb64 477 on_exit(perf_record__sig_exit, rec);
f5970550
PZ
478 signal(SIGCHLD, sig_handler);
479 signal(SIGINT, sig_handler);
18483b81 480 signal(SIGUSR1, sig_handler);
f5970550 481
d7065adb
FBH
482 if (!output_name) {
483 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
d20deb64 484 opts->pipe_output = true;
d7065adb 485 else
d20deb64 486 rec->output_name = output_name = "perf.data";
d7065adb
FBH
487 }
488 if (output_name) {
489 if (!strcmp(output_name, "-"))
d20deb64 490 opts->pipe_output = true;
d7065adb 491 else if (!stat(output_name, &st) && st.st_size) {
d20deb64 492 if (rec->write_mode == WRITE_FORCE) {
d7065adb
FBH
493 char oldname[PATH_MAX];
494 snprintf(oldname, sizeof(oldname), "%s.old",
495 output_name);
496 unlink(oldname);
497 rename(output_name, oldname);
498 }
d20deb64
ACM
499 } else if (rec->write_mode == WRITE_APPEND) {
500 rec->write_mode = WRITE_FORCE;
266e0e21 501 }
97124d5e
PZ
502 }
503
f887f301 504 flags = O_CREAT|O_RDWR;
d20deb64
ACM
505 if (rec->write_mode == WRITE_APPEND)
506 rec->file_new = 0;
abaff32a
IM
507 else
508 flags |= O_TRUNC;
509
d20deb64 510 if (opts->pipe_output)
529870e3
TZ
511 output = STDOUT_FILENO;
512 else
513 output = open(output_name, flags, S_IRUSR | S_IWUSR);
de9ac07b
PZ
514 if (output < 0) {
515 perror("failed to create output file");
8d3eca20 516 return -1;
de9ac07b
PZ
517 }
518
d20deb64
ACM
519 rec->output = output;
520
7865e817 521 session = perf_session__new(output_name, O_WRONLY,
d20deb64 522 rec->write_mode == WRITE_FORCE, false, NULL);
94c744b6 523 if (session == NULL) {
a9a70bbc
ACM
524 pr_err("Not enough memory for reading perf file header\n");
525 return -1;
526 }
527
d20deb64
ACM
528 rec->session = session;
529
781ba9d2
RR
530 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
531 perf_header__set_feat(&session->header, feat);
532
533 if (rec->no_buildid)
534 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
535
536 if (!have_tracepoints(&evsel_list->entries))
2eeaaa09 537 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
baa2f6ce 538
330aa675
SE
539 if (!rec->opts.branch_stack)
540 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
541
d20deb64 542 if (!rec->file_new) {
a91e5431 543 err = perf_session__read_header(session, output);
4dc0a04b 544 if (err < 0)
39d17dac 545 goto out_delete_session;
4dc0a04b
ACM
546 }
547
d4db3f16 548 if (forks) {
d20deb64 549 err = perf_evlist__prepare_workload(evsel_list, opts, argv);
35b9d88e
ACM
550 if (err < 0) {
551 pr_err("Couldn't run the workload!\n");
552 goto out_delete_session;
856e9660 553 }
856e9660
PZ
554 }
555
8d3eca20
DA
556 if (perf_record__open(rec) != 0) {
557 err = -1;
558 goto out_delete_session;
559 }
de9ac07b 560
712a4b60 561 /*
d20deb64 562 * perf_session__delete(session) will be called at perf_record__exit()
712a4b60 563 */
d20deb64 564 on_exit(perf_record__exit, rec);
712a4b60 565
d20deb64 566 if (opts->pipe_output) {
529870e3
TZ
567 err = perf_header__write_pipe(output);
568 if (err < 0)
8d3eca20 569 goto out_delete_session;
d20deb64 570 } else if (rec->file_new) {
a91e5431
ACM
571 err = perf_session__write_header(session, evsel_list,
572 output, false);
d5eed904 573 if (err < 0)
8d3eca20 574 goto out_delete_session;
56b03f3c
ACM
575 }
576
d3665498 577 if (!rec->no_buildid
e20960c0 578 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
d3665498 579 pr_err("Couldn't generate buildids. "
e20960c0 580 "Use --no-buildid to profile anyway.\n");
8d3eca20
DA
581 err = -1;
582 goto out_delete_session;
e20960c0
RR
583 }
584
d20deb64 585 rec->post_processing_offset = lseek(output, 0, SEEK_CUR);
6122e4e4 586
743eb868
ACM
587 machine = perf_session__find_host_machine(session);
588 if (!machine) {
589 pr_err("Couldn't find native kernel information.\n");
8d3eca20
DA
590 err = -1;
591 goto out_delete_session;
743eb868
ACM
592 }
593
d20deb64 594 if (opts->pipe_output) {
45694aa7 595 err = perf_event__synthesize_attrs(tool, session,
d20deb64 596 process_synthesized_event);
2c46dbb5
TZ
597 if (err < 0) {
598 pr_err("Couldn't synthesize attrs.\n");
8d3eca20 599 goto out_delete_session;
2c46dbb5 600 }
cd19a035 601
45694aa7 602 err = perf_event__synthesize_event_types(tool, process_synthesized_event,
743eb868 603 machine);
cd19a035
TZ
604 if (err < 0) {
605 pr_err("Couldn't synthesize event_types.\n");
8d3eca20 606 goto out_delete_session;
cd19a035 607 }
9215545e 608
361c99a6 609 if (have_tracepoints(&evsel_list->entries)) {
63e0c771
TZ
610 /*
611 * FIXME err <= 0 here actually means that
612 * there were no tracepoints so its not really
613 * an error, just that we don't need to
614 * synthesize anything. We really have to
615 * return this more properly and also
616 * propagate errors that now are calling die()
617 */
45694aa7 618 err = perf_event__synthesize_tracing_data(tool, output, evsel_list,
743eb868 619 process_synthesized_event);
63e0c771
TZ
620 if (err <= 0) {
621 pr_err("Couldn't record tracing data.\n");
8d3eca20 622 goto out_delete_session;
63e0c771 623 }
d20deb64 624 advance_output(rec, err);
63e0c771 625 }
2c46dbb5
TZ
626 }
627
45694aa7 628 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
743eb868 629 machine, "_text");
70162138 630 if (err < 0)
45694aa7 631 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
743eb868 632 machine, "_stext");
c1a3a4b9
ACM
633 if (err < 0)
634 pr_err("Couldn't record kernel reference relocation symbol\n"
635 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
636 "Check /proc/kallsyms permission or run as root.\n");
b7cece76 637
45694aa7 638 err = perf_event__synthesize_modules(tool, process_synthesized_event,
743eb868 639 machine);
c1a3a4b9
ACM
640 if (err < 0)
641 pr_err("Couldn't record kernel module information.\n"
642 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
643 "Check /proc/modules permission or run as root.\n");
644
a1645ce1 645 if (perf_guest)
45694aa7 646 perf_session__process_machines(session, tool,
8115d60c 647 perf_event__synthesize_guest_os);
7c6a1c65 648
bea03405 649 if (!opts->target.system_wide)
8d3eca20 650 err = perf_event__synthesize_thread_map(tool, evsel_list->threads,
7c940c18 651 process_synthesized_event,
743eb868 652 machine);
234fbbf5 653 else
8d3eca20 654 err = perf_event__synthesize_threads(tool, process_synthesized_event,
743eb868 655 machine);
7c6a1c65 656
8d3eca20
DA
657 if (err != 0)
658 goto out_delete_session;
659
d20deb64 660 if (rec->realtime_prio) {
de9ac07b
PZ
661 struct sched_param param;
662
d20deb64 663 param.sched_priority = rec->realtime_prio;
de9ac07b 664 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
6beba7ad 665 pr_err("Could not set realtime priority.\n");
8d3eca20
DA
666 err = -1;
667 goto out_delete_session;
de9ac07b
PZ
668 }
669 }
670
764e16a3
DA
671 perf_evlist__enable(evsel_list);
672
856e9660
PZ
673 /*
674 * Let the child rip
675 */
d4db3f16 676 if (forks)
35b9d88e 677 perf_evlist__start_workload(evsel_list);
856e9660 678
649c48a9 679 for (;;) {
d20deb64 680 int hits = rec->samples;
de9ac07b 681
8d3eca20
DA
682 if (perf_record__mmap_read_all(rec) < 0) {
683 err = -1;
684 goto out_delete_session;
685 }
de9ac07b 686
d20deb64 687 if (hits == rec->samples) {
649c48a9
PZ
688 if (done)
689 break;
5c581041 690 err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1);
8b412664
PZ
691 waking++;
692 }
693
4152ab37
ACM
694 if (done)
695 perf_evlist__disable(evsel_list);
de9ac07b
PZ
696 }
697
18483b81 698 if (quiet || signr == SIGUSR1)
b44308f5
ACM
699 return 0;
700
8b412664
PZ
701 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
702
021e9f47
IM
703 /*
704 * Approximate RIP event size: 24 bytes.
705 */
706 fprintf(stderr,
9486aa38 707 "[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64 " samples) ]\n",
d20deb64 708 (double)rec->bytes_written / 1024.0 / 1024.0,
021e9f47 709 output_name,
d20deb64 710 rec->bytes_written / 24);
addc2785 711
de9ac07b 712 return 0;
39d17dac
ACM
713
714out_delete_session:
715 perf_session__delete(session);
716 return err;
de9ac07b 717}
0e9b20b8 718
bdfebd84
RAV
719#define BRANCH_OPT(n, m) \
720 { .name = n, .mode = (m) }
721
722#define BRANCH_END { .name = NULL }
723
724struct branch_mode {
725 const char *name;
726 int mode;
727};
728
729static const struct branch_mode branch_modes[] = {
730 BRANCH_OPT("u", PERF_SAMPLE_BRANCH_USER),
731 BRANCH_OPT("k", PERF_SAMPLE_BRANCH_KERNEL),
732 BRANCH_OPT("hv", PERF_SAMPLE_BRANCH_HV),
733 BRANCH_OPT("any", PERF_SAMPLE_BRANCH_ANY),
734 BRANCH_OPT("any_call", PERF_SAMPLE_BRANCH_ANY_CALL),
735 BRANCH_OPT("any_ret", PERF_SAMPLE_BRANCH_ANY_RETURN),
736 BRANCH_OPT("ind_call", PERF_SAMPLE_BRANCH_IND_CALL),
737 BRANCH_END
738};
739
740static int
a5aabdac 741parse_branch_stack(const struct option *opt, const char *str, int unset)
bdfebd84
RAV
742{
743#define ONLY_PLM \
744 (PERF_SAMPLE_BRANCH_USER |\
745 PERF_SAMPLE_BRANCH_KERNEL |\
746 PERF_SAMPLE_BRANCH_HV)
747
748 uint64_t *mode = (uint64_t *)opt->value;
749 const struct branch_mode *br;
a5aabdac 750 char *s, *os = NULL, *p;
bdfebd84
RAV
751 int ret = -1;
752
a5aabdac
SE
753 if (unset)
754 return 0;
bdfebd84 755
a5aabdac
SE
756 /*
757 * cannot set it twice, -b + --branch-filter for instance
758 */
759 if (*mode)
bdfebd84
RAV
760 return -1;
761
a5aabdac
SE
762 /* str may be NULL in case no arg is passed to -b */
763 if (str) {
764 /* because str is read-only */
765 s = os = strdup(str);
766 if (!s)
767 return -1;
768
769 for (;;) {
770 p = strchr(s, ',');
771 if (p)
772 *p = '\0';
773
774 for (br = branch_modes; br->name; br++) {
775 if (!strcasecmp(s, br->name))
776 break;
777 }
778 if (!br->name) {
779 ui__warning("unknown branch filter %s,"
780 " check man page\n", s);
781 goto error;
782 }
bdfebd84 783
a5aabdac 784 *mode |= br->mode;
bdfebd84 785
a5aabdac
SE
786 if (!p)
787 break;
bdfebd84 788
a5aabdac
SE
789 s = p + 1;
790 }
bdfebd84
RAV
791 }
792 ret = 0;
793
a5aabdac 794 /* default to any branch */
bdfebd84 795 if ((*mode & ~ONLY_PLM) == 0) {
a5aabdac 796 *mode = PERF_SAMPLE_BRANCH_ANY;
bdfebd84
RAV
797 }
798error:
799 free(os);
800 return ret;
801}
802
95485b1c 803#ifdef LIBUNWIND_SUPPORT
26d33022
JO
804static int get_stack_size(char *str, unsigned long *_size)
805{
806 char *endptr;
807 unsigned long size;
808 unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
809
810 size = strtoul(str, &endptr, 0);
811
812 do {
813 if (*endptr)
814 break;
815
816 size = round_up(size, sizeof(u64));
817 if (!size || size > max_size)
818 break;
819
820 *_size = size;
821 return 0;
822
823 } while (0);
824
825 pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
826 max_size, str);
827 return -1;
828}
95485b1c 829#endif /* LIBUNWIND_SUPPORT */
26d33022
JO
830
831static int
1d037ca1 832parse_callchain_opt(const struct option *opt __maybe_unused, const char *arg,
26d33022
JO
833 int unset)
834{
835 struct perf_record *rec = (struct perf_record *)opt->value;
836 char *tok, *name, *saveptr = NULL;
837 char *buf;
838 int ret = -1;
839
840 /* --no-call-graph */
841 if (unset)
842 return 0;
843
844 /* We specified default option if none is provided. */
845 BUG_ON(!arg);
846
847 /* We need buffer that we know we can write to. */
848 buf = malloc(strlen(arg) + 1);
849 if (!buf)
850 return -ENOMEM;
851
852 strcpy(buf, arg);
853
854 tok = strtok_r((char *)buf, ",", &saveptr);
855 name = tok ? : (char *)buf;
856
857 do {
858 /* Framepointer style */
859 if (!strncmp(name, "fp", sizeof("fp"))) {
860 if (!strtok_r(NULL, ",", &saveptr)) {
861 rec->opts.call_graph = CALLCHAIN_FP;
862 ret = 0;
863 } else
864 pr_err("callchain: No more arguments "
865 "needed for -g fp\n");
866 break;
867
95485b1c 868#ifdef LIBUNWIND_SUPPORT
26d33022
JO
869 /* Dwarf style */
870 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
871 ret = 0;
872 rec->opts.call_graph = CALLCHAIN_DWARF;
873 rec->opts.stack_dump_size = default_stack_dump_size;
874
875 tok = strtok_r(NULL, ",", &saveptr);
876 if (tok) {
877 unsigned long size = 0;
878
879 ret = get_stack_size(tok, &size);
880 rec->opts.stack_dump_size = size;
881 }
882
883 if (!ret)
884 pr_debug("callchain: stack dump size %d\n",
885 rec->opts.stack_dump_size);
95485b1c 886#endif /* LIBUNWIND_SUPPORT */
26d33022
JO
887 } else {
888 pr_err("callchain: Unknown -g option "
889 "value: %s\n", arg);
890 break;
891 }
892
893 } while (0);
894
895 free(buf);
896
897 if (!ret)
898 pr_debug("callchain: type %d\n", rec->opts.call_graph);
899
900 return ret;
901}
902
0e9b20b8 903static const char * const record_usage[] = {
9e096753
MG
904 "perf record [<options>] [<command>]",
905 "perf record [<options>] -- <command> [<options>]",
0e9b20b8
IM
906 NULL
907};
908
d20deb64
ACM
909/*
910 * XXX Ideally would be local to cmd_record() and passed to a perf_record__new
911 * because we need to have access to it in perf_record__exit, that is called
912 * after cmd_record() exits, but since record_options need to be accessible to
913 * builtin-script, leave it here.
914 *
915 * At least we don't ouch it in all the other functions here directly.
916 *
917 * Just say no to tons of global variables, sigh.
918 */
919static struct perf_record record = {
920 .opts = {
d20deb64
ACM
921 .mmap_pages = UINT_MAX,
922 .user_freq = UINT_MAX,
923 .user_interval = ULLONG_MAX,
447a6013 924 .freq = 4000,
d1cb9fce
NK
925 .target = {
926 .uses_mmap = true,
927 },
d20deb64
ACM
928 },
929 .write_mode = WRITE_FORCE,
930 .file_new = true,
931};
7865e817 932
d20deb64
ACM
933/*
934 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
935 * with it and switch to use the library functions in perf_evlist that came
936 * from builtin-record.c, i.e. use perf_record_opts,
937 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
938 * using pipes, etc.
939 */
bca647aa 940const struct option record_options[] = {
d20deb64 941 OPT_CALLBACK('e', "event", &record.evlist, "event",
86847b62 942 "event selector. use 'perf list' to list available events",
f120f9d5 943 parse_events_option),
d20deb64 944 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
c171b552 945 "event filter", parse_filter),
bea03405 946 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
d6d901c2 947 "record events on existing process id"),
bea03405 948 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
d6d901c2 949 "record events on existing thread id"),
d20deb64 950 OPT_INTEGER('r', "realtime", &record.realtime_prio,
0e9b20b8 951 "collect data with this RT SCHED_FIFO priority"),
d20deb64 952 OPT_BOOLEAN('D', "no-delay", &record.opts.no_delay,
acac03fa 953 "collect data without buffering"),
d20deb64 954 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
daac07b2 955 "collect raw sample records from all opened counters"),
bea03405 956 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
0e9b20b8 957 "system-wide collection from all CPUs"),
d20deb64 958 OPT_BOOLEAN('A', "append", &record.append_file,
abaff32a 959 "append to the output file to do incremental profiling"),
bea03405 960 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
c45c6ea2 961 "list of cpus to monitor"),
d20deb64 962 OPT_BOOLEAN('f', "force", &record.force,
7865e817 963 "overwrite existing data file (deprecated)"),
d20deb64
ACM
964 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
965 OPT_STRING('o', "output", &record.output_name, "file",
abaff32a 966 "output file name"),
d20deb64 967 OPT_BOOLEAN('i', "no-inherit", &record.opts.no_inherit,
2e6cdf99 968 "child tasks do not inherit counters"),
d20deb64
ACM
969 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
970 OPT_UINTEGER('m', "mmap-pages", &record.opts.mmap_pages,
01c2d99b 971 "number of mmap data pages"),
d20deb64 972 OPT_BOOLEAN(0, "group", &record.opts.group,
43bece79 973 "put the counters into a counter group"),
26d33022
JO
974 OPT_CALLBACK_DEFAULT('g', "call-graph", &record, "mode[,dump_size]",
975 callchain_help, &parse_callchain_opt,
976 "fp"),
c0555642 977 OPT_INCR('v', "verbose", &verbose,
3da297a6 978 "be more verbose (show counter open errors, etc)"),
b44308f5 979 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
d20deb64 980 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
649c48a9 981 "per thread counts"),
d20deb64 982 OPT_BOOLEAN('d', "data", &record.opts.sample_address,
4bba828d 983 "Sample addresses"),
d20deb64 984 OPT_BOOLEAN('T', "timestamp", &record.opts.sample_time, "Sample timestamps"),
3e76ac78 985 OPT_BOOLEAN('P', "period", &record.opts.period, "Sample period"),
d20deb64 986 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
649c48a9 987 "don't sample"),
d20deb64 988 OPT_BOOLEAN('N', "no-buildid-cache", &record.no_buildid_cache,
a1ac1d3c 989 "do not update the buildid cache"),
d20deb64 990 OPT_BOOLEAN('B', "no-buildid", &record.no_buildid,
baa2f6ce 991 "do not collect buildids in perf.data"),
d20deb64 992 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
023695d9
SE
993 "monitor event in cgroup name only",
994 parse_cgroups),
bea03405
NK
995 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
996 "user to profile"),
a5aabdac
SE
997
998 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
999 "branch any", "sample any taken branches",
1000 parse_branch_stack),
1001
1002 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
1003 "branch filter mask", "branch stack filter modes",
bdfebd84 1004 parse_branch_stack),
0e9b20b8
IM
1005 OPT_END()
1006};
1007
1d037ca1 1008int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
0e9b20b8 1009{
69aad6f1
ACM
1010 int err = -ENOMEM;
1011 struct perf_evsel *pos;
d20deb64
ACM
1012 struct perf_evlist *evsel_list;
1013 struct perf_record *rec = &record;
16ad2ffb 1014 char errbuf[BUFSIZ];
0e9b20b8 1015
7e2ed097 1016 evsel_list = perf_evlist__new(NULL, NULL);
361c99a6
ACM
1017 if (evsel_list == NULL)
1018 return -ENOMEM;
1019
d20deb64
ACM
1020 rec->evlist = evsel_list;
1021
bca647aa 1022 argc = parse_options(argc, argv, record_options, record_usage,
655000e7 1023 PARSE_OPT_STOP_AT_NON_OPTION);
d67356e7 1024 if (!argc && perf_target__none(&rec->opts.target))
bca647aa 1025 usage_with_options(record_usage, record_options);
0e9b20b8 1026
d20deb64 1027 if (rec->force && rec->append_file) {
3780f488
NK
1028 ui__error("Can't overwrite and append at the same time."
1029 " You need to choose between -f and -A");
bca647aa 1030 usage_with_options(record_usage, record_options);
d20deb64
ACM
1031 } else if (rec->append_file) {
1032 rec->write_mode = WRITE_APPEND;
7865e817 1033 } else {
d20deb64 1034 rec->write_mode = WRITE_FORCE;
7865e817
FW
1035 }
1036
bea03405 1037 if (nr_cgroups && !rec->opts.target.system_wide) {
3780f488
NK
1038 ui__error("cgroup monitoring only available in"
1039 " system-wide mode\n");
023695d9
SE
1040 usage_with_options(record_usage, record_options);
1041 }
1042
655000e7 1043 symbol__init();
baa2f6ce 1044
ec80fde7 1045 if (symbol_conf.kptr_restrict)
646aaea6
ACM
1046 pr_warning(
1047"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
1048"check /proc/sys/kernel/kptr_restrict.\n\n"
1049"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
1050"file is not found in the buildid cache or in the vmlinux path.\n\n"
1051"Samples in kernel modules won't be resolved at all.\n\n"
1052"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
1053"even with a suitable vmlinux or kallsyms file.\n\n");
ec80fde7 1054
d20deb64 1055 if (rec->no_buildid_cache || rec->no_buildid)
a1ac1d3c 1056 disable_buildid_cache();
655000e7 1057
361c99a6
ACM
1058 if (evsel_list->nr_entries == 0 &&
1059 perf_evlist__add_default(evsel_list) < 0) {
69aad6f1
ACM
1060 pr_err("Not enough memory for event selector list\n");
1061 goto out_symbol_exit;
bbd36e5e 1062 }
0e9b20b8 1063
16ad2ffb
NK
1064 err = perf_target__validate(&rec->opts.target);
1065 if (err) {
1066 perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
1067 ui__warning("%s", errbuf);
1068 }
1069
1070 err = perf_target__parse_uid(&rec->opts.target);
1071 if (err) {
1072 int saved_errno = errno;
4bd0f2d2 1073
16ad2ffb 1074 perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
3780f488 1075 ui__error("%s", errbuf);
16ad2ffb
NK
1076
1077 err = -saved_errno;
0d37aa34 1078 goto out_free_fd;
16ad2ffb 1079 }
0d37aa34 1080
16ad2ffb 1081 err = -ENOMEM;
b809ac10 1082 if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
dd7927f4 1083 usage_with_options(record_usage, record_options);
69aad6f1 1084
361c99a6 1085 list_for_each_entry(pos, &evsel_list->entries, node) {
7289f83c 1086 if (perf_header__push_event(pos->attr.config, perf_evsel__name(pos)))
ad7f4e3f 1087 goto out_free_fd;
d6d901c2 1088 }
5c581041 1089
d20deb64
ACM
1090 if (rec->opts.user_interval != ULLONG_MAX)
1091 rec->opts.default_interval = rec->opts.user_interval;
1092 if (rec->opts.user_freq != UINT_MAX)
1093 rec->opts.freq = rec->opts.user_freq;
f9212819 1094
7e4ff9e3
MG
1095 /*
1096 * User specified count overrides default frequency.
1097 */
d20deb64
ACM
1098 if (rec->opts.default_interval)
1099 rec->opts.freq = 0;
1100 else if (rec->opts.freq) {
1101 rec->opts.default_interval = rec->opts.freq;
7e4ff9e3 1102 } else {
3780f488 1103 ui__error("frequency and count are zero, aborting\n");
39d17dac 1104 err = -EINVAL;
5c581041 1105 goto out_free_fd;
7e4ff9e3
MG
1106 }
1107
d20deb64 1108 err = __cmd_record(&record, argc, argv);
39d17dac 1109out_free_fd:
7e2ed097 1110 perf_evlist__delete_maps(evsel_list);
d65a458b
ACM
1111out_symbol_exit:
1112 symbol__exit();
39d17dac 1113 return err;
0e9b20b8 1114}
This page took 0.187629 seconds and 5 git commands to generate.