perf evsel: Introduce config attr method
[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 */
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"
8d06367f 25#include "util/symbol.h"
a12b51c4 26#include "util/cpumap.h"
fd78260b 27#include "util/thread_map.h"
7c6a1c65 28
97124d5e 29#include <unistd.h>
de9ac07b 30#include <sched.h>
a41794cd 31#include <sys/mman.h>
de9ac07b 32
7865e817
FW
33enum write_mode_t {
34 WRITE_FORCE,
35 WRITE_APPEND
36};
37
0f82ebc4
ACM
38static struct perf_record_opts record_opts = {
39 .target_pid = -1,
40 .target_tid = -1,
41 .user_freq = UINT_MAX,
42 .user_interval = ULLONG_MAX,
43 .freq = 1000,
44 .sample_id_all_avail = true,
45};
a21ca2ca 46
de9ac07b 47static unsigned int page_size;
800cd25c 48static unsigned int mmap_pages = UINT_MAX;
de9ac07b 49static int output;
529870e3 50static int pipe_output = 0;
d7065adb 51static const char *output_name = NULL;
43bece79 52static bool group = false;
1967936d 53static int realtime_prio = 0;
42e59d7d 54static pid_t child_pid = -1;
7865e817 55static enum write_mode_t write_mode = WRITE_FORCE;
a1ac1d3c 56static bool no_buildid = false;
baa2f6ce 57static bool no_buildid_cache = false;
361c99a6 58static struct perf_evlist *evsel_list;
42e59d7d
IM
59
60static long samples = 0;
42e59d7d 61static u64 bytes_written = 0;
a21ca2ca 62
42e59d7d 63static int file_new = 1;
6122e4e4 64static off_t post_processing_offset;
7c6a1c65 65
94c744b6 66static struct perf_session *session;
33e49ea7 67static const char *progname;
f5970550 68
9215545e
TZ
69static void advance_output(size_t size)
70{
71 bytes_written += size;
72}
73
f5970550
PZ
74static void write_output(void *buf, size_t size)
75{
76 while (size) {
77 int ret = write(output, buf, size);
78
79 if (ret < 0)
80 die("failed to write");
81
82 size -= ret;
83 buf += ret;
84
85 bytes_written += ret;
86 }
87}
88
8115d60c 89static int process_synthesized_event(union perf_event *event,
8d50e5b4 90 struct perf_sample *sample __used,
d8f66248 91 struct perf_session *self __used)
234fbbf5 92{
6122e4e4 93 write_output(event, event->header.size);
234fbbf5
ACM
94 return 0;
95}
96
744bd8aa 97static void mmap_read(struct perf_mmap *md)
de9ac07b 98{
744bd8aa 99 unsigned int head = perf_mmap__read_head(md);
de9ac07b
PZ
100 unsigned int old = md->prev;
101 unsigned char *data = md->base + page_size;
102 unsigned long size;
103 void *buf;
de9ac07b 104
dc82009a
ACM
105 if (old == head)
106 return;
107
108 samples++;
de9ac07b
PZ
109
110 size = head - old;
111
112 if ((old & md->mask) + size != (head & md->mask)) {
113 buf = &data[old & md->mask];
114 size = md->mask + 1 - (old & md->mask);
115 old += size;
021e9f47 116
6122e4e4 117 write_output(buf, size);
de9ac07b
PZ
118 }
119
120 buf = &data[old & md->mask];
121 size = head - old;
122 old += size;
021e9f47 123
6122e4e4 124 write_output(buf, size);
de9ac07b
PZ
125
126 md->prev = old;
115d2d89 127 perf_mmap__write_tail(md, old);
de9ac07b
PZ
128}
129
130static volatile int done = 0;
f7b7c26e 131static volatile int signr = -1;
33e49ea7 132static volatile int child_finished = 0;
de9ac07b 133
16c8a109 134static void sig_handler(int sig)
de9ac07b 135{
33e49ea7
AK
136 if (sig == SIGCHLD)
137 child_finished = 1;
138
16c8a109 139 done = 1;
f7b7c26e
PZ
140 signr = sig;
141}
142
143static void sig_atexit(void)
144{
33e49ea7
AK
145 int status;
146
147 if (child_pid > 0) {
148 if (!child_finished)
149 kill(child_pid, SIGTERM);
150
151 wait(&status);
152 if (WIFSIGNALED(status))
153 psignal(WTERMSIG(status), progname);
154 }
933da83a 155
18483b81 156 if (signr == -1 || signr == SIGUSR1)
f7b7c26e
PZ
157 return;
158
159 signal(signr, SIG_DFL);
160 kill(getpid(), signr);
de9ac07b
PZ
161}
162
a91e5431
ACM
163static bool perf_evlist__equal(struct perf_evlist *evlist,
164 struct perf_evlist *other)
165{
166 struct perf_evsel *pos, *pair;
167
168 if (evlist->nr_entries != other->nr_entries)
169 return false;
170
171 pair = list_entry(other->entries.next, struct perf_evsel, node);
172
173 list_for_each_entry(pos, &evlist->entries, node) {
174 if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0))
175 return false;
176 pair = list_entry(pair->node.next, struct perf_evsel, node);
177 }
178
179 return true;
180}
181
dd7927f4
ACM
182static void open_counters(struct perf_evlist *evlist)
183{
727ab04e 184 struct perf_evsel *pos, *first;
dd7927f4 185
727ab04e
ACM
186 first = list_entry(evlist->entries.next, struct perf_evsel, node);
187
0f82ebc4
ACM
188 perf_evlist__config_attrs(evlist, &record_opts);
189
dd7927f4
ACM
190 list_for_each_entry(pos, &evlist->entries, node) {
191 struct perf_event_attr *attr = &pos->attr;
727ab04e 192 struct xyarray *group_fd = NULL;
dd7927f4
ACM
193 /*
194 * Check if parse_single_tracepoint_event has already asked for
195 * PERF_SAMPLE_TIME.
196 *
197 * XXX this is kludgy but short term fix for problems introduced by
198 * eac23d1c that broke 'perf script' by having different sample_types
199 * when using multiple tracepoint events when we use a perf binary
200 * that tries to use sample_id_all on an older kernel.
201 *
202 * We need to move counter creation to perf_session, support
203 * different sample_types, etc.
204 */
205 bool time_needed = attr->sample_type & PERF_SAMPLE_TIME;
d6d901c2 206
727ab04e
ACM
207 if (group && pos != first)
208 group_fd = first->fd;
dd7927f4 209retry_sample_id:
0f82ebc4 210 attr->sample_id_all = record_opts.sample_id_all_avail ? 1 : 0;
dd7927f4 211try_again:
727ab04e
ACM
212 if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group,
213 group_fd) < 0) {
d6d901c2
ZY
214 int err = errno;
215
c286c419 216 if (err == EPERM || err == EACCES) {
b8631e6e 217 ui__error_paranoid();
c286c419 218 exit(EXIT_FAILURE);
0f82ebc4 219 } else if (err == ENODEV && record_opts.cpu_list) {
d6d901c2
ZY
220 die("No such device - did you specify"
221 " an out-of-range profile CPU?\n");
0f82ebc4 222 } else if (err == EINVAL && record_opts.sample_id_all_avail) {
9c90a61c
ACM
223 /*
224 * Old kernel, no attr->sample_id_type_all field
225 */
0f82ebc4
ACM
226 record_opts.sample_id_all_avail = false;
227 if (!record_opts.sample_time && !record_opts.raw_samples && !time_needed)
eac23d1c
IM
228 attr->sample_type &= ~PERF_SAMPLE_TIME;
229
9c90a61c 230 goto retry_sample_id;
d6d901c2 231 }
3da297a6 232
d6d901c2
ZY
233 /*
234 * If it's cycles then fall back to hrtimer
235 * based cpu-clock-tick sw counter, which
236 * is always available even if no PMU support:
237 */
238 if (attr->type == PERF_TYPE_HARDWARE
239 && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
240
241 if (verbose)
ca6a4258
DA
242 ui__warning("The cycles event is not supported, "
243 "trying to fall back to cpu-clock-ticks\n");
d6d901c2
ZY
244 attr->type = PERF_TYPE_SOFTWARE;
245 attr->config = PERF_COUNT_SW_CPU_CLOCK;
246 goto try_again;
247 }
ca6a4258
DA
248
249 if (err == ENOENT) {
250 ui__warning("The %s event is not supported.\n",
251 event_name(pos));
252 exit(EXIT_FAILURE);
253 }
254
d6d901c2 255 printf("\n");
d9cf837e 256 error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n",
dd7927f4 257 err, strerror(err));
bfd45118
SK
258
259#if defined(__i386__) || defined(__x86_64__)
d6d901c2
ZY
260 if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP)
261 die("No hardware sampling interrupt available."
262 " No APIC? If so then you can boot the kernel"
263 " with the \"lapic\" boot parameter to"
264 " force-enable it.\n");
bfd45118
SK
265#endif
266
d6d901c2 267 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
c171b552
LZ
268 }
269 }
a43d3f08 270
0a102479
FW
271 if (perf_evlist__set_filters(evlist)) {
272 error("failed to set filter with %d (%s)\n", errno,
273 strerror(errno));
274 exit(-1);
275 }
276
7e2ed097 277 if (perf_evlist__mmap(evlist, mmap_pages, false) < 0)
0a27d7f9
ACM
278 die("failed to mmap with %d (%s)\n", errno, strerror(errno));
279
a91e5431
ACM
280 if (file_new)
281 session->evlist = evlist;
282 else {
283 if (!perf_evlist__equal(session->evlist, evlist)) {
284 fprintf(stderr, "incompatible append\n");
285 exit(-1);
286 }
287 }
288
289 perf_session__update_sample_type(session);
16c8a109
PZ
290}
291
6122e4e4
ACM
292static int process_buildids(void)
293{
294 u64 size = lseek(output, 0, SEEK_CUR);
295
9f591fd7
ACM
296 if (size == 0)
297 return 0;
298
6122e4e4
ACM
299 session->fd = output;
300 return __perf_session__process_events(session, post_processing_offset,
301 size - post_processing_offset,
302 size, &build_id__mark_dso_hit_ops);
303}
304
f5970550
PZ
305static void atexit_header(void)
306{
c7929e47
TZ
307 if (!pipe_output) {
308 session->header.data_size += bytes_written;
f5970550 309
baa2f6ce
ACM
310 if (!no_buildid)
311 process_buildids();
a91e5431 312 perf_session__write_header(session, evsel_list, output, true);
39d17dac 313 perf_session__delete(session);
361c99a6 314 perf_evlist__delete(evsel_list);
d65a458b 315 symbol__exit();
c7929e47 316 }
f5970550
PZ
317}
318
8115d60c 319static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
a1645ce1
ZY
320{
321 int err;
23346f21 322 struct perf_session *psession = data;
a1645ce1 323
23346f21 324 if (machine__is_host(machine))
a1645ce1
ZY
325 return;
326
327 /*
328 *As for guest kernel when processing subcommand record&report,
329 *we arrange module mmap prior to guest kernel mmap and trigger
330 *a preload dso because default guest module symbols are loaded
331 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
332 *method is used to avoid symbol missing when the first addr is
333 *in module instead of in guest kernel.
334 */
8115d60c
ACM
335 err = perf_event__synthesize_modules(process_synthesized_event,
336 psession, machine);
a1645ce1
ZY
337 if (err < 0)
338 pr_err("Couldn't record guest kernel [%d]'s reference"
23346f21 339 " relocation symbol.\n", machine->pid);
a1645ce1 340
a1645ce1
ZY
341 /*
342 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
343 * have no _text sometimes.
344 */
8115d60c
ACM
345 err = perf_event__synthesize_kernel_mmap(process_synthesized_event,
346 psession, machine, "_text");
a1645ce1 347 if (err < 0)
8115d60c
ACM
348 err = perf_event__synthesize_kernel_mmap(process_synthesized_event,
349 psession, machine,
350 "_stext");
a1645ce1
ZY
351 if (err < 0)
352 pr_err("Couldn't record guest kernel [%d]'s reference"
23346f21 353 " relocation symbol.\n", machine->pid);
a1645ce1
ZY
354}
355
98402807
FW
356static struct perf_event_header finished_round_event = {
357 .size = sizeof(struct perf_event_header),
358 .type = PERF_RECORD_FINISHED_ROUND,
359};
360
361static void mmap_read_all(void)
362{
0e2e63dd 363 int i;
98402807 364
aece948f 365 for (i = 0; i < evsel_list->nr_mmaps; i++) {
0a27d7f9
ACM
366 if (evsel_list->mmap[i].base)
367 mmap_read(&evsel_list->mmap[i]);
98402807
FW
368 }
369
370 if (perf_header__has_feat(&session->header, HEADER_TRACE_INFO))
371 write_output(&finished_round_event, sizeof(finished_round_event));
372}
373
d4db3f16 374static int __cmd_record(int argc, const char **argv)
16c8a109 375{
abaff32a 376 struct stat st;
abaff32a 377 int flags;
4dc0a04b 378 int err;
8b412664 379 unsigned long waking = 0;
856e9660 380 int child_ready_pipe[2], go_pipe[2];
46be604b 381 const bool forks = argc > 0;
856e9660 382 char buf;
23346f21 383 struct machine *machine;
de9ac07b 384
33e49ea7
AK
385 progname = argv[0];
386
de9ac07b 387 page_size = sysconf(_SC_PAGE_SIZE);
de9ac07b 388
f5970550
PZ
389 atexit(sig_atexit);
390 signal(SIGCHLD, sig_handler);
391 signal(SIGINT, sig_handler);
18483b81 392 signal(SIGUSR1, sig_handler);
f5970550 393
d4db3f16 394 if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
856e9660
PZ
395 perror("failed to create pipes");
396 exit(-1);
397 }
398
d7065adb
FBH
399 if (!output_name) {
400 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
0f82ebc4 401 pipe_output = true;
d7065adb
FBH
402 else
403 output_name = "perf.data";
404 }
405 if (output_name) {
406 if (!strcmp(output_name, "-"))
0f82ebc4 407 pipe_output = true;
d7065adb
FBH
408 else if (!stat(output_name, &st) && st.st_size) {
409 if (write_mode == WRITE_FORCE) {
410 char oldname[PATH_MAX];
411 snprintf(oldname, sizeof(oldname), "%s.old",
412 output_name);
413 unlink(oldname);
414 rename(output_name, oldname);
415 }
416 } else if (write_mode == WRITE_APPEND) {
417 write_mode = WRITE_FORCE;
266e0e21 418 }
97124d5e
PZ
419 }
420
f887f301 421 flags = O_CREAT|O_RDWR;
7865e817 422 if (write_mode == WRITE_APPEND)
f5970550 423 file_new = 0;
abaff32a
IM
424 else
425 flags |= O_TRUNC;
426
529870e3
TZ
427 if (pipe_output)
428 output = STDOUT_FILENO;
429 else
430 output = open(output_name, flags, S_IRUSR | S_IWUSR);
de9ac07b
PZ
431 if (output < 0) {
432 perror("failed to create output file");
433 exit(-1);
434 }
435
7865e817 436 session = perf_session__new(output_name, O_WRONLY,
21ef97f0 437 write_mode == WRITE_FORCE, false, NULL);
94c744b6 438 if (session == NULL) {
a9a70bbc
ACM
439 pr_err("Not enough memory for reading perf file header\n");
440 return -1;
441 }
442
baa2f6ce
ACM
443 if (!no_buildid)
444 perf_header__set_feat(&session->header, HEADER_BUILD_ID);
445
4dc0a04b 446 if (!file_new) {
a91e5431 447 err = perf_session__read_header(session, output);
4dc0a04b 448 if (err < 0)
39d17dac 449 goto out_delete_session;
4dc0a04b
ACM
450 }
451
361c99a6 452 if (have_tracepoints(&evsel_list->entries))
94c744b6 453 perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
03456a15 454
fbe96f29
SE
455 perf_header__set_feat(&session->header, HEADER_HOSTNAME);
456 perf_header__set_feat(&session->header, HEADER_OSRELEASE);
457 perf_header__set_feat(&session->header, HEADER_ARCH);
458 perf_header__set_feat(&session->header, HEADER_CPUDESC);
459 perf_header__set_feat(&session->header, HEADER_NRCPUS);
460 perf_header__set_feat(&session->header, HEADER_EVENT_DESC);
461 perf_header__set_feat(&session->header, HEADER_CMDLINE);
462 perf_header__set_feat(&session->header, HEADER_VERSION);
463 perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
464 perf_header__set_feat(&session->header, HEADER_TOTAL_MEM);
465 perf_header__set_feat(&session->header, HEADER_NUMA_TOPOLOGY);
466 perf_header__set_feat(&session->header, HEADER_CPUID);
467
800cd25c
FW
468 /* 512 kiB: default amount of unprivileged mlocked memory */
469 if (mmap_pages == UINT_MAX)
470 mmap_pages = (512 * 1024) / page_size;
471
d4db3f16 472 if (forks) {
46be604b 473 child_pid = fork();
2fb750e8 474 if (child_pid < 0) {
856e9660
PZ
475 perror("failed to fork");
476 exit(-1);
477 }
7c6a1c65 478
46be604b 479 if (!child_pid) {
529870e3
TZ
480 if (pipe_output)
481 dup2(2, 1);
856e9660
PZ
482 close(child_ready_pipe[0]);
483 close(go_pipe[1]);
484 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
485
486 /*
487 * Do a dummy execvp to get the PLT entry resolved,
488 * so we avoid the resolver overhead on the real
489 * execvp call.
490 */
491 execvp("", (char **)argv);
492
493 /*
494 * Tell the parent we're ready to go
495 */
496 close(child_ready_pipe[1]);
497
498 /*
499 * Wait until the parent tells us to go.
500 */
501 if (read(go_pipe[0], &buf, 1) == -1)
502 perror("unable to read pipe");
503
504 execvp(argv[0], (char **)argv);
505
506 perror(argv[0]);
18483b81 507 kill(getppid(), SIGUSR1);
856e9660 508 exit(-1);
0a5ac846 509 }
856e9660 510
0f82ebc4 511 if (!record_opts.system_wide && record_opts.target_tid == -1 && record_opts.target_pid == -1)
7e2ed097 512 evsel_list->threads->map[0] = child_pid;
d6d901c2 513
856e9660
PZ
514 close(child_ready_pipe[1]);
515 close(go_pipe[0]);
516 /*
517 * wait for child to settle
518 */
519 if (read(child_ready_pipe[0], &buf, 1) == -1) {
520 perror("unable to read pipe");
521 exit(-1);
522 }
523 close(child_ready_pipe[0]);
524 }
525
dd7927f4 526 open_counters(evsel_list);
de9ac07b 527
712a4b60
ACM
528 /*
529 * perf_session__delete(session) will be called at atexit_header()
530 */
531 atexit(atexit_header);
532
529870e3
TZ
533 if (pipe_output) {
534 err = perf_header__write_pipe(output);
535 if (err < 0)
536 return err;
537 } else if (file_new) {
a91e5431
ACM
538 err = perf_session__write_header(session, evsel_list,
539 output, false);
d5eed904
ACM
540 if (err < 0)
541 return err;
56b03f3c
ACM
542 }
543
6122e4e4
ACM
544 post_processing_offset = lseek(output, 0, SEEK_CUR);
545
2c46dbb5 546 if (pipe_output) {
a91e5431
ACM
547 err = perf_session__synthesize_attrs(session,
548 process_synthesized_event);
2c46dbb5
TZ
549 if (err < 0) {
550 pr_err("Couldn't synthesize attrs.\n");
551 return err;
552 }
cd19a035 553
8115d60c
ACM
554 err = perf_event__synthesize_event_types(process_synthesized_event,
555 session);
cd19a035
TZ
556 if (err < 0) {
557 pr_err("Couldn't synthesize event_types.\n");
558 return err;
559 }
9215545e 560
361c99a6 561 if (have_tracepoints(&evsel_list->entries)) {
63e0c771
TZ
562 /*
563 * FIXME err <= 0 here actually means that
564 * there were no tracepoints so its not really
565 * an error, just that we don't need to
566 * synthesize anything. We really have to
567 * return this more properly and also
568 * propagate errors that now are calling die()
569 */
8115d60c
ACM
570 err = perf_event__synthesize_tracing_data(output, evsel_list,
571 process_synthesized_event,
572 session);
63e0c771
TZ
573 if (err <= 0) {
574 pr_err("Couldn't record tracing data.\n");
575 return err;
576 }
2c9faa06 577 advance_output(err);
63e0c771 578 }
2c46dbb5
TZ
579 }
580
23346f21
ACM
581 machine = perf_session__find_host_machine(session);
582 if (!machine) {
a1645ce1
ZY
583 pr_err("Couldn't find native kernel information.\n");
584 return -1;
585 }
586
8115d60c
ACM
587 err = perf_event__synthesize_kernel_mmap(process_synthesized_event,
588 session, machine, "_text");
70162138 589 if (err < 0)
8115d60c
ACM
590 err = perf_event__synthesize_kernel_mmap(process_synthesized_event,
591 session, machine, "_stext");
c1a3a4b9
ACM
592 if (err < 0)
593 pr_err("Couldn't record kernel reference relocation symbol\n"
594 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
595 "Check /proc/kallsyms permission or run as root.\n");
b7cece76 596
8115d60c
ACM
597 err = perf_event__synthesize_modules(process_synthesized_event,
598 session, machine);
c1a3a4b9
ACM
599 if (err < 0)
600 pr_err("Couldn't record kernel module information.\n"
601 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
602 "Check /proc/modules permission or run as root.\n");
603
a1645ce1 604 if (perf_guest)
8115d60c
ACM
605 perf_session__process_machines(session,
606 perf_event__synthesize_guest_os);
7c6a1c65 607
0f82ebc4 608 if (!record_opts.system_wide)
7c940c18
ACM
609 perf_event__synthesize_thread_map(evsel_list->threads,
610 process_synthesized_event,
611 session);
234fbbf5 612 else
8115d60c
ACM
613 perf_event__synthesize_threads(process_synthesized_event,
614 session);
7c6a1c65 615
de9ac07b
PZ
616 if (realtime_prio) {
617 struct sched_param param;
618
619 param.sched_priority = realtime_prio;
620 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
6beba7ad 621 pr_err("Could not set realtime priority.\n");
de9ac07b
PZ
622 exit(-1);
623 }
624 }
625
764e16a3
DA
626 perf_evlist__enable(evsel_list);
627
856e9660
PZ
628 /*
629 * Let the child rip
630 */
d4db3f16
ACM
631 if (forks)
632 close(go_pipe[1]);
856e9660 633
649c48a9 634 for (;;) {
2debbc83 635 int hits = samples;
de9ac07b 636
98402807 637 mmap_read_all();
de9ac07b 638
649c48a9
PZ
639 if (hits == samples) {
640 if (done)
641 break;
5c581041 642 err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1);
8b412664
PZ
643 waking++;
644 }
645
4152ab37
ACM
646 if (done)
647 perf_evlist__disable(evsel_list);
de9ac07b
PZ
648 }
649
18483b81 650 if (quiet || signr == SIGUSR1)
b44308f5
ACM
651 return 0;
652
8b412664
PZ
653 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
654
021e9f47
IM
655 /*
656 * Approximate RIP event size: 24 bytes.
657 */
658 fprintf(stderr,
9486aa38 659 "[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64 " samples) ]\n",
021e9f47
IM
660 (double)bytes_written / 1024.0 / 1024.0,
661 output_name,
662 bytes_written / 24);
addc2785 663
de9ac07b 664 return 0;
39d17dac
ACM
665
666out_delete_session:
667 perf_session__delete(session);
668 return err;
de9ac07b 669}
0e9b20b8 670
0e9b20b8 671static const char * const record_usage[] = {
9e096753
MG
672 "perf record [<options>] [<command>]",
673 "perf record [<options>] -- <command> [<options>]",
0e9b20b8
IM
674 NULL
675};
676
7865e817
FW
677static bool force, append_file;
678
bca647aa 679const struct option record_options[] = {
361c99a6 680 OPT_CALLBACK('e', "event", &evsel_list, "event",
86847b62 681 "event selector. use 'perf list' to list available events",
f120f9d5 682 parse_events_option),
361c99a6 683 OPT_CALLBACK(0, "filter", &evsel_list, "filter",
c171b552 684 "event filter", parse_filter),
0f82ebc4 685 OPT_INTEGER('p', "pid", &record_opts.target_pid,
d6d901c2 686 "record events on existing process id"),
0f82ebc4 687 OPT_INTEGER('t', "tid", &record_opts.target_tid,
d6d901c2 688 "record events on existing thread id"),
0e9b20b8
IM
689 OPT_INTEGER('r', "realtime", &realtime_prio,
690 "collect data with this RT SCHED_FIFO priority"),
0f82ebc4 691 OPT_BOOLEAN('D', "no-delay", &record_opts.no_delay,
acac03fa 692 "collect data without buffering"),
0f82ebc4 693 OPT_BOOLEAN('R', "raw-samples", &record_opts.raw_samples,
daac07b2 694 "collect raw sample records from all opened counters"),
0f82ebc4 695 OPT_BOOLEAN('a', "all-cpus", &record_opts.system_wide,
0e9b20b8 696 "system-wide collection from all CPUs"),
abaff32a
IM
697 OPT_BOOLEAN('A', "append", &append_file,
698 "append to the output file to do incremental profiling"),
0f82ebc4 699 OPT_STRING('C', "cpu", &record_opts.cpu_list, "cpu",
c45c6ea2 700 "list of cpus to monitor"),
97124d5e 701 OPT_BOOLEAN('f', "force", &force,
7865e817 702 "overwrite existing data file (deprecated)"),
0f82ebc4 703 OPT_U64('c', "count", &record_opts.user_interval, "event period to sample"),
abaff32a
IM
704 OPT_STRING('o', "output", &output_name, "file",
705 "output file name"),
0f82ebc4 706 OPT_BOOLEAN('i', "no-inherit", &record_opts.no_inherit,
2e6cdf99 707 "child tasks do not inherit counters"),
0f82ebc4 708 OPT_UINTEGER('F', "freq", &record_opts.user_freq, "profile at this frequency"),
1967936d 709 OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"),
43bece79
LM
710 OPT_BOOLEAN(0, "group", &group,
711 "put the counters into a counter group"),
0f82ebc4 712 OPT_BOOLEAN('g', "call-graph", &record_opts.call_graph,
3efa1cc9 713 "do call-graph (stack chain/backtrace) recording"),
c0555642 714 OPT_INCR('v', "verbose", &verbose,
3da297a6 715 "be more verbose (show counter open errors, etc)"),
b44308f5 716 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
0f82ebc4 717 OPT_BOOLEAN('s', "stat", &record_opts.inherit_stat,
649c48a9 718 "per thread counts"),
0f82ebc4 719 OPT_BOOLEAN('d', "data", &record_opts.sample_address,
4bba828d 720 "Sample addresses"),
0f82ebc4
ACM
721 OPT_BOOLEAN('T', "timestamp", &record_opts.sample_time, "Sample timestamps"),
722 OPT_BOOLEAN('n', "no-samples", &record_opts.no_samples,
649c48a9 723 "don't sample"),
baa2f6ce 724 OPT_BOOLEAN('N', "no-buildid-cache", &no_buildid_cache,
a1ac1d3c 725 "do not update the buildid cache"),
baa2f6ce
ACM
726 OPT_BOOLEAN('B', "no-buildid", &no_buildid,
727 "do not collect buildids in perf.data"),
023695d9
SE
728 OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
729 "monitor event in cgroup name only",
730 parse_cgroups),
0e9b20b8
IM
731 OPT_END()
732};
733
f37a291c 734int cmd_record(int argc, const char **argv, const char *prefix __used)
0e9b20b8 735{
69aad6f1
ACM
736 int err = -ENOMEM;
737 struct perf_evsel *pos;
0e9b20b8 738
fbe96f29
SE
739 perf_header__set_cmdline(argc, argv);
740
7e2ed097 741 evsel_list = perf_evlist__new(NULL, NULL);
361c99a6
ACM
742 if (evsel_list == NULL)
743 return -ENOMEM;
744
bca647aa 745 argc = parse_options(argc, argv, record_options, record_usage,
655000e7 746 PARSE_OPT_STOP_AT_NON_OPTION);
0f82ebc4
ACM
747 if (!argc && record_opts.target_pid == -1 && record_opts.target_tid == -1 &&
748 !record_opts.system_wide && !record_opts.cpu_list)
bca647aa 749 usage_with_options(record_usage, record_options);
0e9b20b8 750
7865e817
FW
751 if (force && append_file) {
752 fprintf(stderr, "Can't overwrite and append at the same time."
753 " You need to choose between -f and -A");
bca647aa 754 usage_with_options(record_usage, record_options);
7865e817
FW
755 } else if (append_file) {
756 write_mode = WRITE_APPEND;
757 } else {
758 write_mode = WRITE_FORCE;
759 }
760
0f82ebc4 761 if (nr_cgroups && !record_opts.system_wide) {
023695d9
SE
762 fprintf(stderr, "cgroup monitoring only available in"
763 " system-wide mode\n");
764 usage_with_options(record_usage, record_options);
765 }
766
655000e7 767 symbol__init();
baa2f6ce 768
ec80fde7 769 if (symbol_conf.kptr_restrict)
646aaea6
ACM
770 pr_warning(
771"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
772"check /proc/sys/kernel/kptr_restrict.\n\n"
773"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
774"file is not found in the buildid cache or in the vmlinux path.\n\n"
775"Samples in kernel modules won't be resolved at all.\n\n"
776"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
777"even with a suitable vmlinux or kallsyms file.\n\n");
ec80fde7 778
baa2f6ce 779 if (no_buildid_cache || no_buildid)
a1ac1d3c 780 disable_buildid_cache();
655000e7 781
361c99a6
ACM
782 if (evsel_list->nr_entries == 0 &&
783 perf_evlist__add_default(evsel_list) < 0) {
69aad6f1
ACM
784 pr_err("Not enough memory for event selector list\n");
785 goto out_symbol_exit;
bbd36e5e 786 }
0e9b20b8 787
0f82ebc4
ACM
788 if (record_opts.target_pid != -1)
789 record_opts.target_tid = record_opts.target_pid;
d6d901c2 790
0f82ebc4
ACM
791 if (perf_evlist__create_maps(evsel_list, record_opts.target_pid,
792 record_opts.target_tid, record_opts.cpu_list) < 0)
dd7927f4 793 usage_with_options(record_usage, record_options);
69aad6f1 794
361c99a6 795 list_for_each_entry(pos, &evsel_list->entries, node) {
7e2ed097
ACM
796 if (perf_evsel__alloc_fd(pos, evsel_list->cpus->nr,
797 evsel_list->threads->nr) < 0)
69aad6f1 798 goto out_free_fd;
ad7f4e3f
ACM
799 if (perf_header__push_event(pos->attr.config, event_name(pos)))
800 goto out_free_fd;
d6d901c2 801 }
5c581041 802
7e2ed097 803 if (perf_evlist__alloc_pollfd(evsel_list) < 0)
39d17dac 804 goto out_free_fd;
d6d901c2 805
0f82ebc4
ACM
806 if (record_opts.user_interval != ULLONG_MAX)
807 record_opts.default_interval = record_opts.user_interval;
808 if (record_opts.user_freq != UINT_MAX)
809 record_opts.freq = record_opts.user_freq;
f9212819 810
7e4ff9e3
MG
811 /*
812 * User specified count overrides default frequency.
813 */
0f82ebc4
ACM
814 if (record_opts.default_interval)
815 record_opts.freq = 0;
816 else if (record_opts.freq) {
817 record_opts.default_interval = record_opts.freq;
7e4ff9e3
MG
818 } else {
819 fprintf(stderr, "frequency and count are zero, aborting\n");
39d17dac 820 err = -EINVAL;
5c581041 821 goto out_free_fd;
7e4ff9e3
MG
822 }
823
39d17dac 824 err = __cmd_record(argc, argv);
39d17dac 825out_free_fd:
7e2ed097 826 perf_evlist__delete_maps(evsel_list);
d65a458b
ACM
827out_symbol_exit:
828 symbol__exit();
39d17dac 829 return err;
0e9b20b8 830}