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