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