perf trace: Don't relookup fields by name in each sample
[linux-2.6-block.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 */
16f762a2 8#include "builtin.h"
bf9e1876
IM
9
10#include "perf.h"
11
6122e4e4 12#include "util/build-id.h"
6eda5838 13#include "util/util.h"
0e9b20b8 14#include "util/parse-options.h"
8ad8db37 15#include "util/parse-events.h"
6eda5838 16
7c6a1c65 17#include "util/header.h"
66e274f3 18#include "util/event.h"
361c99a6 19#include "util/evlist.h"
69aad6f1 20#include "util/evsel.h"
8f28827a 21#include "util/debug.h"
94c744b6 22#include "util/session.h"
45694aa7 23#include "util/tool.h"
8d06367f 24#include "util/symbol.h"
a12b51c4 25#include "util/cpumap.h"
fd78260b 26#include "util/thread_map.h"
f5fc1412 27#include "util/data.h"
7c6a1c65 28
97124d5e 29#include <unistd.h>
de9ac07b 30#include <sched.h>
a41794cd 31#include <sys/mman.h>
de9ac07b 32
89fe808a 33#ifndef HAVE_ON_EXIT_SUPPORT
78da39fa
BR
34#ifndef ATEXIT_MAX
35#define ATEXIT_MAX 32
36#endif
37static int __on_exit_count = 0;
38typedef void (*on_exit_func_t) (int, void *);
39static on_exit_func_t __on_exit_funcs[ATEXIT_MAX];
40static void *__on_exit_args[ATEXIT_MAX];
41static int __exitcode = 0;
42static void __handle_on_exit_funcs(void);
43static int on_exit(on_exit_func_t function, void *arg);
44#define exit(x) (exit)(__exitcode = (x))
45
46static 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
57static 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
d20deb64 65struct perf_record {
45694aa7 66 struct perf_tool tool;
d20deb64
ACM
67 struct perf_record_opts opts;
68 u64 bytes_written;
f5fc1412 69 struct perf_data_file file;
d20deb64
ACM
70 struct perf_evlist *evlist;
71 struct perf_session *session;
72 const char *progname;
d20deb64 73 int realtime_prio;
d20deb64
ACM
74 bool no_buildid;
75 bool no_buildid_cache;
d20deb64
ACM
76 long samples;
77 off_t post_processing_offset;
0f82ebc4 78};
a21ca2ca 79
d20deb64 80static void advance_output(struct perf_record *rec, size_t size)
9215545e 81{
d20deb64 82 rec->bytes_written += size;
9215545e
TZ
83}
84
8d3eca20 85static int write_output(struct perf_record *rec, void *buf, size_t size)
f5970550 86{
f5fc1412
JO
87 struct perf_data_file *file = &rec->file;
88
f5970550 89 while (size) {
f5fc1412 90 int ret = write(file->fd, buf, size);
f5970550 91
8d3eca20 92 if (ret < 0) {
4f624685 93 pr_err("failed to write perf data, error: %m\n");
8d3eca20
DA
94 return -1;
95 }
f5970550
PZ
96
97 size -= ret;
98 buf += ret;
99
d20deb64 100 rec->bytes_written += ret;
f5970550 101 }
8d3eca20
DA
102
103 return 0;
f5970550
PZ
104}
105
45694aa7 106static int process_synthesized_event(struct perf_tool *tool,
d20deb64 107 union perf_event *event,
1d037ca1
IT
108 struct perf_sample *sample __maybe_unused,
109 struct machine *machine __maybe_unused)
234fbbf5 110{
45694aa7 111 struct perf_record *rec = container_of(tool, struct perf_record, tool);
8d3eca20
DA
112 if (write_output(rec, event, event->header.size) < 0)
113 return -1;
114
234fbbf5
ACM
115 return 0;
116}
117
8d3eca20 118static int perf_record__mmap_read(struct perf_record *rec,
d20deb64 119 struct perf_mmap *md)
de9ac07b 120{
744bd8aa 121 unsigned int head = perf_mmap__read_head(md);
de9ac07b 122 unsigned int old = md->prev;
918512b4 123 unsigned char *data = md->base + page_size;
de9ac07b
PZ
124 unsigned long size;
125 void *buf;
8d3eca20 126 int rc = 0;
de9ac07b 127
dc82009a 128 if (old == head)
8d3eca20 129 return 0;
dc82009a 130
d20deb64 131 rec->samples++;
de9ac07b
PZ
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;
021e9f47 139
8d3eca20
DA
140 if (write_output(rec, buf, size) < 0) {
141 rc = -1;
142 goto out;
143 }
de9ac07b
PZ
144 }
145
146 buf = &data[old & md->mask];
147 size = head - old;
148 old += size;
021e9f47 149
8d3eca20
DA
150 if (write_output(rec, buf, size) < 0) {
151 rc = -1;
152 goto out;
153 }
de9ac07b
PZ
154
155 md->prev = old;
115d2d89 156 perf_mmap__write_tail(md, old);
8d3eca20
DA
157
158out:
159 return rc;
de9ac07b
PZ
160}
161
162static volatile int done = 0;
f7b7c26e 163static volatile int signr = -1;
33e49ea7 164static volatile int child_finished = 0;
de9ac07b 165
16c8a109 166static void sig_handler(int sig)
de9ac07b 167{
33e49ea7
AK
168 if (sig == SIGCHLD)
169 child_finished = 1;
170
16c8a109 171 done = 1;
f7b7c26e
PZ
172 signr = sig;
173}
174
1d037ca1 175static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
f7b7c26e 176{
d20deb64 177 struct perf_record *rec = arg;
33e49ea7
AK
178 int status;
179
d20deb64 180 if (rec->evlist->workload.pid > 0) {
33e49ea7 181 if (!child_finished)
d20deb64 182 kill(rec->evlist->workload.pid, SIGTERM);
33e49ea7
AK
183
184 wait(&status);
185 if (WIFSIGNALED(status))
d20deb64 186 psignal(WTERMSIG(status), rec->progname);
33e49ea7 187 }
933da83a 188
18483b81 189 if (signr == -1 || signr == SIGUSR1)
f7b7c26e
PZ
190 return;
191
192 signal(signr, SIG_DFL);
de9ac07b
PZ
193}
194
8d3eca20 195static int perf_record__open(struct perf_record *rec)
dd7927f4 196{
56e52e85 197 char msg[512];
6a4bb04c 198 struct perf_evsel *pos;
d20deb64
ACM
199 struct perf_evlist *evlist = rec->evlist;
200 struct perf_session *session = rec->session;
201 struct perf_record_opts *opts = &rec->opts;
8d3eca20 202 int rc = 0;
dd7927f4 203
f77a9518 204 perf_evlist__config(evlist, opts);
cac21425 205
dd7927f4 206 list_for_each_entry(pos, &evlist->entries, node) {
dd7927f4 207try_again:
6a4bb04c 208 if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) {
56e52e85 209 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
d6d901c2 210 if (verbose)
c0a54341 211 ui__warning("%s\n", msg);
d6d901c2
ZY
212 goto try_again;
213 }
ca6a4258 214
56e52e85
ACM
215 rc = -errno;
216 perf_evsel__open_strerror(pos, &opts->target,
217 errno, msg, sizeof(msg));
218 ui__error("%s\n", msg);
8d3eca20 219 goto out;
c171b552
LZ
220 }
221 }
a43d3f08 222
1491a632 223 if (perf_evlist__apply_filters(evlist)) {
0a102479
FW
224 error("failed to set filter with %d (%s)\n", errno,
225 strerror(errno));
8d3eca20
DA
226 rc = -1;
227 goto out;
0a102479
FW
228 }
229
18e60939 230 if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) {
8d3eca20
DA
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;
8d3eca20
DA
238 } else {
239 pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno));
240 rc = -errno;
241 }
242 goto out;
18e60939 243 }
0a27d7f9 244
563aecb2 245 session->evlist = evlist;
7b56cce2 246 perf_session__set_id_hdr_size(session);
8d3eca20
DA
247out:
248 return rc;
16c8a109
PZ
249}
250
d20deb64 251static int process_buildids(struct perf_record *rec)
6122e4e4 252{
f5fc1412
JO
253 struct perf_data_file *file = &rec->file;
254 struct perf_session *session = rec->session;
6122e4e4 255
f5fc1412 256 u64 size = lseek(file->fd, 0, SEEK_CUR);
9f591fd7
ACM
257 if (size == 0)
258 return 0;
259
f5fc1412 260 return __perf_session__process_events(session, rec->post_processing_offset,
d20deb64 261 size - rec->post_processing_offset,
6122e4e4
ACM
262 size, &build_id__mark_dso_hit_ops);
263}
264
8d3eca20 265static void perf_record__exit(int status, void *arg)
f5970550 266{
d20deb64 267 struct perf_record *rec = arg;
f5fc1412 268 struct perf_data_file *file = &rec->file;
d20deb64 269
8d3eca20
DA
270 if (status != 0)
271 return;
272
f5fc1412 273 if (!file->is_pipe) {
d20deb64
ACM
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,
f5fc1412 279 file->fd, true);
d20deb64
ACM
280 perf_session__delete(rec->session);
281 perf_evlist__delete(rec->evlist);
d65a458b 282 symbol__exit();
c7929e47 283 }
f5970550
PZ
284}
285
8115d60c 286static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
a1645ce1
ZY
287{
288 int err;
45694aa7 289 struct perf_tool *tool = data;
a1645ce1
ZY
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 */
45694aa7 298 err = perf_event__synthesize_modules(tool, process_synthesized_event,
743eb868 299 machine);
a1645ce1
ZY
300 if (err < 0)
301 pr_err("Couldn't record guest kernel [%d]'s reference"
23346f21 302 " relocation symbol.\n", machine->pid);
a1645ce1 303
a1645ce1
ZY
304 /*
305 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
306 * have no _text sometimes.
307 */
45694aa7 308 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
743eb868 309 machine, "_text");
a1645ce1 310 if (err < 0)
45694aa7 311 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
743eb868 312 machine, "_stext");
a1645ce1
ZY
313 if (err < 0)
314 pr_err("Couldn't record guest kernel [%d]'s reference"
23346f21 315 " relocation symbol.\n", machine->pid);
a1645ce1
ZY
316}
317
98402807
FW
318static struct perf_event_header finished_round_event = {
319 .size = sizeof(struct perf_event_header),
320 .type = PERF_RECORD_FINISHED_ROUND,
321};
322
8d3eca20 323static int perf_record__mmap_read_all(struct perf_record *rec)
98402807 324{
0e2e63dd 325 int i;
8d3eca20 326 int rc = 0;
98402807 327
d20deb64 328 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
8d3eca20
DA
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 }
98402807
FW
335 }
336
2eeaaa09 337 if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA))
8d3eca20
DA
338 rc = write_output(rec, &finished_round_event,
339 sizeof(finished_round_event));
340
341out:
342 return rc;
98402807
FW
343}
344
d20deb64 345static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
16c8a109 346{
f5fc1412 347 int err, feat;
8b412664 348 unsigned long waking = 0;
46be604b 349 const bool forks = argc > 0;
23346f21 350 struct machine *machine;
45694aa7 351 struct perf_tool *tool = &rec->tool;
d20deb64
ACM
352 struct perf_record_opts *opts = &rec->opts;
353 struct perf_evlist *evsel_list = rec->evlist;
f5fc1412 354 struct perf_data_file *file = &rec->file;
d20deb64 355 struct perf_session *session;
2711926a 356 bool disabled = false;
de9ac07b 357
d20deb64 358 rec->progname = argv[0];
33e49ea7 359
d20deb64 360 on_exit(perf_record__sig_exit, rec);
f5970550
PZ
361 signal(SIGCHLD, sig_handler);
362 signal(SIGINT, sig_handler);
18483b81 363 signal(SIGUSR1, sig_handler);
804f7ac7 364 signal(SIGTERM, sig_handler);
f5970550 365
f5fc1412 366 session = perf_session__new(file, false, NULL);
94c744b6 367 if (session == NULL) {
a9a70bbc
ACM
368 pr_err("Not enough memory for reading perf file header\n");
369 return -1;
370 }
371
d20deb64
ACM
372 rec->session = session;
373
781ba9d2
RR
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))
2eeaaa09 381 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
baa2f6ce 382
330aa675
SE
383 if (!rec->opts.branch_stack)
384 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
385
d4db3f16 386 if (forks) {
6ef73ec4 387 err = perf_evlist__prepare_workload(evsel_list, &opts->target,
f5fc1412 388 argv, file->is_pipe,
55e162ea 389 true);
35b9d88e
ACM
390 if (err < 0) {
391 pr_err("Couldn't run the workload!\n");
392 goto out_delete_session;
856e9660 393 }
856e9660
PZ
394 }
395
8d3eca20
DA
396 if (perf_record__open(rec) != 0) {
397 err = -1;
398 goto out_delete_session;
399 }
de9ac07b 400
a8bb559b
NK
401 if (!evsel_list->nr_groups)
402 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
403
712a4b60 404 /*
d20deb64 405 * perf_session__delete(session) will be called at perf_record__exit()
712a4b60 406 */
d20deb64 407 on_exit(perf_record__exit, rec);
712a4b60 408
f5fc1412
JO
409 if (file->is_pipe) {
410 err = perf_header__write_pipe(file->fd);
529870e3 411 if (err < 0)
8d3eca20 412 goto out_delete_session;
563aecb2 413 } else {
a91e5431 414 err = perf_session__write_header(session, evsel_list,
f5fc1412 415 file->fd, false);
d5eed904 416 if (err < 0)
8d3eca20 417 goto out_delete_session;
56b03f3c
ACM
418 }
419
d3665498 420 if (!rec->no_buildid
e20960c0 421 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
d3665498 422 pr_err("Couldn't generate buildids. "
e20960c0 423 "Use --no-buildid to profile anyway.\n");
8d3eca20
DA
424 err = -1;
425 goto out_delete_session;
e20960c0
RR
426 }
427
f5fc1412 428 rec->post_processing_offset = lseek(file->fd, 0, SEEK_CUR);
6122e4e4 429
34ba5122 430 machine = &session->machines.host;
743eb868 431
f5fc1412 432 if (file->is_pipe) {
45694aa7 433 err = perf_event__synthesize_attrs(tool, session,
d20deb64 434 process_synthesized_event);
2c46dbb5
TZ
435 if (err < 0) {
436 pr_err("Couldn't synthesize attrs.\n");
8d3eca20 437 goto out_delete_session;
2c46dbb5 438 }
cd19a035 439
361c99a6 440 if (have_tracepoints(&evsel_list->entries)) {
63e0c771
TZ
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 */
f5fc1412 449 err = perf_event__synthesize_tracing_data(tool, file->fd, evsel_list,
743eb868 450 process_synthesized_event);
63e0c771
TZ
451 if (err <= 0) {
452 pr_err("Couldn't record tracing data.\n");
8d3eca20 453 goto out_delete_session;
63e0c771 454 }
d20deb64 455 advance_output(rec, err);
63e0c771 456 }
2c46dbb5
TZ
457 }
458
45694aa7 459 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
743eb868 460 machine, "_text");
70162138 461 if (err < 0)
45694aa7 462 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
743eb868 463 machine, "_stext");
c1a3a4b9
ACM
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");
b7cece76 468
45694aa7 469 err = perf_event__synthesize_modules(tool, process_synthesized_event,
743eb868 470 machine);
c1a3a4b9
ACM
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
7e383de4 476 if (perf_guest) {
876650e6
ACM
477 machines__process_guests(&session->machines,
478 perf_event__synthesize_guest_os, tool);
7e383de4 479 }
7c6a1c65 480
e4dd45fe 481 if (perf_target__has_task(&opts->target))
8d3eca20 482 err = perf_event__synthesize_thread_map(tool, evsel_list->threads,
7c940c18 483 process_synthesized_event,
743eb868 484 machine);
e4dd45fe 485 else if (perf_target__has_cpu(&opts->target))
8d3eca20 486 err = perf_event__synthesize_threads(tool, process_synthesized_event,
743eb868 487 machine);
e4dd45fe
JO
488 else /* command specified */
489 err = 0;
7c6a1c65 490
8d3eca20
DA
491 if (err != 0)
492 goto out_delete_session;
493
d20deb64 494 if (rec->realtime_prio) {
de9ac07b
PZ
495 struct sched_param param;
496
d20deb64 497 param.sched_priority = rec->realtime_prio;
de9ac07b 498 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
6beba7ad 499 pr_err("Could not set realtime priority.\n");
8d3eca20
DA
500 err = -1;
501 goto out_delete_session;
de9ac07b
PZ
502 }
503 }
504
774cb499
JO
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);
764e16a3 512
856e9660
PZ
513 /*
514 * Let the child rip
515 */
d4db3f16 516 if (forks)
35b9d88e 517 perf_evlist__start_workload(evsel_list);
856e9660 518
649c48a9 519 for (;;) {
d20deb64 520 int hits = rec->samples;
de9ac07b 521
8d3eca20
DA
522 if (perf_record__mmap_read_all(rec) < 0) {
523 err = -1;
524 goto out_delete_session;
525 }
de9ac07b 526
d20deb64 527 if (hits == rec->samples) {
649c48a9
PZ
528 if (done)
529 break;
5c581041 530 err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1);
8b412664
PZ
531 waking++;
532 }
533
774cb499
JO
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 */
2711926a 539 if (done && !disabled && !perf_target__none(&opts->target)) {
4152ab37 540 perf_evlist__disable(evsel_list);
2711926a
JO
541 disabled = true;
542 }
de9ac07b
PZ
543 }
544
18483b81 545 if (quiet || signr == SIGUSR1)
b44308f5
ACM
546 return 0;
547
8b412664
PZ
548 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
549
021e9f47
IM
550 /*
551 * Approximate RIP event size: 24 bytes.
552 */
553 fprintf(stderr,
9486aa38 554 "[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64 " samples) ]\n",
d20deb64 555 (double)rec->bytes_written / 1024.0 / 1024.0,
6a4d98d7 556 file->path,
d20deb64 557 rec->bytes_written / 24);
addc2785 558
de9ac07b 559 return 0;
39d17dac
ACM
560
561out_delete_session:
562 perf_session__delete(session);
563 return err;
de9ac07b 564}
0e9b20b8 565
bdfebd84
RAV
566#define BRANCH_OPT(n, m) \
567 { .name = n, .mode = (m) }
568
569#define BRANCH_END { .name = NULL }
570
571struct branch_mode {
572 const char *name;
573 int mode;
574};
575
576static 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),
0126d493
AK
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),
bdfebd84
RAV
587 BRANCH_END
588};
589
590static int
a5aabdac 591parse_branch_stack(const struct option *opt, const char *str, int unset)
bdfebd84
RAV
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;
a5aabdac 600 char *s, *os = NULL, *p;
bdfebd84
RAV
601 int ret = -1;
602
a5aabdac
SE
603 if (unset)
604 return 0;
bdfebd84 605
a5aabdac
SE
606 /*
607 * cannot set it twice, -b + --branch-filter for instance
608 */
609 if (*mode)
bdfebd84
RAV
610 return -1;
611
a5aabdac
SE
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 }
bdfebd84 633
a5aabdac 634 *mode |= br->mode;
bdfebd84 635
a5aabdac
SE
636 if (!p)
637 break;
bdfebd84 638
a5aabdac
SE
639 s = p + 1;
640 }
bdfebd84
RAV
641 }
642 ret = 0;
643
a5aabdac 644 /* default to any branch */
bdfebd84 645 if ((*mode & ~ONLY_PLM) == 0) {
a5aabdac 646 *mode = PERF_SAMPLE_BRANCH_ANY;
bdfebd84
RAV
647 }
648error:
649 free(os);
650 return ret;
651}
652
89fe808a 653#ifdef HAVE_LIBUNWIND_SUPPORT
26d33022
JO
654static 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}
89fe808a 679#endif /* HAVE_LIBUNWIND_SUPPORT */
26d33022 680
09b0fd45 681int record_parse_callchain(const char *arg, struct perf_record_opts *opts)
26d33022 682{
26d33022
JO
683 char *tok, *name, *saveptr = NULL;
684 char *buf;
685 int ret = -1;
686
26d33022
JO
687 /* We need buffer that we know we can write to. */
688 buf = malloc(strlen(arg) + 1);
689 if (!buf)
690 return -ENOMEM;
691
692 strcpy(buf, arg);
693
694 tok = strtok_r((char *)buf, ",", &saveptr);
695 name = tok ? : (char *)buf;
696
697 do {
698 /* Framepointer style */
699 if (!strncmp(name, "fp", sizeof("fp"))) {
700 if (!strtok_r(NULL, ",", &saveptr)) {
c5ff78c3 701 opts->call_graph = CALLCHAIN_FP;
26d33022
JO
702 ret = 0;
703 } else
704 pr_err("callchain: No more arguments "
705 "needed for -g fp\n");
706 break;
707
89fe808a 708#ifdef HAVE_LIBUNWIND_SUPPORT
26d33022
JO
709 /* Dwarf style */
710 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
61eaa3be
ACM
711 const unsigned long default_stack_dump_size = 8192;
712
26d33022 713 ret = 0;
c5ff78c3
ACM
714 opts->call_graph = CALLCHAIN_DWARF;
715 opts->stack_dump_size = default_stack_dump_size;
26d33022
JO
716
717 tok = strtok_r(NULL, ",", &saveptr);
718 if (tok) {
719 unsigned long size = 0;
720
721 ret = get_stack_size(tok, &size);
c5ff78c3 722 opts->stack_dump_size = size;
26d33022 723 }
89fe808a 724#endif /* HAVE_LIBUNWIND_SUPPORT */
26d33022 725 } else {
09b0fd45 726 pr_err("callchain: Unknown --call-graph option "
26d33022
JO
727 "value: %s\n", arg);
728 break;
729 }
730
731 } while (0);
732
733 free(buf);
09b0fd45
JO
734 return ret;
735}
736
737static void callchain_debug(struct perf_record_opts *opts)
738{
739 pr_debug("callchain: type %d\n", opts->call_graph);
26d33022 740
09b0fd45
JO
741 if (opts->call_graph == CALLCHAIN_DWARF)
742 pr_debug("callchain: stack dump size %d\n",
743 opts->stack_dump_size);
744}
745
746int record_parse_callchain_opt(const struct option *opt,
747 const char *arg,
748 int unset)
749{
750 struct perf_record_opts *opts = opt->value;
751 int ret;
752
753 /* --no-call-graph */
754 if (unset) {
755 opts->call_graph = CALLCHAIN_NONE;
756 pr_debug("callchain: disabled\n");
757 return 0;
758 }
759
760 ret = record_parse_callchain(arg, opts);
26d33022 761 if (!ret)
09b0fd45 762 callchain_debug(opts);
26d33022
JO
763
764 return ret;
765}
766
09b0fd45
JO
767int record_callchain_opt(const struct option *opt,
768 const char *arg __maybe_unused,
769 int unset __maybe_unused)
770{
771 struct perf_record_opts *opts = opt->value;
772
773 if (opts->call_graph == CALLCHAIN_NONE)
774 opts->call_graph = CALLCHAIN_FP;
775
776 callchain_debug(opts);
777 return 0;
778}
779
0e9b20b8 780static const char * const record_usage[] = {
9e096753
MG
781 "perf record [<options>] [<command>]",
782 "perf record [<options>] -- <command> [<options>]",
0e9b20b8
IM
783 NULL
784};
785
d20deb64
ACM
786/*
787 * XXX Ideally would be local to cmd_record() and passed to a perf_record__new
788 * because we need to have access to it in perf_record__exit, that is called
789 * after cmd_record() exits, but since record_options need to be accessible to
790 * builtin-script, leave it here.
791 *
792 * At least we don't ouch it in all the other functions here directly.
793 *
794 * Just say no to tons of global variables, sigh.
795 */
796static struct perf_record record = {
797 .opts = {
d20deb64
ACM
798 .mmap_pages = UINT_MAX,
799 .user_freq = UINT_MAX,
800 .user_interval = ULLONG_MAX,
447a6013 801 .freq = 4000,
d1cb9fce
NK
802 .target = {
803 .uses_mmap = true,
804 },
d20deb64 805 },
d20deb64 806};
7865e817 807
09b0fd45 808#define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace) recording: "
61eaa3be 809
89fe808a 810#ifdef HAVE_LIBUNWIND_SUPPORT
09b0fd45 811const char record_callchain_help[] = CALLCHAIN_HELP "fp dwarf";
61eaa3be 812#else
09b0fd45 813const char record_callchain_help[] = CALLCHAIN_HELP "fp";
61eaa3be
ACM
814#endif
815
d20deb64
ACM
816/*
817 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
818 * with it and switch to use the library functions in perf_evlist that came
819 * from builtin-record.c, i.e. use perf_record_opts,
820 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
821 * using pipes, etc.
822 */
bca647aa 823const struct option record_options[] = {
d20deb64 824 OPT_CALLBACK('e', "event", &record.evlist, "event",
86847b62 825 "event selector. use 'perf list' to list available events",
f120f9d5 826 parse_events_option),
d20deb64 827 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
c171b552 828 "event filter", parse_filter),
bea03405 829 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
d6d901c2 830 "record events on existing process id"),
bea03405 831 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
d6d901c2 832 "record events on existing thread id"),
d20deb64 833 OPT_INTEGER('r', "realtime", &record.realtime_prio,
0e9b20b8 834 "collect data with this RT SCHED_FIFO priority"),
d20deb64 835 OPT_BOOLEAN('D', "no-delay", &record.opts.no_delay,
acac03fa 836 "collect data without buffering"),
d20deb64 837 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
daac07b2 838 "collect raw sample records from all opened counters"),
bea03405 839 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
0e9b20b8 840 "system-wide collection from all CPUs"),
bea03405 841 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
c45c6ea2 842 "list of cpus to monitor"),
d20deb64 843 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
f5fc1412 844 OPT_STRING('o', "output", &record.file.path, "file",
abaff32a 845 "output file name"),
d20deb64 846 OPT_BOOLEAN('i', "no-inherit", &record.opts.no_inherit,
2e6cdf99 847 "child tasks do not inherit counters"),
d20deb64 848 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
994a1f78
JO
849 OPT_CALLBACK('m', "mmap-pages", &record.opts.mmap_pages, "pages",
850 "number of mmap data pages",
851 perf_evlist__parse_mmap_pages),
d20deb64 852 OPT_BOOLEAN(0, "group", &record.opts.group,
43bece79 853 "put the counters into a counter group"),
09b0fd45
JO
854 OPT_CALLBACK_NOOPT('g', NULL, &record.opts,
855 NULL, "enables call-graph recording" ,
856 &record_callchain_opt),
857 OPT_CALLBACK(0, "call-graph", &record.opts,
858 "mode[,dump_size]", record_callchain_help,
859 &record_parse_callchain_opt),
c0555642 860 OPT_INCR('v', "verbose", &verbose,
3da297a6 861 "be more verbose (show counter open errors, etc)"),
b44308f5 862 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
d20deb64 863 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
649c48a9 864 "per thread counts"),
d20deb64 865 OPT_BOOLEAN('d', "data", &record.opts.sample_address,
4bba828d 866 "Sample addresses"),
d20deb64 867 OPT_BOOLEAN('T', "timestamp", &record.opts.sample_time, "Sample timestamps"),
3e76ac78 868 OPT_BOOLEAN('P', "period", &record.opts.period, "Sample period"),
d20deb64 869 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
649c48a9 870 "don't sample"),
d20deb64 871 OPT_BOOLEAN('N', "no-buildid-cache", &record.no_buildid_cache,
a1ac1d3c 872 "do not update the buildid cache"),
d20deb64 873 OPT_BOOLEAN('B', "no-buildid", &record.no_buildid,
baa2f6ce 874 "do not collect buildids in perf.data"),
d20deb64 875 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
023695d9
SE
876 "monitor event in cgroup name only",
877 parse_cgroups),
bea03405
NK
878 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
879 "user to profile"),
a5aabdac
SE
880
881 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
882 "branch any", "sample any taken branches",
883 parse_branch_stack),
884
885 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
886 "branch filter mask", "branch stack filter modes",
bdfebd84 887 parse_branch_stack),
05484298
AK
888 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
889 "sample by weight (on special events only)"),
475eeab9
AK
890 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
891 "sample transaction flags (special events only)"),
0e9b20b8
IM
892 OPT_END()
893};
894
1d037ca1 895int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
0e9b20b8 896{
69aad6f1 897 int err = -ENOMEM;
d20deb64
ACM
898 struct perf_evlist *evsel_list;
899 struct perf_record *rec = &record;
16ad2ffb 900 char errbuf[BUFSIZ];
0e9b20b8 901
334fe7a3 902 evsel_list = perf_evlist__new();
361c99a6
ACM
903 if (evsel_list == NULL)
904 return -ENOMEM;
905
d20deb64
ACM
906 rec->evlist = evsel_list;
907
bca647aa 908 argc = parse_options(argc, argv, record_options, record_usage,
655000e7 909 PARSE_OPT_STOP_AT_NON_OPTION);
d67356e7 910 if (!argc && perf_target__none(&rec->opts.target))
bca647aa 911 usage_with_options(record_usage, record_options);
0e9b20b8 912
bea03405 913 if (nr_cgroups && !rec->opts.target.system_wide) {
3780f488
NK
914 ui__error("cgroup monitoring only available in"
915 " system-wide mode\n");
023695d9
SE
916 usage_with_options(record_usage, record_options);
917 }
918
655000e7 919 symbol__init();
baa2f6ce 920
ec80fde7 921 if (symbol_conf.kptr_restrict)
646aaea6
ACM
922 pr_warning(
923"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
924"check /proc/sys/kernel/kptr_restrict.\n\n"
925"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
926"file is not found in the buildid cache or in the vmlinux path.\n\n"
927"Samples in kernel modules won't be resolved at all.\n\n"
928"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
929"even with a suitable vmlinux or kallsyms file.\n\n");
ec80fde7 930
d20deb64 931 if (rec->no_buildid_cache || rec->no_buildid)
a1ac1d3c 932 disable_buildid_cache();
655000e7 933
361c99a6
ACM
934 if (evsel_list->nr_entries == 0 &&
935 perf_evlist__add_default(evsel_list) < 0) {
69aad6f1
ACM
936 pr_err("Not enough memory for event selector list\n");
937 goto out_symbol_exit;
bbd36e5e 938 }
0e9b20b8 939
16ad2ffb
NK
940 err = perf_target__validate(&rec->opts.target);
941 if (err) {
942 perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
943 ui__warning("%s", errbuf);
944 }
945
946 err = perf_target__parse_uid(&rec->opts.target);
947 if (err) {
948 int saved_errno = errno;
4bd0f2d2 949
16ad2ffb 950 perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
3780f488 951 ui__error("%s", errbuf);
16ad2ffb
NK
952
953 err = -saved_errno;
8fa60e1f 954 goto out_symbol_exit;
16ad2ffb 955 }
0d37aa34 956
16ad2ffb 957 err = -ENOMEM;
b809ac10 958 if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
dd7927f4 959 usage_with_options(record_usage, record_options);
69aad6f1 960
714647bd 961 if (perf_record_opts__config(&rec->opts)) {
39d17dac 962 err = -EINVAL;
5c581041 963 goto out_free_fd;
7e4ff9e3
MG
964 }
965
d20deb64 966 err = __cmd_record(&record, argc, argv);
8fa60e1f
NK
967
968 perf_evlist__munmap(evsel_list);
969 perf_evlist__close(evsel_list);
39d17dac 970out_free_fd:
7e2ed097 971 perf_evlist__delete_maps(evsel_list);
d65a458b
ACM
972out_symbol_exit:
973 symbol__exit();
39d17dac 974 return err;
0e9b20b8 975}