blob: 32a9a68d38a24e680ed8de92457ae0fd3879c339 [file] [log] [blame]
Ingo Molnarabaff322009-06-02 22:59:57 +02001/*
Ingo Molnarbf9e1872009-06-02 23:37:05 +02002 * 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.
Ingo Molnarabaff322009-06-02 22:59:57 +02007 */
Ingo Molnar16f762a2009-05-27 09:10:38 +02008#include "builtin.h"
Ingo Molnarbf9e1872009-06-02 23:37:05 +02009
10#include "perf.h"
11
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -020012#include "util/build-id.h"
Thomas Gleixner6eda5832009-05-01 18:29:57 +020013#include "util/util.h"
Josh Poimboeuf4b6ab942015-12-15 09:39:39 -060014#include <subcmd/parse-options.h>
Ingo Molnar8ad8db32009-05-26 11:10:09 +020015#include "util/parse-events.h"
Taeung Song41840d22016-06-23 17:55:17 +090016#include "util/config.h"
Thomas Gleixner6eda5832009-05-01 18:29:57 +020017
Arnaldo Carvalho de Melo8f651ea2014-10-09 16:12:24 -030018#include "util/callchain.h"
Arnaldo Carvalho de Melof14d5702014-10-17 12:17:40 -030019#include "util/cgroup.h"
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +020020#include "util/header.h"
Frederic Weisbecker66e274f2009-08-12 11:07:25 +020021#include "util/event.h"
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -020022#include "util/evlist.h"
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -020023#include "util/evsel.h"
Frederic Weisbecker8f288272009-08-16 22:05:48 +020024#include "util/debug.h"
Mathieu Poirier5d8bb1e2016-09-16 09:50:03 -060025#include "util/drv_configs.h"
Arnaldo Carvalho de Melo94c744b2009-12-11 21:24:02 -020026#include "util/session.h"
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020027#include "util/tool.h"
Arnaldo Carvalho de Melo8d063672009-11-04 18:50:43 -020028#include "util/symbol.h"
Paul Mackerrasa12b51c2010-03-10 20:36:09 +110029#include "util/cpumap.h"
Arnaldo Carvalho de Melofd782602011-01-18 15:15:24 -020030#include "util/thread_map.h"
Jiri Olsaf5fc14122013-10-15 16:27:32 +020031#include "util/data.h"
Stephane Eranianbcc84ec2015-08-31 18:41:12 +020032#include "util/perf_regs.h"
Adrian Hunteref149c22015-04-09 18:53:45 +030033#include "util/auxtrace.h"
Adrian Hunter46bc29b2016-03-08 10:38:44 +020034#include "util/tsc.h"
Andi Kleenf00898f2015-05-27 10:51:51 -070035#include "util/parse-branch-options.h"
Stephane Eranianbcc84ec2015-08-31 18:41:12 +020036#include "util/parse-regs-options.h"
Wang Nan71dc23262015-10-14 12:41:19 +000037#include "util/llvm-utils.h"
Wang Nan8690a2a2016-02-22 09:10:32 +000038#include "util/bpf-loader.h"
Wang Nan5f9cf592016-04-20 18:59:49 +000039#include "util/trigger.h"
Wang Nana0748652016-11-26 07:03:28 +000040#include "util/perf-hooks.h"
Arnaldo Carvalho de Meloc5e40272017-04-19 16:12:39 -030041#include "util/time-utils.h"
Arnaldo Carvalho de Melo58db1d62017-04-19 16:05:56 -030042#include "util/units.h"
Wang Nand8871ea2016-02-26 09:32:06 +000043#include "asm/bug.h"
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +020044
Arnaldo Carvalho de Meloa43783a2017-04-18 10:46:11 -030045#include <errno.h>
Arnaldo Carvalho de Melofd20e812017-04-17 15:23:08 -030046#include <inttypes.h>
Peter Zijlstra97124d5e2009-06-02 15:52:24 +020047#include <unistd.h>
Peter Zijlstrade9ac072009-04-08 15:01:31 +020048#include <sched.h>
Arnaldo Carvalho de Melo9607ad32017-04-19 15:49:18 -030049#include <signal.h>
Arnaldo Carvalho de Meloa41794c2010-05-18 18:29:23 -030050#include <sys/mman.h>
Wang Nan2d11c652016-05-23 07:13:39 +000051#include <asm/bug.h>
Arnaldo Carvalho de Melo0693e682016-08-08 15:05:46 -030052#include <linux/time64.h>
Bernhard Rosenkraenzer78da39f2012-10-08 09:43:26 +030053
Jiri Olsa1b43b702017-01-09 10:51:56 +010054struct switch_output {
Jiri Olsadc0c6122017-01-09 10:51:58 +010055 bool enabled;
Jiri Olsa1b43b702017-01-09 10:51:56 +010056 bool signal;
Jiri Olsadc0c6122017-01-09 10:51:58 +010057 unsigned long size;
Jiri Olsabfacbe32017-01-09 10:52:00 +010058 unsigned long time;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +010059 const char *str;
60 bool set;
Jiri Olsa1b43b702017-01-09 10:51:56 +010061};
62
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -030063struct record {
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020064 struct perf_tool tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -030065 struct record_opts opts;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020066 u64 bytes_written;
Jiri Olsaf5fc14122013-10-15 16:27:32 +020067 struct perf_data_file file;
Adrian Hunteref149c22015-04-09 18:53:45 +030068 struct auxtrace_record *itr;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020069 struct perf_evlist *evlist;
70 struct perf_session *session;
71 const char *progname;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020072 int realtime_prio;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020073 bool no_buildid;
Wang Nand2db9a92016-01-25 09:56:19 +000074 bool no_buildid_set;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020075 bool no_buildid_cache;
Wang Nand2db9a92016-01-25 09:56:19 +000076 bool no_buildid_cache_set;
Namhyung Kim61566812016-01-11 22:37:09 +090077 bool buildid_all;
Wang Nanecfd7a92016-04-13 08:21:07 +000078 bool timestamp_filename;
Jiri Olsa1b43b702017-01-09 10:51:56 +010079 struct switch_output switch_output;
Yang Shi9f065192015-09-29 14:49:43 -070080 unsigned long long samples;
Arnaldo Carvalho de Melo0f82ebc2011-11-08 14:41:57 -020081};
Ingo Molnara21ca2c2009-06-06 09:58:57 +020082
Jiri Olsadc0c6122017-01-09 10:51:58 +010083static volatile int auxtrace_record__snapshot_started;
84static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
85static DEFINE_TRIGGER(switch_output_trigger);
86
87static bool switch_output_signal(struct record *rec)
88{
89 return rec->switch_output.signal &&
90 trigger_is_ready(&switch_output_trigger);
91}
92
93static bool switch_output_size(struct record *rec)
94{
95 return rec->switch_output.size &&
96 trigger_is_ready(&switch_output_trigger) &&
97 (rec->bytes_written >= rec->switch_output.size);
98}
99
Jiri Olsabfacbe32017-01-09 10:52:00 +0100100static bool switch_output_time(struct record *rec)
101{
102 return rec->switch_output.time &&
103 trigger_is_ready(&switch_output_trigger);
104}
105
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300106static int record__write(struct record *rec, void *bf, size_t size)
Peter Zijlstraf5970552009-06-18 23:22:55 +0200107{
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -0300108 if (perf_data_file__write(rec->session->file, bf, size) < 0) {
Jiri Olsa50a9b862013-11-22 13:11:24 +0100109 pr_err("failed to write perf data, error: %m\n");
110 return -1;
Peter Zijlstraf5970552009-06-18 23:22:55 +0200111 }
David Ahern8d3eca22012-08-26 12:24:47 -0600112
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -0300113 rec->bytes_written += size;
Jiri Olsadc0c6122017-01-09 10:51:58 +0100114
115 if (switch_output_size(rec))
116 trigger_hit(&switch_output_trigger);
117
David Ahern8d3eca22012-08-26 12:24:47 -0600118 return 0;
Peter Zijlstraf5970552009-06-18 23:22:55 +0200119}
120
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200121static int process_synthesized_event(struct perf_tool *tool,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200122 union perf_event *event,
Irina Tirdea1d037ca2012-09-11 01:15:03 +0300123 struct perf_sample *sample __maybe_unused,
124 struct machine *machine __maybe_unused)
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -0200125{
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300126 struct record *rec = container_of(tool, struct record, tool);
127 return record__write(rec, event, event->header.size);
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -0200128}
129
Wang Nan3a62a7b2016-05-23 07:13:41 +0000130static int
131backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end)
132{
133 struct perf_event_header *pheader;
134 u64 evt_head = head;
135 int size = mask + 1;
136
137 pr_debug2("backward_rb_find_range: buf=%p, head=%"PRIx64"\n", buf, head);
138 pheader = (struct perf_event_header *)(buf + (head & mask));
139 *start = head;
140 while (true) {
141 if (evt_head - head >= (unsigned int)size) {
Colin Ian King5e30d552016-08-22 19:30:08 +0100142 pr_debug("Finished reading backward ring buffer: rewind\n");
Wang Nan3a62a7b2016-05-23 07:13:41 +0000143 if (evt_head - head > (unsigned int)size)
144 evt_head -= pheader->size;
145 *end = evt_head;
146 return 0;
147 }
148
149 pheader = (struct perf_event_header *)(buf + (evt_head & mask));
150
151 if (pheader->size == 0) {
Colin Ian King5e30d552016-08-22 19:30:08 +0100152 pr_debug("Finished reading backward ring buffer: get start\n");
Wang Nan3a62a7b2016-05-23 07:13:41 +0000153 *end = evt_head;
154 return 0;
155 }
156
157 evt_head += pheader->size;
158 pr_debug3("move evt_head: %"PRIx64"\n", evt_head);
159 }
160 WARN_ONCE(1, "Shouldn't get here\n");
161 return -1;
162}
163
164static int
Wang Nana4ea0ec2016-07-14 08:34:36 +0000165rb_find_range(void *data, int mask, u64 head, u64 old,
166 u64 *start, u64 *end, bool backward)
Wang Nan3a62a7b2016-05-23 07:13:41 +0000167{
Wang Nana4ea0ec2016-07-14 08:34:36 +0000168 if (!backward) {
Wang Nan3a62a7b2016-05-23 07:13:41 +0000169 *start = old;
170 *end = head;
171 return 0;
172 }
173
174 return backward_rb_find_range(data, mask, head, start, end);
175}
176
Wang Nana4ea0ec2016-07-14 08:34:36 +0000177static int
178record__mmap_read(struct record *rec, struct perf_mmap *md,
179 bool overwrite, bool backward)
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200180{
David Ahern7b8283b52015-04-07 09:20:37 -0600181 u64 head = perf_mmap__read_head(md);
182 u64 old = md->prev;
Wang Nan09fa4f42016-05-23 07:13:40 +0000183 u64 end = head, start = old;
Jiri Olsa918512b2013-09-12 18:39:35 +0200184 unsigned char *data = md->base + page_size;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200185 unsigned long size;
186 void *buf;
David Ahern8d3eca22012-08-26 12:24:47 -0600187 int rc = 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200188
Wang Nana4ea0ec2016-07-14 08:34:36 +0000189 if (rb_find_range(data, md->mask, head,
190 old, &start, &end, backward))
Wang Nan3a62a7b2016-05-23 07:13:41 +0000191 return -1;
192
Wang Nan09fa4f42016-05-23 07:13:40 +0000193 if (start == end)
David Ahern8d3eca22012-08-26 12:24:47 -0600194 return 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200195
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200196 rec->samples++;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200197
Wang Nan09fa4f42016-05-23 07:13:40 +0000198 size = end - start;
Wang Nan2d11c652016-05-23 07:13:39 +0000199 if (size > (unsigned long)(md->mask) + 1) {
200 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
201
202 md->prev = head;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000203 perf_mmap__consume(md, overwrite || backward);
Wang Nan2d11c652016-05-23 07:13:39 +0000204 return 0;
205 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200206
Wang Nan09fa4f42016-05-23 07:13:40 +0000207 if ((start & md->mask) + size != (end & md->mask)) {
208 buf = &data[start & md->mask];
209 size = md->mask + 1 - (start & md->mask);
210 start += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200211
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300212 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600213 rc = -1;
214 goto out;
215 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200216 }
217
Wang Nan09fa4f42016-05-23 07:13:40 +0000218 buf = &data[start & md->mask];
219 size = end - start;
220 start += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200221
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300222 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600223 rc = -1;
224 goto out;
225 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200226
Wang Nan09fa4f42016-05-23 07:13:40 +0000227 md->prev = head;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000228 perf_mmap__consume(md, overwrite || backward);
David Ahern8d3eca22012-08-26 12:24:47 -0600229out:
230 return rc;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200231}
232
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300233static volatile int done;
234static volatile int signr = -1;
235static volatile int child_finished;
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000236
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300237static void sig_handler(int sig)
238{
239 if (sig == SIGCHLD)
240 child_finished = 1;
241 else
242 signr = sig;
243
244 done = 1;
245}
246
Wang Nana0748652016-11-26 07:03:28 +0000247static void sigsegv_handler(int sig)
248{
249 perf_hooks__recover();
250 sighandler_dump_stack(sig);
251}
252
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300253static void record__sig_exit(void)
254{
255 if (signr == -1)
256 return;
257
258 signal(signr, SIG_DFL);
259 raise(signr);
260}
261
Adrian Huntere31f0d02015-04-30 17:37:27 +0300262#ifdef HAVE_AUXTRACE_SUPPORT
263
Adrian Hunteref149c22015-04-09 18:53:45 +0300264static int record__process_auxtrace(struct perf_tool *tool,
265 union perf_event *event, void *data1,
266 size_t len1, void *data2, size_t len2)
267{
268 struct record *rec = container_of(tool, struct record, tool);
Adrian Hunter99fa2982015-04-30 17:37:25 +0300269 struct perf_data_file *file = &rec->file;
Adrian Hunteref149c22015-04-09 18:53:45 +0300270 size_t padding;
271 u8 pad[8] = {0};
272
Adrian Hunter99fa2982015-04-30 17:37:25 +0300273 if (!perf_data_file__is_pipe(file)) {
274 off_t file_offset;
275 int fd = perf_data_file__fd(file);
276 int err;
277
278 file_offset = lseek(fd, 0, SEEK_CUR);
279 if (file_offset == -1)
280 return -1;
281 err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index,
282 event, file_offset);
283 if (err)
284 return err;
285 }
286
Adrian Hunteref149c22015-04-09 18:53:45 +0300287 /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */
288 padding = (len1 + len2) & 7;
289 if (padding)
290 padding = 8 - padding;
291
292 record__write(rec, event, event->header.size);
293 record__write(rec, data1, len1);
294 if (len2)
295 record__write(rec, data2, len2);
296 record__write(rec, &pad, padding);
297
298 return 0;
299}
300
301static int record__auxtrace_mmap_read(struct record *rec,
302 struct auxtrace_mmap *mm)
303{
304 int ret;
305
306 ret = auxtrace_mmap__read(mm, rec->itr, &rec->tool,
307 record__process_auxtrace);
308 if (ret < 0)
309 return ret;
310
311 if (ret)
312 rec->samples++;
313
314 return 0;
315}
316
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300317static int record__auxtrace_mmap_read_snapshot(struct record *rec,
318 struct auxtrace_mmap *mm)
319{
320 int ret;
321
322 ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool,
323 record__process_auxtrace,
324 rec->opts.auxtrace_snapshot_size);
325 if (ret < 0)
326 return ret;
327
328 if (ret)
329 rec->samples++;
330
331 return 0;
332}
333
334static int record__auxtrace_read_snapshot_all(struct record *rec)
335{
336 int i;
337 int rc = 0;
338
339 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
340 struct auxtrace_mmap *mm =
341 &rec->evlist->mmap[i].auxtrace_mmap;
342
343 if (!mm->base)
344 continue;
345
346 if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) {
347 rc = -1;
348 goto out;
349 }
350 }
351out:
352 return rc;
353}
354
355static void record__read_auxtrace_snapshot(struct record *rec)
356{
357 pr_debug("Recording AUX area tracing snapshot\n");
358 if (record__auxtrace_read_snapshot_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000359 trigger_error(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300360 } else {
Wang Nan5f9cf592016-04-20 18:59:49 +0000361 if (auxtrace_record__snapshot_finish(rec->itr))
362 trigger_error(&auxtrace_snapshot_trigger);
363 else
364 trigger_ready(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300365 }
366}
367
Adrian Huntere31f0d02015-04-30 17:37:27 +0300368#else
369
370static inline
371int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
372 struct auxtrace_mmap *mm __maybe_unused)
373{
374 return 0;
375}
376
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300377static inline
378void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
379{
380}
381
382static inline
383int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
384{
385 return 0;
386}
387
Adrian Huntere31f0d02015-04-30 17:37:27 +0300388#endif
389
Wang Nancda57a82016-06-27 10:24:03 +0000390static int record__mmap_evlist(struct record *rec,
391 struct perf_evlist *evlist)
392{
393 struct record_opts *opts = &rec->opts;
394 char msg[512];
395
396 if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
397 opts->auxtrace_mmap_pages,
398 opts->auxtrace_snapshot_mode) < 0) {
399 if (errno == EPERM) {
400 pr_err("Permission error mapping pages.\n"
401 "Consider increasing "
402 "/proc/sys/kernel/perf_event_mlock_kb,\n"
403 "or try again with a smaller value of -m/--mmap_pages.\n"
404 "(current value: %u,%u)\n",
405 opts->mmap_pages, opts->auxtrace_mmap_pages);
406 return -errno;
407 } else {
408 pr_err("failed to mmap with %d (%s)\n", errno,
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300409 str_error_r(errno, msg, sizeof(msg)));
Wang Nancda57a82016-06-27 10:24:03 +0000410 if (errno)
411 return -errno;
412 else
413 return -EINVAL;
414 }
415 }
416 return 0;
417}
418
419static int record__mmap(struct record *rec)
420{
421 return record__mmap_evlist(rec, rec->evlist);
422}
423
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300424static int record__open(struct record *rec)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200425{
Arnaldo Carvalho de Melod6195a62017-02-13 16:45:24 -0300426 char msg[BUFSIZ];
Jiri Olsa6a4bb042012-08-08 12:22:36 +0200427 struct perf_evsel *pos;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200428 struct perf_evlist *evlist = rec->evlist;
429 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300430 struct record_opts *opts = &rec->opts;
Mathieu Poirier5d8bb1e2016-09-16 09:50:03 -0600431 struct perf_evsel_config_term *err_term;
David Ahern8d3eca22012-08-26 12:24:47 -0600432 int rc = 0;
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200433
Arnaldo Carvalho de Meloe68ae9c2016-04-11 18:15:29 -0300434 perf_evlist__config(evlist, opts, &callchain_param);
Jiri Olsacac21422012-11-12 18:34:00 +0100435
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -0300436 evlist__for_each_entry(evlist, pos) {
Ingo Molnar3da297a2009-06-07 17:39:02 +0200437try_again:
Kan Liangd988d5e2015-08-21 02:23:14 -0400438 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300439 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
Namhyung Kimbb963e12017-02-17 17:17:38 +0900440 if (verbose > 0)
Arnaldo Carvalho de Meloc0a54342012-12-13 14:16:30 -0300441 ui__warning("%s\n", msg);
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300442 goto try_again;
443 }
David Ahernca6a4252011-03-25 13:11:11 -0600444
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300445 rc = -errno;
446 perf_evsel__open_strerror(pos, &opts->target,
447 errno, msg, sizeof(msg));
448 ui__error("%s\n", msg);
David Ahern8d3eca22012-08-26 12:24:47 -0600449 goto out;
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300450 }
Li Zefanc171b552009-10-15 11:22:07 +0800451 }
Arnaldo Carvalho de Meloa43d3f02010-12-25 12:12:25 -0200452
Arnaldo Carvalho de Melo23d4aad2015-03-24 19:23:47 -0300453 if (perf_evlist__apply_filters(evlist, &pos)) {
454 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
455 pos->filter, perf_evsel__name(pos), errno,
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300456 str_error_r(errno, msg, sizeof(msg)));
David Ahern8d3eca22012-08-26 12:24:47 -0600457 rc = -1;
458 goto out;
Frederic Weisbecker0a102472011-02-26 04:51:54 +0100459 }
460
Mathieu Poirier5d8bb1e2016-09-16 09:50:03 -0600461 if (perf_evlist__apply_drv_configs(evlist, &pos, &err_term)) {
462 error("failed to set config \"%s\" on event %s with %d (%s)\n",
463 err_term->val.drv_cfg, perf_evsel__name(pos), errno,
464 str_error_r(errno, msg, sizeof(msg)));
465 rc = -1;
466 goto out;
467 }
468
Wang Nancda57a82016-06-27 10:24:03 +0000469 rc = record__mmap(rec);
470 if (rc)
David Ahern8d3eca22012-08-26 12:24:47 -0600471 goto out;
Arnaldo Carvalho de Melo0a27d7f2011-01-14 15:50:51 -0200472
Jiri Olsa563aecb2013-06-05 13:35:06 +0200473 session->evlist = evlist;
Arnaldo Carvalho de Melo7b56cce2012-08-01 19:31:00 -0300474 perf_session__set_id_hdr_size(session);
David Ahern8d3eca22012-08-26 12:24:47 -0600475out:
476 return rc;
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200477}
478
Namhyung Kime3d59112015-01-29 17:06:44 +0900479static int process_sample_event(struct perf_tool *tool,
480 union perf_event *event,
481 struct perf_sample *sample,
482 struct perf_evsel *evsel,
483 struct machine *machine)
484{
485 struct record *rec = container_of(tool, struct record, tool);
486
487 rec->samples++;
488
489 return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
490}
491
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300492static int process_buildids(struct record *rec)
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200493{
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200494 struct perf_data_file *file = &rec->file;
495 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200496
He Kuang457ae942015-05-28 13:17:30 +0000497 if (file->size == 0)
Arnaldo Carvalho de Melo9f591fd2010-03-11 15:53:11 -0300498 return 0;
499
Namhyung Kim00dc8652014-11-04 10:14:32 +0900500 /*
501 * During this process, it'll load kernel map and replace the
502 * dso->long_name to a real pathname it found. In this case
503 * we prefer the vmlinux path like
504 * /lib/modules/3.16.4/build/vmlinux
505 *
506 * rather than build-id path (in debug directory).
507 * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551
508 */
509 symbol_conf.ignore_vmlinux_buildid = true;
510
Namhyung Kim61566812016-01-11 22:37:09 +0900511 /*
512 * If --buildid-all is given, it marks all DSO regardless of hits,
513 * so no need to process samples.
514 */
515 if (rec->buildid_all)
516 rec->tool.sample = NULL;
517
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300518 return perf_session__process_events(session);
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200519}
520
Arnaldo Carvalho de Melo8115d602011-01-29 14:01:45 -0200521static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800522{
523 int err;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200524 struct perf_tool *tool = data;
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800525 /*
526 *As for guest kernel when processing subcommand record&report,
527 *we arrange module mmap prior to guest kernel mmap and trigger
528 *a preload dso because default guest module symbols are loaded
529 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
530 *method is used to avoid symbol missing when the first addr is
531 *in module instead of in guest kernel.
532 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200533 err = perf_event__synthesize_modules(tool, process_synthesized_event,
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200534 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800535 if (err < 0)
536 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300537 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800538
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800539 /*
540 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
541 * have no _text sometimes.
542 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200543 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
Adrian Hunter0ae617b2014-01-29 16:14:40 +0200544 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800545 if (err < 0)
546 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300547 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800548}
549
Frederic Weisbecker98402802010-05-02 22:05:29 +0200550static struct perf_event_header finished_round_event = {
551 .size = sizeof(struct perf_event_header),
552 .type = PERF_RECORD_FINISHED_ROUND,
553};
554
Wang Nana4ea0ec2016-07-14 08:34:36 +0000555static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist,
556 bool backward)
Frederic Weisbecker98402802010-05-02 22:05:29 +0200557{
Jiri Olsadcabb502014-07-25 16:56:16 +0200558 u64 bytes_written = rec->bytes_written;
Peter Zijlstra0e2e63d2010-05-20 14:45:26 +0200559 int i;
David Ahern8d3eca22012-08-26 12:24:47 -0600560 int rc = 0;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000561 struct perf_mmap *maps;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200562
Wang Nancb216862016-06-27 10:24:04 +0000563 if (!evlist)
564 return 0;
Adrian Hunteref149c22015-04-09 18:53:45 +0300565
Wang Nanb2cb6152016-07-14 08:34:39 +0000566 maps = backward ? evlist->backward_mmap : evlist->mmap;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000567 if (!maps)
568 return 0;
Wang Nancb216862016-06-27 10:24:04 +0000569
Wang Nan54cc54d2016-07-14 08:34:42 +0000570 if (backward && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING)
571 return 0;
572
Wang Nana4ea0ec2016-07-14 08:34:36 +0000573 for (i = 0; i < evlist->nr_mmaps; i++) {
574 struct auxtrace_mmap *mm = &maps[i].auxtrace_mmap;
575
576 if (maps[i].base) {
577 if (record__mmap_read(rec, &maps[i],
578 evlist->overwrite, backward) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600579 rc = -1;
580 goto out;
581 }
582 }
Adrian Hunteref149c22015-04-09 18:53:45 +0300583
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300584 if (mm->base && !rec->opts.auxtrace_snapshot_mode &&
Adrian Hunteref149c22015-04-09 18:53:45 +0300585 record__auxtrace_mmap_read(rec, mm) != 0) {
586 rc = -1;
587 goto out;
588 }
Frederic Weisbecker98402802010-05-02 22:05:29 +0200589 }
590
Jiri Olsadcabb502014-07-25 16:56:16 +0200591 /*
592 * Mark the round finished in case we wrote
593 * at least one event.
594 */
595 if (bytes_written != rec->bytes_written)
596 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
David Ahern8d3eca22012-08-26 12:24:47 -0600597
Wang Nan54cc54d2016-07-14 08:34:42 +0000598 if (backward)
599 perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY);
David Ahern8d3eca22012-08-26 12:24:47 -0600600out:
601 return rc;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200602}
603
Wang Nancb216862016-06-27 10:24:04 +0000604static int record__mmap_read_all(struct record *rec)
605{
606 int err;
607
Wang Nana4ea0ec2016-07-14 08:34:36 +0000608 err = record__mmap_read_evlist(rec, rec->evlist, false);
Wang Nancb216862016-06-27 10:24:04 +0000609 if (err)
610 return err;
611
Wang Nan057374642016-07-14 08:34:43 +0000612 return record__mmap_read_evlist(rec, rec->evlist, true);
Wang Nancb216862016-06-27 10:24:04 +0000613}
614
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300615static void record__init_features(struct record *rec)
David Ahern57706ab2013-11-06 11:41:34 -0700616{
David Ahern57706ab2013-11-06 11:41:34 -0700617 struct perf_session *session = rec->session;
618 int feat;
619
620 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
621 perf_header__set_feat(&session->header, feat);
622
623 if (rec->no_buildid)
624 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
625
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300626 if (!have_tracepoints(&rec->evlist->entries))
David Ahern57706ab2013-11-06 11:41:34 -0700627 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
628
629 if (!rec->opts.branch_stack)
630 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
Adrian Hunteref149c22015-04-09 18:53:45 +0300631
632 if (!rec->opts.full_auxtrace)
633 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
Jiri Olsaffa517a2015-10-25 15:51:43 +0100634
635 perf_header__clear_feat(&session->header, HEADER_STAT);
David Ahern57706ab2013-11-06 11:41:34 -0700636}
637
Wang Nane1ab48b2016-02-26 09:32:10 +0000638static void
639record__finish_output(struct record *rec)
640{
641 struct perf_data_file *file = &rec->file;
642 int fd = perf_data_file__fd(file);
643
644 if (file->is_pipe)
645 return;
646
647 rec->session->header.data_size += rec->bytes_written;
648 file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR);
649
650 if (!rec->no_buildid) {
651 process_buildids(rec);
652
653 if (rec->buildid_all)
654 dsos__hit_all(rec->session);
655 }
656 perf_session__write_header(rec->session, rec->evlist, fd, true);
657
658 return;
659}
660
Wang Nan4ea648a2016-07-14 08:34:47 +0000661static int record__synthesize_workload(struct record *rec, bool tail)
Wang Nanbe7b0c92016-04-20 18:59:54 +0000662{
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -0300663 int err;
664 struct thread_map *thread_map;
Wang Nanbe7b0c92016-04-20 18:59:54 +0000665
Wang Nan4ea648a2016-07-14 08:34:47 +0000666 if (rec->opts.tail_synthesize != tail)
667 return 0;
668
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -0300669 thread_map = thread_map__new_by_tid(rec->evlist->workload.pid);
670 if (thread_map == NULL)
671 return -1;
672
673 err = perf_event__synthesize_thread_map(&rec->tool, thread_map,
Wang Nanbe7b0c92016-04-20 18:59:54 +0000674 process_synthesized_event,
675 &rec->session->machines.host,
676 rec->opts.sample_address,
677 rec->opts.proc_map_timeout);
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -0300678 thread_map__put(thread_map);
679 return err;
Wang Nanbe7b0c92016-04-20 18:59:54 +0000680}
681
Wang Nan4ea648a2016-07-14 08:34:47 +0000682static int record__synthesize(struct record *rec, bool tail);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000683
Wang Nanecfd7a92016-04-13 08:21:07 +0000684static int
685record__switch_output(struct record *rec, bool at_exit)
686{
687 struct perf_data_file *file = &rec->file;
688 int fd, err;
689
690 /* Same Size: "2015122520103046"*/
691 char timestamp[] = "InvalidTimestamp";
692
Wang Nan4ea648a2016-07-14 08:34:47 +0000693 record__synthesize(rec, true);
694 if (target__none(&rec->opts.target))
695 record__synthesize_workload(rec, true);
696
Wang Nanecfd7a92016-04-13 08:21:07 +0000697 rec->samples = 0;
698 record__finish_output(rec);
699 err = fetch_current_timestamp(timestamp, sizeof(timestamp));
700 if (err) {
701 pr_err("Failed to get current timestamp\n");
702 return -EINVAL;
703 }
704
705 fd = perf_data_file__switch(file, timestamp,
706 rec->session->header.data_offset,
707 at_exit);
708 if (fd >= 0 && !at_exit) {
709 rec->bytes_written = 0;
710 rec->session->header.data_size = 0;
711 }
712
713 if (!quiet)
714 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
715 file->path, timestamp);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000716
717 /* Output tracking events */
Wang Nanbe7b0c92016-04-20 18:59:54 +0000718 if (!at_exit) {
Wang Nan4ea648a2016-07-14 08:34:47 +0000719 record__synthesize(rec, false);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000720
Wang Nanbe7b0c92016-04-20 18:59:54 +0000721 /*
722 * In 'perf record --switch-output' without -a,
723 * record__synthesize() in record__switch_output() won't
724 * generate tracking events because there's no thread_map
725 * in evlist. Which causes newly created perf.data doesn't
726 * contain map and comm information.
727 * Create a fake thread_map and directly call
728 * perf_event__synthesize_thread_map() for those events.
729 */
730 if (target__none(&rec->opts.target))
Wang Nan4ea648a2016-07-14 08:34:47 +0000731 record__synthesize_workload(rec, false);
Wang Nanbe7b0c92016-04-20 18:59:54 +0000732 }
Wang Nanecfd7a92016-04-13 08:21:07 +0000733 return fd;
734}
735
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300736static volatile int workload_exec_errno;
737
738/*
739 * perf_evlist__prepare_workload will send a SIGUSR1
740 * if the fork fails, since we asked by setting its
741 * want_signal to true.
742 */
Namhyung Kim45604712014-05-12 09:47:24 +0900743static void workload_exec_failed_signal(int signo __maybe_unused,
744 siginfo_t *info,
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300745 void *ucontext __maybe_unused)
746{
747 workload_exec_errno = info->si_value.sival_int;
748 done = 1;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300749 child_finished = 1;
750}
751
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300752static void snapshot_sig_handler(int sig);
Jiri Olsabfacbe32017-01-09 10:52:00 +0100753static void alarm_sig_handler(int sig);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300754
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200755int __weak
756perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
757 struct perf_tool *tool __maybe_unused,
758 perf_event__handler_t process __maybe_unused,
759 struct machine *machine __maybe_unused)
760{
761 return 0;
762}
763
Wang Nanee667f92016-06-27 10:24:05 +0000764static const struct perf_event_mmap_page *
765perf_evlist__pick_pc(struct perf_evlist *evlist)
766{
Wang Nanb2cb6152016-07-14 08:34:39 +0000767 if (evlist) {
768 if (evlist->mmap && evlist->mmap[0].base)
769 return evlist->mmap[0].base;
770 if (evlist->backward_mmap && evlist->backward_mmap[0].base)
771 return evlist->backward_mmap[0].base;
772 }
Wang Nanee667f92016-06-27 10:24:05 +0000773 return NULL;
774}
775
Wang Nanc45628b2016-05-24 02:28:59 +0000776static const struct perf_event_mmap_page *record__pick_pc(struct record *rec)
777{
Wang Nanee667f92016-06-27 10:24:05 +0000778 const struct perf_event_mmap_page *pc;
779
780 pc = perf_evlist__pick_pc(rec->evlist);
781 if (pc)
782 return pc;
Wang Nanc45628b2016-05-24 02:28:59 +0000783 return NULL;
784}
785
Wang Nan4ea648a2016-07-14 08:34:47 +0000786static int record__synthesize(struct record *rec, bool tail)
Wang Nanc45c86e2016-02-26 09:32:07 +0000787{
788 struct perf_session *session = rec->session;
789 struct machine *machine = &session->machines.host;
790 struct perf_data_file *file = &rec->file;
791 struct record_opts *opts = &rec->opts;
792 struct perf_tool *tool = &rec->tool;
793 int fd = perf_data_file__fd(file);
794 int err = 0;
795
Wang Nan4ea648a2016-07-14 08:34:47 +0000796 if (rec->opts.tail_synthesize != tail)
797 return 0;
798
Wang Nanc45c86e2016-02-26 09:32:07 +0000799 if (file->is_pipe) {
800 err = perf_event__synthesize_attrs(tool, session,
801 process_synthesized_event);
802 if (err < 0) {
803 pr_err("Couldn't synthesize attrs.\n");
804 goto out;
805 }
806
807 if (have_tracepoints(&rec->evlist->entries)) {
808 /*
809 * FIXME err <= 0 here actually means that
810 * there were no tracepoints so its not really
811 * an error, just that we don't need to
812 * synthesize anything. We really have to
813 * return this more properly and also
814 * propagate errors that now are calling die()
815 */
816 err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
817 process_synthesized_event);
818 if (err <= 0) {
819 pr_err("Couldn't record tracing data.\n");
820 goto out;
821 }
822 rec->bytes_written += err;
823 }
824 }
825
Wang Nanc45628b2016-05-24 02:28:59 +0000826 err = perf_event__synth_time_conv(record__pick_pc(rec), tool,
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200827 process_synthesized_event, machine);
828 if (err)
829 goto out;
830
Wang Nanc45c86e2016-02-26 09:32:07 +0000831 if (rec->opts.full_auxtrace) {
832 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
833 session, process_synthesized_event);
834 if (err)
835 goto out;
836 }
837
838 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
839 machine);
840 WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
841 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
842 "Check /proc/kallsyms permission or run as root.\n");
843
844 err = perf_event__synthesize_modules(tool, process_synthesized_event,
845 machine);
846 WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
847 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
848 "Check /proc/modules permission or run as root.\n");
849
850 if (perf_guest) {
851 machines__process_guests(&session->machines,
852 perf_event__synthesize_guest_os, tool);
853 }
854
855 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
856 process_synthesized_event, opts->sample_address,
857 opts->proc_map_timeout);
858out:
859 return err;
860}
861
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300862static int __cmd_record(struct record *rec, int argc, const char **argv)
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200863{
David Ahern57706ab2013-11-06 11:41:34 -0700864 int err;
Namhyung Kim45604712014-05-12 09:47:24 +0900865 int status = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200866 unsigned long waking = 0;
Zhang, Yanmin46be6042010-03-18 11:36:04 -0300867 const bool forks = argc > 0;
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300868 struct machine *machine;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200869 struct perf_tool *tool = &rec->tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300870 struct record_opts *opts = &rec->opts;
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200871 struct perf_data_file *file = &rec->file;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200872 struct perf_session *session;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300873 bool disabled = false, draining = false;
Namhyung Kim42aa2762015-01-29 17:06:48 +0900874 int fd;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200875
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200876 rec->progname = argv[0];
Andi Kleen33e49ea2011-09-15 14:31:40 -0700877
Namhyung Kim45604712014-05-12 09:47:24 +0900878 atexit(record__sig_exit);
Peter Zijlstraf5970552009-06-18 23:22:55 +0200879 signal(SIGCHLD, sig_handler);
880 signal(SIGINT, sig_handler);
David Ahern804f7ac2013-05-06 12:24:23 -0600881 signal(SIGTERM, sig_handler);
Wang Nana0748652016-11-26 07:03:28 +0000882 signal(SIGSEGV, sigsegv_handler);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000883
Hari Bathinif3b36142017-03-08 02:11:43 +0530884 if (rec->opts.record_namespaces)
885 tool->namespace_events = true;
886
Jiri Olsadc0c6122017-01-09 10:51:58 +0100887 if (rec->opts.auxtrace_snapshot_mode || rec->switch_output.enabled) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300888 signal(SIGUSR2, snapshot_sig_handler);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000889 if (rec->opts.auxtrace_snapshot_mode)
890 trigger_on(&auxtrace_snapshot_trigger);
Jiri Olsadc0c6122017-01-09 10:51:58 +0100891 if (rec->switch_output.enabled)
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000892 trigger_on(&switch_output_trigger);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000893 } else {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300894 signal(SIGUSR2, SIG_IGN);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000895 }
Peter Zijlstraf5970552009-06-18 23:22:55 +0200896
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300897 session = perf_session__new(file, false, tool);
Arnaldo Carvalho de Melo94c744b2009-12-11 21:24:02 -0200898 if (session == NULL) {
Adrien BAKffa91882014-04-18 11:00:43 +0900899 pr_err("Perf session creation failed.\n");
Arnaldo Carvalho de Meloa9a70bb2009-11-17 01:18:11 -0200900 return -1;
901 }
902
Namhyung Kim42aa2762015-01-29 17:06:48 +0900903 fd = perf_data_file__fd(file);
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200904 rec->session = session;
905
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300906 record__init_features(rec);
Stephane Eranian330aa672012-03-08 23:47:46 +0100907
Arnaldo Carvalho de Melod4db3f12009-12-27 21:36:57 -0200908 if (forks) {
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300909 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200910 argv, file->is_pipe,
Arnaldo Carvalho de Melo735f7e02014-01-03 14:56:49 -0300911 workload_exec_failed_signal);
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200912 if (err < 0) {
913 pr_err("Couldn't run the workload!\n");
Namhyung Kim45604712014-05-12 09:47:24 +0900914 status = err;
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200915 goto out_delete_session;
Jens Axboe0a5ac842009-08-12 11:18:01 +0200916 }
Peter Zijlstra856e9662009-12-16 17:55:55 +0100917 }
918
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300919 if (record__open(rec) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600920 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900921 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600922 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200923
Wang Nan8690a2a2016-02-22 09:10:32 +0000924 err = bpf__apply_obj_config();
925 if (err) {
926 char errbuf[BUFSIZ];
927
928 bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
929 pr_err("ERROR: Apply config to BPF failed: %s\n",
930 errbuf);
931 goto out_child;
932 }
933
Adrian Huntercca84822015-08-19 17:29:21 +0300934 /*
935 * Normally perf_session__new would do this, but it doesn't have the
936 * evlist.
937 */
938 if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
939 pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
940 rec->tool.ordered_events = false;
941 }
942
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300943 if (!rec->evlist->nr_groups)
Namhyung Kima8bb5592013-01-22 18:09:31 +0900944 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
945
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200946 if (file->is_pipe) {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900947 err = perf_header__write_pipe(fd);
Tom Zanussi529870e2010-04-01 23:59:16 -0500948 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900949 goto out_child;
Jiri Olsa563aecb2013-06-05 13:35:06 +0200950 } else {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900951 err = perf_session__write_header(session, rec->evlist, fd, false);
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200952 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900953 goto out_child;
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200954 }
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +0200955
David Ahernd3665492012-02-06 15:27:52 -0700956 if (!rec->no_buildid
Robert Richtere20960c2011-12-07 10:02:55 +0100957 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
David Ahernd3665492012-02-06 15:27:52 -0700958 pr_err("Couldn't generate buildids. "
Robert Richtere20960c2011-12-07 10:02:55 +0100959 "Use --no-buildid to profile anyway.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600960 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900961 goto out_child;
Robert Richtere20960c2011-12-07 10:02:55 +0100962 }
963
Arnaldo Carvalho de Melo34ba5122012-12-19 09:04:24 -0300964 machine = &session->machines.host;
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200965
Wang Nan4ea648a2016-07-14 08:34:47 +0000966 err = record__synthesize(rec, false);
Wang Nanc45c86e2016-02-26 09:32:07 +0000967 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900968 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600969
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200970 if (rec->realtime_prio) {
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200971 struct sched_param param;
972
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200973 param.sched_priority = rec->realtime_prio;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200974 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
Arnaldo Carvalho de Melo6beba7a2009-10-21 17:34:06 -0200975 pr_err("Could not set realtime priority.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600976 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900977 goto out_child;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200978 }
979 }
980
Jiri Olsa774cb492012-11-12 18:34:01 +0100981 /*
982 * When perf is starting the traced process, all the events
983 * (apart from group members) have enable_on_exec=1 set,
984 * so don't spoil it by prematurely enabling them.
985 */
Andi Kleen6619a532014-01-11 13:38:27 -0800986 if (!target__none(&opts->target) && !opts->initial_delay)
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300987 perf_evlist__enable(rec->evlist);
David Ahern764e16a32011-08-25 10:17:55 -0600988
Peter Zijlstra856e9662009-12-16 17:55:55 +0100989 /*
990 * Let the child rip
991 */
Namhyung Kime803cf92015-09-22 09:24:55 +0900992 if (forks) {
Namhyung Kime5bed562015-09-30 10:45:24 +0900993 union perf_event *event;
Hari Bathinie907caf2017-03-08 02:11:51 +0530994 pid_t tgid;
Namhyung Kime5bed562015-09-30 10:45:24 +0900995
996 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
997 if (event == NULL) {
998 err = -ENOMEM;
999 goto out_child;
1000 }
1001
Namhyung Kime803cf92015-09-22 09:24:55 +09001002 /*
1003 * Some H/W events are generated before COMM event
1004 * which is emitted during exec(), so perf script
1005 * cannot see a correct process name for those events.
1006 * Synthesize COMM event to prevent it.
1007 */
Hari Bathinie907caf2017-03-08 02:11:51 +05301008 tgid = perf_event__synthesize_comm(tool, event,
1009 rec->evlist->workload.pid,
1010 process_synthesized_event,
1011 machine);
1012 free(event);
1013
1014 if (tgid == -1)
1015 goto out_child;
1016
1017 event = malloc(sizeof(event->namespaces) +
1018 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
1019 machine->id_hdr_size);
1020 if (event == NULL) {
1021 err = -ENOMEM;
1022 goto out_child;
1023 }
1024
1025 /*
1026 * Synthesize NAMESPACES event for the command specified.
1027 */
1028 perf_event__synthesize_namespaces(tool, event,
1029 rec->evlist->workload.pid,
1030 tgid, process_synthesized_event,
1031 machine);
Namhyung Kime5bed562015-09-30 10:45:24 +09001032 free(event);
Namhyung Kime803cf92015-09-22 09:24:55 +09001033
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001034 perf_evlist__start_workload(rec->evlist);
Namhyung Kime803cf92015-09-22 09:24:55 +09001035 }
Peter Zijlstra856e9662009-12-16 17:55:55 +01001036
Andi Kleen6619a532014-01-11 13:38:27 -08001037 if (opts->initial_delay) {
Arnaldo Carvalho de Melo0693e682016-08-08 15:05:46 -03001038 usleep(opts->initial_delay * USEC_PER_MSEC);
Andi Kleen6619a532014-01-11 13:38:27 -08001039 perf_evlist__enable(rec->evlist);
1040 }
1041
Wang Nan5f9cf592016-04-20 18:59:49 +00001042 trigger_ready(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001043 trigger_ready(&switch_output_trigger);
Wang Nana0748652016-11-26 07:03:28 +00001044 perf_hooks__invoke_record_start();
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001045 for (;;) {
Yang Shi9f065192015-09-29 14:49:43 -07001046 unsigned long long hits = rec->samples;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001047
Wang Nan057374642016-07-14 08:34:43 +00001048 /*
1049 * rec->evlist->bkw_mmap_state is possible to be
1050 * BKW_MMAP_EMPTY here: when done == true and
1051 * hits != rec->samples in previous round.
1052 *
1053 * perf_evlist__toggle_bkw_mmap ensure we never
1054 * convert BKW_MMAP_EMPTY to BKW_MMAP_DATA_PENDING.
1055 */
1056 if (trigger_is_hit(&switch_output_trigger) || done || draining)
1057 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_DATA_PENDING);
1058
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001059 if (record__mmap_read_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +00001060 trigger_error(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001061 trigger_error(&switch_output_trigger);
David Ahern8d3eca22012-08-26 12:24:47 -06001062 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001063 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -06001064 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001065
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001066 if (auxtrace_record__snapshot_started) {
1067 auxtrace_record__snapshot_started = 0;
Wang Nan5f9cf592016-04-20 18:59:49 +00001068 if (!trigger_is_error(&auxtrace_snapshot_trigger))
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001069 record__read_auxtrace_snapshot(rec);
Wang Nan5f9cf592016-04-20 18:59:49 +00001070 if (trigger_is_error(&auxtrace_snapshot_trigger)) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001071 pr_err("AUX area tracing snapshot failed\n");
1072 err = -1;
1073 goto out_child;
1074 }
1075 }
1076
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001077 if (trigger_is_hit(&switch_output_trigger)) {
Wang Nan057374642016-07-14 08:34:43 +00001078 /*
1079 * If switch_output_trigger is hit, the data in
1080 * overwritable ring buffer should have been collected,
1081 * so bkw_mmap_state should be set to BKW_MMAP_EMPTY.
1082 *
1083 * If SIGUSR2 raise after or during record__mmap_read_all(),
1084 * record__mmap_read_all() didn't collect data from
1085 * overwritable ring buffer. Read again.
1086 */
1087 if (rec->evlist->bkw_mmap_state == BKW_MMAP_RUNNING)
1088 continue;
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001089 trigger_ready(&switch_output_trigger);
1090
Wang Nan057374642016-07-14 08:34:43 +00001091 /*
1092 * Reenable events in overwrite ring buffer after
1093 * record__mmap_read_all(): we should have collected
1094 * data from it.
1095 */
1096 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_RUNNING);
1097
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001098 if (!quiet)
1099 fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
1100 waking);
1101 waking = 0;
1102 fd = record__switch_output(rec, false);
1103 if (fd < 0) {
1104 pr_err("Failed to switch to new file\n");
1105 trigger_error(&switch_output_trigger);
1106 err = fd;
1107 goto out_child;
1108 }
Jiri Olsabfacbe32017-01-09 10:52:00 +01001109
1110 /* re-arm the alarm */
1111 if (rec->switch_output.time)
1112 alarm(rec->switch_output.time);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001113 }
1114
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001115 if (hits == rec->samples) {
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001116 if (done || draining)
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001117 break;
Arnaldo Carvalho de Melof66a8892014-08-18 17:25:59 -03001118 err = perf_evlist__poll(rec->evlist, -1);
Jiri Olsaa5151142014-06-02 13:44:23 -04001119 /*
1120 * Propagate error, only if there's any. Ignore positive
1121 * number of returned events and interrupt error.
1122 */
1123 if (err > 0 || (err < 0 && errno == EINTR))
Namhyung Kim45604712014-05-12 09:47:24 +09001124 err = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001125 waking++;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001126
1127 if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
1128 draining = true;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001129 }
1130
Jiri Olsa774cb492012-11-12 18:34:01 +01001131 /*
1132 * When perf is starting the traced process, at the end events
1133 * die with the process and we wait for that. Thus no need to
1134 * disable events in this case.
1135 */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001136 if (done && !disabled && !target__none(&opts->target)) {
Wang Nan5f9cf592016-04-20 18:59:49 +00001137 trigger_off(&auxtrace_snapshot_trigger);
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001138 perf_evlist__disable(rec->evlist);
Jiri Olsa27119262012-11-12 18:34:02 +01001139 disabled = true;
1140 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001141 }
Wang Nan5f9cf592016-04-20 18:59:49 +00001142 trigger_off(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001143 trigger_off(&switch_output_trigger);
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001144
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001145 if (forks && workload_exec_errno) {
Masami Hiramatsu35550da2014-08-14 02:22:43 +00001146 char msg[STRERR_BUFSIZE];
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -03001147 const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001148 pr_err("Workload failed: %s\n", emsg);
1149 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001150 goto out_child;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001151 }
1152
Namhyung Kime3d59112015-01-29 17:06:44 +09001153 if (!quiet)
Namhyung Kim45604712014-05-12 09:47:24 +09001154 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001155
Wang Nan4ea648a2016-07-14 08:34:47 +00001156 if (target__none(&rec->opts.target))
1157 record__synthesize_workload(rec, true);
1158
Namhyung Kim45604712014-05-12 09:47:24 +09001159out_child:
1160 if (forks) {
1161 int exit_status;
Ingo Molnaraddc2782009-06-02 23:43:11 +02001162
Namhyung Kim45604712014-05-12 09:47:24 +09001163 if (!child_finished)
1164 kill(rec->evlist->workload.pid, SIGTERM);
1165
1166 wait(&exit_status);
1167
1168 if (err < 0)
1169 status = err;
1170 else if (WIFEXITED(exit_status))
1171 status = WEXITSTATUS(exit_status);
1172 else if (WIFSIGNALED(exit_status))
1173 signr = WTERMSIG(exit_status);
1174 } else
1175 status = err;
1176
Wang Nan4ea648a2016-07-14 08:34:47 +00001177 record__synthesize(rec, true);
Namhyung Kime3d59112015-01-29 17:06:44 +09001178 /* this will be recalculated during process_buildids() */
1179 rec->samples = 0;
1180
Wang Nanecfd7a92016-04-13 08:21:07 +00001181 if (!err) {
1182 if (!rec->timestamp_filename) {
1183 record__finish_output(rec);
1184 } else {
1185 fd = record__switch_output(rec, true);
1186 if (fd < 0) {
1187 status = fd;
1188 goto out_delete_session;
1189 }
1190 }
1191 }
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001192
Wang Nana0748652016-11-26 07:03:28 +00001193 perf_hooks__invoke_record_end();
1194
Namhyung Kime3d59112015-01-29 17:06:44 +09001195 if (!err && !quiet) {
1196 char samples[128];
Wang Nanecfd7a92016-04-13 08:21:07 +00001197 const char *postfix = rec->timestamp_filename ?
1198 ".<timestamp>" : "";
Namhyung Kime3d59112015-01-29 17:06:44 +09001199
Adrian Hunteref149c22015-04-09 18:53:45 +03001200 if (rec->samples && !rec->opts.full_auxtrace)
Namhyung Kime3d59112015-01-29 17:06:44 +09001201 scnprintf(samples, sizeof(samples),
1202 " (%" PRIu64 " samples)", rec->samples);
1203 else
1204 samples[0] = '\0';
1205
Wang Nanecfd7a92016-04-13 08:21:07 +00001206 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
Namhyung Kime3d59112015-01-29 17:06:44 +09001207 perf_data_file__size(file) / 1024.0 / 1024.0,
Wang Nanecfd7a92016-04-13 08:21:07 +00001208 file->path, postfix, samples);
Namhyung Kime3d59112015-01-29 17:06:44 +09001209 }
1210
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001211out_delete_session:
1212 perf_session__delete(session);
Namhyung Kim45604712014-05-12 09:47:24 +09001213 return status;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001214}
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001215
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001216static void callchain_debug(struct callchain_param *callchain)
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001217{
Kan Liangaad2b212015-01-05 13:23:04 -05001218 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
Jiri Olsaa601fdf2014-02-03 12:44:43 +01001219
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001220 pr_debug("callchain: type %s\n", str[callchain->record_mode]);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001221
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001222 if (callchain->record_mode == CALLCHAIN_DWARF)
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001223 pr_debug("callchain: stack dump size %d\n",
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001224 callchain->dump_size);
1225}
1226
1227int record_opts__parse_callchain(struct record_opts *record,
1228 struct callchain_param *callchain,
1229 const char *arg, bool unset)
1230{
1231 int ret;
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001232 callchain->enabled = !unset;
1233
1234 /* --no-call-graph */
1235 if (unset) {
1236 callchain->record_mode = CALLCHAIN_NONE;
1237 pr_debug("callchain: disabled\n");
1238 return 0;
1239 }
1240
1241 ret = parse_callchain_record_opt(arg, callchain);
1242 if (!ret) {
1243 /* Enable data address sampling for DWARF unwind. */
1244 if (callchain->record_mode == CALLCHAIN_DWARF)
1245 record->sample_address = true;
1246 callchain_debug(callchain);
1247 }
1248
1249 return ret;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001250}
1251
Kan Liangc421e802015-07-29 05:42:12 -04001252int record_parse_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001253 const char *arg,
1254 int unset)
1255{
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001256 return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
Jiri Olsa26d33022012-08-07 15:20:47 +02001257}
1258
Kan Liangc421e802015-07-29 05:42:12 -04001259int record_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001260 const char *arg __maybe_unused,
1261 int unset __maybe_unused)
1262{
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001263 struct callchain_param *callchain = opt->value;
Kan Liangc421e802015-07-29 05:42:12 -04001264
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001265 callchain->enabled = true;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001266
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001267 if (callchain->record_mode == CALLCHAIN_NONE)
1268 callchain->record_mode = CALLCHAIN_FP;
Jiri Olsaeb853e82014-02-03 12:44:42 +01001269
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001270 callchain_debug(callchain);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001271 return 0;
1272}
1273
Jiri Olsaeb853e82014-02-03 12:44:42 +01001274static int perf_record_config(const char *var, const char *value, void *cb)
1275{
Namhyung Kim7a29c082015-12-15 10:49:56 +09001276 struct record *rec = cb;
1277
1278 if (!strcmp(var, "record.build-id")) {
1279 if (!strcmp(value, "cache"))
1280 rec->no_buildid_cache = false;
1281 else if (!strcmp(value, "no-cache"))
1282 rec->no_buildid_cache = true;
1283 else if (!strcmp(value, "skip"))
1284 rec->no_buildid = true;
1285 else
1286 return -1;
1287 return 0;
1288 }
Jiri Olsaeb853e82014-02-03 12:44:42 +01001289 if (!strcmp(var, "record.call-graph"))
Namhyung Kim5a2e5e82014-09-23 10:01:44 +09001290 var = "call-graph.record-mode"; /* fall-through */
Jiri Olsaeb853e82014-02-03 12:44:42 +01001291
1292 return perf_default_config(var, value, cb);
1293}
1294
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001295struct clockid_map {
1296 const char *name;
1297 int clockid;
1298};
1299
1300#define CLOCKID_MAP(n, c) \
1301 { .name = n, .clockid = (c), }
1302
1303#define CLOCKID_END { .name = NULL, }
1304
1305
1306/*
1307 * Add the missing ones, we need to build on many distros...
1308 */
1309#ifndef CLOCK_MONOTONIC_RAW
1310#define CLOCK_MONOTONIC_RAW 4
1311#endif
1312#ifndef CLOCK_BOOTTIME
1313#define CLOCK_BOOTTIME 7
1314#endif
1315#ifndef CLOCK_TAI
1316#define CLOCK_TAI 11
1317#endif
1318
1319static const struct clockid_map clockids[] = {
1320 /* available for all events, NMI safe */
1321 CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
1322 CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
1323
1324 /* available for some events */
1325 CLOCKID_MAP("realtime", CLOCK_REALTIME),
1326 CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
1327 CLOCKID_MAP("tai", CLOCK_TAI),
1328
1329 /* available for the lazy */
1330 CLOCKID_MAP("mono", CLOCK_MONOTONIC),
1331 CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
1332 CLOCKID_MAP("real", CLOCK_REALTIME),
1333 CLOCKID_MAP("boot", CLOCK_BOOTTIME),
1334
1335 CLOCKID_END,
1336};
1337
1338static int parse_clockid(const struct option *opt, const char *str, int unset)
1339{
1340 struct record_opts *opts = (struct record_opts *)opt->value;
1341 const struct clockid_map *cm;
1342 const char *ostr = str;
1343
1344 if (unset) {
1345 opts->use_clockid = 0;
1346 return 0;
1347 }
1348
1349 /* no arg passed */
1350 if (!str)
1351 return 0;
1352
1353 /* no setting it twice */
1354 if (opts->use_clockid)
1355 return -1;
1356
1357 opts->use_clockid = true;
1358
1359 /* if its a number, we're done */
1360 if (sscanf(str, "%d", &opts->clockid) == 1)
1361 return 0;
1362
1363 /* allow a "CLOCK_" prefix to the name */
1364 if (!strncasecmp(str, "CLOCK_", 6))
1365 str += 6;
1366
1367 for (cm = clockids; cm->name; cm++) {
1368 if (!strcasecmp(str, cm->name)) {
1369 opts->clockid = cm->clockid;
1370 return 0;
1371 }
1372 }
1373
1374 opts->use_clockid = false;
1375 ui__warning("unknown clockid %s, check man page\n", ostr);
1376 return -1;
1377}
1378
Adrian Huntere9db1312015-04-09 18:53:46 +03001379static int record__parse_mmap_pages(const struct option *opt,
1380 const char *str,
1381 int unset __maybe_unused)
1382{
1383 struct record_opts *opts = opt->value;
1384 char *s, *p;
1385 unsigned int mmap_pages;
1386 int ret;
1387
1388 if (!str)
1389 return -EINVAL;
1390
1391 s = strdup(str);
1392 if (!s)
1393 return -ENOMEM;
1394
1395 p = strchr(s, ',');
1396 if (p)
1397 *p = '\0';
1398
1399 if (*s) {
1400 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
1401 if (ret)
1402 goto out_free;
1403 opts->mmap_pages = mmap_pages;
1404 }
1405
1406 if (!p) {
1407 ret = 0;
1408 goto out_free;
1409 }
1410
1411 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
1412 if (ret)
1413 goto out_free;
1414
1415 opts->auxtrace_mmap_pages = mmap_pages;
1416
1417out_free:
1418 free(s);
1419 return ret;
1420}
1421
Jiri Olsa0c582442017-01-09 10:51:59 +01001422static void switch_output_size_warn(struct record *rec)
1423{
1424 u64 wakeup_size = perf_evlist__mmap_size(rec->opts.mmap_pages);
1425 struct switch_output *s = &rec->switch_output;
1426
1427 wakeup_size /= 2;
1428
1429 if (s->size < wakeup_size) {
1430 char buf[100];
1431
1432 unit_number__scnprintf(buf, sizeof(buf), wakeup_size);
1433 pr_warning("WARNING: switch-output data size lower than "
1434 "wakeup kernel buffer size (%s) "
1435 "expect bigger perf.data sizes\n", buf);
1436 }
1437}
1438
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001439static int switch_output_setup(struct record *rec)
1440{
1441 struct switch_output *s = &rec->switch_output;
Jiri Olsadc0c6122017-01-09 10:51:58 +01001442 static struct parse_tag tags_size[] = {
1443 { .tag = 'B', .mult = 1 },
1444 { .tag = 'K', .mult = 1 << 10 },
1445 { .tag = 'M', .mult = 1 << 20 },
1446 { .tag = 'G', .mult = 1 << 30 },
1447 { .tag = 0 },
1448 };
Jiri Olsabfacbe32017-01-09 10:52:00 +01001449 static struct parse_tag tags_time[] = {
1450 { .tag = 's', .mult = 1 },
1451 { .tag = 'm', .mult = 60 },
1452 { .tag = 'h', .mult = 60*60 },
1453 { .tag = 'd', .mult = 60*60*24 },
1454 { .tag = 0 },
1455 };
Jiri Olsadc0c6122017-01-09 10:51:58 +01001456 unsigned long val;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001457
1458 if (!s->set)
1459 return 0;
1460
1461 if (!strcmp(s->str, "signal")) {
1462 s->signal = true;
1463 pr_debug("switch-output with SIGUSR2 signal\n");
Jiri Olsadc0c6122017-01-09 10:51:58 +01001464 goto enabled;
1465 }
1466
1467 val = parse_tag_value(s->str, tags_size);
1468 if (val != (unsigned long) -1) {
1469 s->size = val;
1470 pr_debug("switch-output with %s size threshold\n", s->str);
1471 goto enabled;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001472 }
1473
Jiri Olsabfacbe32017-01-09 10:52:00 +01001474 val = parse_tag_value(s->str, tags_time);
1475 if (val != (unsigned long) -1) {
1476 s->time = val;
1477 pr_debug("switch-output with %s time threshold (%lu seconds)\n",
1478 s->str, s->time);
1479 goto enabled;
1480 }
1481
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001482 return -1;
Jiri Olsadc0c6122017-01-09 10:51:58 +01001483
1484enabled:
1485 rec->timestamp_filename = true;
1486 s->enabled = true;
Jiri Olsa0c582442017-01-09 10:51:59 +01001487
1488 if (s->size && !rec->opts.no_buffering)
1489 switch_output_size_warn(rec);
1490
Jiri Olsadc0c6122017-01-09 10:51:58 +01001491 return 0;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001492}
1493
Namhyung Kime5b2c202014-10-23 00:15:46 +09001494static const char * const __record_usage[] = {
Mike Galbraith9e0967532009-05-28 16:25:34 +02001495 "perf record [<options>] [<command>]",
1496 "perf record [<options>] -- <command> [<options>]",
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001497 NULL
1498};
Namhyung Kime5b2c202014-10-23 00:15:46 +09001499const char * const *record_usage = __record_usage;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001500
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001501/*
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001502 * XXX Ideally would be local to cmd_record() and passed to a record__new
1503 * because we need to have access to it in record__exit, that is called
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001504 * after cmd_record() exits, but since record_options need to be accessible to
1505 * builtin-script, leave it here.
1506 *
1507 * At least we don't ouch it in all the other functions here directly.
1508 *
1509 * Just say no to tons of global variables, sigh.
1510 */
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001511static struct record record = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001512 .opts = {
Andi Kleen8affc2b2014-07-31 14:45:04 +08001513 .sample_time = true,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001514 .mmap_pages = UINT_MAX,
1515 .user_freq = UINT_MAX,
1516 .user_interval = ULLONG_MAX,
Arnaldo Carvalho de Melo447a6012012-05-22 13:14:18 -03001517 .freq = 4000,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001518 .target = {
1519 .uses_mmap = true,
Adrian Hunter3aa59392013-11-15 15:52:29 +02001520 .default_per_cpu = true,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001521 },
Kan Liang9d9cad72015-06-17 09:51:11 -04001522 .proc_map_timeout = 500,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001523 },
Namhyung Kime3d59112015-01-29 17:06:44 +09001524 .tool = {
1525 .sample = process_sample_event,
1526 .fork = perf_event__process_fork,
Adrian Huntercca84822015-08-19 17:29:21 +03001527 .exit = perf_event__process_exit,
Namhyung Kime3d59112015-01-29 17:06:44 +09001528 .comm = perf_event__process_comm,
Hari Bathinif3b36142017-03-08 02:11:43 +05301529 .namespaces = perf_event__process_namespaces,
Namhyung Kime3d59112015-01-29 17:06:44 +09001530 .mmap = perf_event__process_mmap,
1531 .mmap2 = perf_event__process_mmap2,
Adrian Huntercca84822015-08-19 17:29:21 +03001532 .ordered_events = true,
Namhyung Kime3d59112015-01-29 17:06:44 +09001533 },
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001534};
Frederic Weisbecker7865e812010-04-14 19:42:07 +02001535
Namhyung Kim76a26542015-10-22 23:28:32 +09001536const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1537 "\n\t\t\t\tDefault: fp";
Arnaldo Carvalho de Melo61eaa3b2012-10-01 15:20:58 -03001538
Wang Nan0aab2132016-06-16 08:02:41 +00001539static bool dry_run;
1540
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001541/*
1542 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
1543 * with it and switch to use the library functions in perf_evlist that came
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001544 * from builtin-record.c, i.e. use record_opts,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001545 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
1546 * using pipes, etc.
1547 */
Jiri Olsaefd21302017-01-03 09:19:55 +01001548static struct option __record_options[] = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001549 OPT_CALLBACK('e', "event", &record.evlist, "event",
Thomas Gleixner86847b62009-06-06 12:24:17 +02001550 "event selector. use 'perf list' to list available events",
Jiri Olsaf120f9d2011-07-14 11:25:32 +02001551 parse_events_option),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001552 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
Li Zefanc171b552009-10-15 11:22:07 +08001553 "event filter", parse_filter),
Wang Nan4ba1faa2015-07-10 07:36:10 +00001554 OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
1555 NULL, "don't record events from perf itself",
1556 exclude_perf),
Namhyung Kimbea03402012-04-26 14:15:15 +09001557 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001558 "record events on existing process id"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001559 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001560 "record events on existing thread id"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001561 OPT_INTEGER('r', "realtime", &record.realtime_prio,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001562 "collect data with this RT SCHED_FIFO priority"),
Arnaldo Carvalho de Melo509051e2014-01-14 17:52:14 -03001563 OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
Kirill Smelkovacac03f2011-01-12 17:59:36 +03001564 "collect data without buffering"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001565 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
Frederic Weisbeckerdaac07b2009-08-13 10:27:19 +02001566 "collect raw sample records from all opened counters"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001567 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001568 "system-wide collection from all CPUs"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001569 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
Stephane Eranianc45c6ea2010-05-28 12:00:01 +02001570 "list of cpus to monitor"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001571 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
Jiri Olsaf5fc14122013-10-15 16:27:32 +02001572 OPT_STRING('o', "output", &record.file.path, "file",
Ingo Molnarabaff322009-06-02 22:59:57 +02001573 "output file name"),
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001574 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1575 &record.opts.no_inherit_set,
1576 "child tasks do not inherit counters"),
Wang Nan4ea648a2016-07-14 08:34:47 +00001577 OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize,
1578 "synthesize non-sample events at the end of output"),
Wang Nan626a6b72016-07-14 08:34:45 +00001579 OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001580 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
Adrian Huntere9db1312015-04-09 18:53:46 +03001581 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
1582 "number of mmap data pages and AUX area tracing mmap pages",
1583 record__parse_mmap_pages),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001584 OPT_BOOLEAN(0, "group", &record.opts.group,
Lin Ming43bece72011-08-17 18:42:07 +08001585 "put the counters into a counter group"),
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001586 OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001587 NULL, "enables call-graph recording" ,
1588 &record_callchain_opt),
1589 OPT_CALLBACK(0, "call-graph", &record.opts,
Namhyung Kim76a26542015-10-22 23:28:32 +09001590 "record_mode[,record_size]", record_callchain_help,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001591 &record_parse_callchain_opt),
Ian Munsiec0555642010-04-13 18:37:33 +10001592 OPT_INCR('v', "verbose", &verbose,
Ingo Molnar3da297a2009-06-07 17:39:02 +02001593 "be more verbose (show counter open errors, etc)"),
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001594 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001595 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001596 "per thread counts"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001597 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
Jiri Olsab6f35ed2016-08-01 20:02:35 +02001598 OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"),
Adrian Hunter3abebc52015-07-06 14:51:01 +03001599 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
1600 &record.opts.sample_time_set,
1601 "Record the sample timestamps"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001602 OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001603 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001604 "don't sample"),
Wang Nand2db9a92016-01-25 09:56:19 +00001605 OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
1606 &record.no_buildid_cache_set,
1607 "do not update the buildid cache"),
1608 OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
1609 &record.no_buildid_set,
1610 "do not collect buildids in perf.data"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001611 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
Stephane Eranian023695d2011-02-14 11:20:01 +02001612 "monitor event in cgroup name only",
1613 parse_cgroups),
Arnaldo Carvalho de Meloa6205a32014-01-14 17:58:12 -03001614 OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
Andi Kleen6619a532014-01-11 13:38:27 -08001615 "ms to wait before starting measurement after program start"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001616 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
1617 "user to profile"),
Stephane Eraniana5aabda2012-03-08 23:47:45 +01001618
1619 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
1620 "branch any", "sample any taken branches",
1621 parse_branch_stack),
1622
1623 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
1624 "branch filter mask", "branch stack filter modes",
Roberto Agostino Vitillobdfebd82012-02-09 23:21:02 +01001625 parse_branch_stack),
Andi Kleen05484292013-01-24 16:10:29 +01001626 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
1627 "sample by weight (on special events only)"),
Andi Kleen475eeab2013-09-20 07:40:43 -07001628 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
1629 "sample transaction flags (special events only)"),
Adrian Hunter3aa59392013-11-15 15:52:29 +02001630 OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
1631 "use per-thread mmaps"),
Stephane Eranianbcc84ec2015-08-31 18:41:12 +02001632 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
1633 "sample selected machine registers on interrupt,"
1634 " use -I ? to list register names", parse_regs),
Andi Kleen85c273d2015-02-24 15:13:40 -08001635 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
1636 "Record running/enabled time of read (:S) events"),
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001637 OPT_CALLBACK('k', "clockid", &record.opts,
1638 "clockid", "clockid to use for events, see clock_gettime()",
1639 parse_clockid),
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001640 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
1641 "opts", "AUX area tracing Snapshot Mode", ""),
Kan Liang9d9cad72015-06-17 09:51:11 -04001642 OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
1643 "per thread proc mmap processing timeout in ms"),
Hari Bathinif3b36142017-03-08 02:11:43 +05301644 OPT_BOOLEAN(0, "namespaces", &record.opts.record_namespaces,
1645 "Record namespaces events"),
Adrian Hunterb757bb02015-07-21 12:44:04 +03001646 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1647 "Record context switch events"),
Jiri Olsa85723882016-02-15 09:34:31 +01001648 OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
1649 "Configure all used events to run in kernel space.",
1650 PARSE_OPT_EXCLUSIVE),
1651 OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
1652 "Configure all used events to run in user space.",
1653 PARSE_OPT_EXCLUSIVE),
Wang Nan71dc23262015-10-14 12:41:19 +00001654 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1655 "clang binary to use for compiling BPF scriptlets"),
1656 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1657 "options passed to clang when compiling BPF scriptlets"),
He Kuang7efe0e02015-12-14 10:39:23 +00001658 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1659 "file", "vmlinux pathname"),
Namhyung Kim61566812016-01-11 22:37:09 +09001660 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
1661 "Record build-id of all DSOs regardless of hits"),
Wang Nanecfd7a92016-04-13 08:21:07 +00001662 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1663 "append timestamp to output filename"),
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001664 OPT_STRING_OPTARG_SET(0, "switch-output", &record.switch_output.str,
Jiri Olsabfacbe32017-01-09 10:52:00 +01001665 &record.switch_output.set, "signal,size,time",
1666 "Switch output when receive SIGUSR2 or cross size,time threshold",
Jiri Olsadc0c6122017-01-09 10:51:58 +01001667 "signal"),
Wang Nan0aab2132016-06-16 08:02:41 +00001668 OPT_BOOLEAN(0, "dry-run", &dry_run,
1669 "Parse options then exit"),
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001670 OPT_END()
1671};
1672
Namhyung Kime5b2c202014-10-23 00:15:46 +09001673struct option *record_options = __record_options;
1674
Arnaldo Carvalho de Melob0ad8ea2017-03-27 11:47:20 -03001675int cmd_record(int argc, const char **argv)
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001676{
Adrian Hunteref149c22015-04-09 18:53:45 +03001677 int err;
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001678 struct record *rec = &record;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001679 char errbuf[BUFSIZ];
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001680
Wang Nan48e1cab2015-12-14 10:39:22 +00001681#ifndef HAVE_LIBBPF_SUPPORT
1682# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
1683 set_nobuild('\0', "clang-path", true);
1684 set_nobuild('\0', "clang-opt", true);
1685# undef set_nobuild
1686#endif
1687
He Kuang7efe0e02015-12-14 10:39:23 +00001688#ifndef HAVE_BPF_PROLOGUE
1689# if !defined (HAVE_DWARF_SUPPORT)
1690# define REASON "NO_DWARF=1"
1691# elif !defined (HAVE_LIBBPF_SUPPORT)
1692# define REASON "NO_LIBBPF=1"
1693# else
1694# define REASON "this architecture doesn't support BPF prologue"
1695# endif
1696# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
1697 set_nobuild('\0', "vmlinux", true);
1698# undef set_nobuild
1699# undef REASON
1700#endif
1701
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001702 rec->evlist = perf_evlist__new();
1703 if (rec->evlist == NULL)
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -02001704 return -ENOMEM;
1705
Arnaldo Carvalho de Meloecc4c562017-01-24 13:44:10 -03001706 err = perf_config(perf_record_config, rec);
1707 if (err)
1708 return err;
Jiri Olsaeb853e82014-02-03 12:44:42 +01001709
Tom Zanussibca647a2010-11-10 08:11:30 -06001710 argc = parse_options(argc, argv, record_options, record_usage,
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001711 PARSE_OPT_STOP_AT_NON_OPTION);
Namhyung Kim68ba3232017-02-17 17:17:42 +09001712 if (quiet)
1713 perf_quiet_option();
Jiri Olsa483635a2017-02-17 18:00:18 +01001714
1715 /* Make system wide (-a) the default target. */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001716 if (!argc && target__none(&rec->opts.target))
Jiri Olsa483635a2017-02-17 18:00:18 +01001717 rec->opts.target.system_wide = true;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001718
Namhyung Kimbea03402012-04-26 14:15:15 +09001719 if (nr_cgroups && !rec->opts.target.system_wide) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001720 usage_with_options_msg(record_usage, record_options,
1721 "cgroup monitoring only available in system-wide mode");
1722
Stephane Eranian023695d2011-02-14 11:20:01 +02001723 }
Adrian Hunterb757bb02015-07-21 12:44:04 +03001724 if (rec->opts.record_switch_events &&
1725 !perf_can_record_switch_events()) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001726 ui__error("kernel does not support recording context switch events\n");
1727 parse_options_usage(record_usage, record_options, "switch-events", 0);
1728 return -EINVAL;
Adrian Hunterb757bb02015-07-21 12:44:04 +03001729 }
Stephane Eranian023695d2011-02-14 11:20:01 +02001730
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001731 if (switch_output_setup(rec)) {
1732 parse_options_usage(record_usage, record_options, "switch-output", 0);
1733 return -EINVAL;
1734 }
1735
Jiri Olsabfacbe32017-01-09 10:52:00 +01001736 if (rec->switch_output.time) {
1737 signal(SIGALRM, alarm_sig_handler);
1738 alarm(rec->switch_output.time);
1739 }
1740
Adrian Hunteref149c22015-04-09 18:53:45 +03001741 if (!rec->itr) {
1742 rec->itr = auxtrace_record__init(rec->evlist, &err);
1743 if (err)
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001744 goto out;
Adrian Hunteref149c22015-04-09 18:53:45 +03001745 }
1746
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001747 err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
1748 rec->opts.auxtrace_snapshot_opts);
1749 if (err)
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001750 goto out;
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001751
Adrian Hunter1b36c032016-09-23 17:38:39 +03001752 /*
1753 * Allow aliases to facilitate the lookup of symbols for address
1754 * filters. Refer to auxtrace_parse_filters().
1755 */
1756 symbol_conf.allow_aliases = true;
1757
1758 symbol__init(NULL);
1759
1760 err = auxtrace_parse_filters(rec->evlist);
1761 if (err)
1762 goto out;
1763
Wang Nan0aab2132016-06-16 08:02:41 +00001764 if (dry_run)
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001765 goto out;
Wang Nan0aab2132016-06-16 08:02:41 +00001766
Wang Nand7888572016-04-08 15:07:24 +00001767 err = bpf__setup_stdout(rec->evlist);
1768 if (err) {
1769 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
1770 pr_err("ERROR: Setup BPF stdout failed: %s\n",
1771 errbuf);
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001772 goto out;
Wang Nand7888572016-04-08 15:07:24 +00001773 }
1774
Adrian Hunteref149c22015-04-09 18:53:45 +03001775 err = -ENOMEM;
1776
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001777 if (symbol_conf.kptr_restrict)
Arnaldo Carvalho de Melo646aaea2011-05-27 11:00:41 -03001778 pr_warning(
1779"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
1780"check /proc/sys/kernel/kptr_restrict.\n\n"
1781"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
1782"file is not found in the buildid cache or in the vmlinux path.\n\n"
1783"Samples in kernel modules won't be resolved at all.\n\n"
1784"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
1785"even with a suitable vmlinux or kallsyms file.\n\n");
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001786
Wang Nan0c1d46a2016-04-20 18:59:52 +00001787 if (rec->no_buildid_cache || rec->no_buildid) {
Stephane Eraniana1ac1d32010-06-17 11:39:01 +02001788 disable_buildid_cache();
Jiri Olsadc0c6122017-01-09 10:51:58 +01001789 } else if (rec->switch_output.enabled) {
Wang Nan0c1d46a2016-04-20 18:59:52 +00001790 /*
1791 * In 'perf record --switch-output', disable buildid
1792 * generation by default to reduce data file switching
1793 * overhead. Still generate buildid if they are required
1794 * explicitly using
1795 *
Jiri Olsa60437ac2017-01-03 09:19:56 +01001796 * perf record --switch-output --no-no-buildid \
Wang Nan0c1d46a2016-04-20 18:59:52 +00001797 * --no-no-buildid-cache
1798 *
1799 * Following code equals to:
1800 *
1801 * if ((rec->no_buildid || !rec->no_buildid_set) &&
1802 * (rec->no_buildid_cache || !rec->no_buildid_cache_set))
1803 * disable_buildid_cache();
1804 */
1805 bool disable = true;
1806
1807 if (rec->no_buildid_set && !rec->no_buildid)
1808 disable = false;
1809 if (rec->no_buildid_cache_set && !rec->no_buildid_cache)
1810 disable = false;
1811 if (disable) {
1812 rec->no_buildid = true;
1813 rec->no_buildid_cache = true;
1814 disable_buildid_cache();
1815 }
1816 }
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001817
Wang Nan4ea648a2016-07-14 08:34:47 +00001818 if (record.opts.overwrite)
1819 record.opts.tail_synthesize = true;
1820
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001821 if (rec->evlist->nr_entries == 0 &&
1822 perf_evlist__add_default(rec->evlist) < 0) {
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001823 pr_err("Not enough memory for event selector list\n");
Adrian Hunter394c01e2016-09-23 17:38:36 +03001824 goto out;
Peter Zijlstrabbd36e52009-06-11 23:11:50 +02001825 }
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001826
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001827 if (rec->opts.target.tid && !rec->opts.no_inherit_set)
1828 rec->opts.no_inherit = true;
1829
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001830 err = target__validate(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001831 if (err) {
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001832 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001833 ui__warning("%s", errbuf);
1834 }
Namhyung Kim4bd0f2d2012-04-26 14:15:18 +09001835
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001836 err = target__parse_uid(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001837 if (err) {
1838 int saved_errno = errno;
1839
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001840 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim3780f482012-05-29 13:22:57 +09001841 ui__error("%s", errbuf);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001842
1843 err = -saved_errno;
Adrian Hunter394c01e2016-09-23 17:38:36 +03001844 goto out;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001845 }
Arnaldo Carvalho de Melo0d37aa32012-01-19 14:08:15 -02001846
Jiri Olsa23dc4f12016-12-12 11:35:43 +01001847 /* Enable ignoring missing threads when -u option is defined. */
1848 rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX;
1849
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001850 err = -ENOMEM;
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001851 if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -02001852 usage_with_options(record_usage, record_options);
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001853
Adrian Hunteref149c22015-04-09 18:53:45 +03001854 err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
1855 if (err)
Adrian Hunter394c01e2016-09-23 17:38:36 +03001856 goto out;
Adrian Hunteref149c22015-04-09 18:53:45 +03001857
Namhyung Kim61566812016-01-11 22:37:09 +09001858 /*
1859 * We take all buildids when the file contains
1860 * AUX area tracing data because we do not decode the
1861 * trace because it would take too long.
1862 */
1863 if (rec->opts.full_auxtrace)
1864 rec->buildid_all = true;
1865
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001866 if (record_opts__config(&rec->opts)) {
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001867 err = -EINVAL;
Adrian Hunter394c01e2016-09-23 17:38:36 +03001868 goto out;
Mike Galbraith7e4ff9e2009-10-12 07:56:03 +02001869 }
1870
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001871 err = __cmd_record(&record, argc, argv);
Adrian Hunter394c01e2016-09-23 17:38:36 +03001872out:
Namhyung Kim45604712014-05-12 09:47:24 +09001873 perf_evlist__delete(rec->evlist);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03001874 symbol__exit();
Adrian Hunteref149c22015-04-09 18:53:45 +03001875 auxtrace_record__free(rec->itr);
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001876 return err;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001877}
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001878
1879static void snapshot_sig_handler(int sig __maybe_unused)
1880{
Jiri Olsadc0c6122017-01-09 10:51:58 +01001881 struct record *rec = &record;
1882
Wang Nan5f9cf592016-04-20 18:59:49 +00001883 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1884 trigger_hit(&auxtrace_snapshot_trigger);
1885 auxtrace_record__snapshot_started = 1;
1886 if (auxtrace_record__snapshot_start(record.itr))
1887 trigger_error(&auxtrace_snapshot_trigger);
1888 }
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001889
Jiri Olsadc0c6122017-01-09 10:51:58 +01001890 if (switch_output_signal(rec))
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001891 trigger_hit(&switch_output_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001892}
Jiri Olsabfacbe32017-01-09 10:52:00 +01001893
1894static void alarm_sig_handler(int sig __maybe_unused)
1895{
1896 struct record *rec = &record;
1897
1898 if (switch_output_time(rec))
1899 trigger_hit(&switch_output_trigger);
1900}