blob: 234fdf4734f6988e3df116f0ee82ab29a2cdf80c [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>
Arnaldo Carvalho de Melo42087352017-04-19 19:06:30 -030047#include <poll.h>
Peter Zijlstra97124d5e2009-06-02 15:52:24 +020048#include <unistd.h>
Peter Zijlstrade9ac072009-04-08 15:01:31 +020049#include <sched.h>
Arnaldo Carvalho de Melo9607ad32017-04-19 15:49:18 -030050#include <signal.h>
Arnaldo Carvalho de Meloa41794c2010-05-18 18:29:23 -030051#include <sys/mman.h>
Arnaldo Carvalho de Melo42087352017-04-19 19:06:30 -030052#include <sys/wait.h>
Wang Nan2d11c652016-05-23 07:13:39 +000053#include <asm/bug.h>
Arnaldo Carvalho de Melo0693e682016-08-08 15:05:46 -030054#include <linux/time64.h>
Bernhard Rosenkraenzer78da39f2012-10-08 09:43:26 +030055
Jiri Olsa1b43b702017-01-09 10:51:56 +010056struct switch_output {
Jiri Olsadc0c6122017-01-09 10:51:58 +010057 bool enabled;
Jiri Olsa1b43b702017-01-09 10:51:56 +010058 bool signal;
Jiri Olsadc0c6122017-01-09 10:51:58 +010059 unsigned long size;
Jiri Olsabfacbe32017-01-09 10:52:00 +010060 unsigned long time;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +010061 const char *str;
62 bool set;
Jiri Olsa1b43b702017-01-09 10:51:56 +010063};
64
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -030065struct record {
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020066 struct perf_tool tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -030067 struct record_opts opts;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020068 u64 bytes_written;
Jiri Olsaf5fc14122013-10-15 16:27:32 +020069 struct perf_data_file file;
Adrian Hunteref149c22015-04-09 18:53:45 +030070 struct auxtrace_record *itr;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020071 struct perf_evlist *evlist;
72 struct perf_session *session;
73 const char *progname;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020074 int realtime_prio;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020075 bool no_buildid;
Wang Nand2db9a92016-01-25 09:56:19 +000076 bool no_buildid_set;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020077 bool no_buildid_cache;
Wang Nand2db9a92016-01-25 09:56:19 +000078 bool no_buildid_cache_set;
Namhyung Kim61566812016-01-11 22:37:09 +090079 bool buildid_all;
Wang Nanecfd7a92016-04-13 08:21:07 +000080 bool timestamp_filename;
Jiri Olsa1b43b702017-01-09 10:51:56 +010081 struct switch_output switch_output;
Yang Shi9f065192015-09-29 14:49:43 -070082 unsigned long long samples;
Arnaldo Carvalho de Melo0f82ebc2011-11-08 14:41:57 -020083};
Ingo Molnara21ca2c2009-06-06 09:58:57 +020084
Jiri Olsadc0c6122017-01-09 10:51:58 +010085static volatile int auxtrace_record__snapshot_started;
86static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
87static DEFINE_TRIGGER(switch_output_trigger);
88
89static bool switch_output_signal(struct record *rec)
90{
91 return rec->switch_output.signal &&
92 trigger_is_ready(&switch_output_trigger);
93}
94
95static bool switch_output_size(struct record *rec)
96{
97 return rec->switch_output.size &&
98 trigger_is_ready(&switch_output_trigger) &&
99 (rec->bytes_written >= rec->switch_output.size);
100}
101
Jiri Olsabfacbe32017-01-09 10:52:00 +0100102static bool switch_output_time(struct record *rec)
103{
104 return rec->switch_output.time &&
105 trigger_is_ready(&switch_output_trigger);
106}
107
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300108static int record__write(struct record *rec, void *bf, size_t size)
Peter Zijlstraf5970552009-06-18 23:22:55 +0200109{
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -0300110 if (perf_data_file__write(rec->session->file, bf, size) < 0) {
Jiri Olsa50a9b862013-11-22 13:11:24 +0100111 pr_err("failed to write perf data, error: %m\n");
112 return -1;
Peter Zijlstraf5970552009-06-18 23:22:55 +0200113 }
David Ahern8d3eca22012-08-26 12:24:47 -0600114
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -0300115 rec->bytes_written += size;
Jiri Olsadc0c6122017-01-09 10:51:58 +0100116
117 if (switch_output_size(rec))
118 trigger_hit(&switch_output_trigger);
119
David Ahern8d3eca22012-08-26 12:24:47 -0600120 return 0;
Peter Zijlstraf5970552009-06-18 23:22:55 +0200121}
122
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200123static int process_synthesized_event(struct perf_tool *tool,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200124 union perf_event *event,
Irina Tirdea1d037ca2012-09-11 01:15:03 +0300125 struct perf_sample *sample __maybe_unused,
126 struct machine *machine __maybe_unused)
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -0200127{
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300128 struct record *rec = container_of(tool, struct record, tool);
129 return record__write(rec, event, event->header.size);
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -0200130}
131
Wang Nan3a62a7b2016-05-23 07:13:41 +0000132static int
133backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end)
134{
135 struct perf_event_header *pheader;
136 u64 evt_head = head;
137 int size = mask + 1;
138
139 pr_debug2("backward_rb_find_range: buf=%p, head=%"PRIx64"\n", buf, head);
140 pheader = (struct perf_event_header *)(buf + (head & mask));
141 *start = head;
142 while (true) {
143 if (evt_head - head >= (unsigned int)size) {
Colin Ian King5e30d552016-08-22 19:30:08 +0100144 pr_debug("Finished reading backward ring buffer: rewind\n");
Wang Nan3a62a7b2016-05-23 07:13:41 +0000145 if (evt_head - head > (unsigned int)size)
146 evt_head -= pheader->size;
147 *end = evt_head;
148 return 0;
149 }
150
151 pheader = (struct perf_event_header *)(buf + (evt_head & mask));
152
153 if (pheader->size == 0) {
Colin Ian King5e30d552016-08-22 19:30:08 +0100154 pr_debug("Finished reading backward ring buffer: get start\n");
Wang Nan3a62a7b2016-05-23 07:13:41 +0000155 *end = evt_head;
156 return 0;
157 }
158
159 evt_head += pheader->size;
160 pr_debug3("move evt_head: %"PRIx64"\n", evt_head);
161 }
162 WARN_ONCE(1, "Shouldn't get here\n");
163 return -1;
164}
165
166static int
Wang Nana4ea0ec2016-07-14 08:34:36 +0000167rb_find_range(void *data, int mask, u64 head, u64 old,
168 u64 *start, u64 *end, bool backward)
Wang Nan3a62a7b2016-05-23 07:13:41 +0000169{
Wang Nana4ea0ec2016-07-14 08:34:36 +0000170 if (!backward) {
Wang Nan3a62a7b2016-05-23 07:13:41 +0000171 *start = old;
172 *end = head;
173 return 0;
174 }
175
176 return backward_rb_find_range(data, mask, head, start, end);
177}
178
Wang Nana4ea0ec2016-07-14 08:34:36 +0000179static int
180record__mmap_read(struct record *rec, struct perf_mmap *md,
181 bool overwrite, bool backward)
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200182{
David Ahern7b8283b52015-04-07 09:20:37 -0600183 u64 head = perf_mmap__read_head(md);
184 u64 old = md->prev;
Wang Nan09fa4f42016-05-23 07:13:40 +0000185 u64 end = head, start = old;
Jiri Olsa918512b2013-09-12 18:39:35 +0200186 unsigned char *data = md->base + page_size;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200187 unsigned long size;
188 void *buf;
David Ahern8d3eca22012-08-26 12:24:47 -0600189 int rc = 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200190
Wang Nana4ea0ec2016-07-14 08:34:36 +0000191 if (rb_find_range(data, md->mask, head,
192 old, &start, &end, backward))
Wang Nan3a62a7b2016-05-23 07:13:41 +0000193 return -1;
194
Wang Nan09fa4f42016-05-23 07:13:40 +0000195 if (start == end)
David Ahern8d3eca22012-08-26 12:24:47 -0600196 return 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200197
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200198 rec->samples++;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200199
Wang Nan09fa4f42016-05-23 07:13:40 +0000200 size = end - start;
Wang Nan2d11c652016-05-23 07:13:39 +0000201 if (size > (unsigned long)(md->mask) + 1) {
202 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
203
204 md->prev = head;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000205 perf_mmap__consume(md, overwrite || backward);
Wang Nan2d11c652016-05-23 07:13:39 +0000206 return 0;
207 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200208
Wang Nan09fa4f42016-05-23 07:13:40 +0000209 if ((start & md->mask) + size != (end & md->mask)) {
210 buf = &data[start & md->mask];
211 size = md->mask + 1 - (start & md->mask);
212 start += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200213
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300214 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600215 rc = -1;
216 goto out;
217 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200218 }
219
Wang Nan09fa4f42016-05-23 07:13:40 +0000220 buf = &data[start & md->mask];
221 size = end - start;
222 start += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200223
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300224 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600225 rc = -1;
226 goto out;
227 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200228
Wang Nan09fa4f42016-05-23 07:13:40 +0000229 md->prev = head;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000230 perf_mmap__consume(md, overwrite || backward);
David Ahern8d3eca22012-08-26 12:24:47 -0600231out:
232 return rc;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200233}
234
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300235static volatile int done;
236static volatile int signr = -1;
237static volatile int child_finished;
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000238
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300239static void sig_handler(int sig)
240{
241 if (sig == SIGCHLD)
242 child_finished = 1;
243 else
244 signr = sig;
245
246 done = 1;
247}
248
Wang Nana0748652016-11-26 07:03:28 +0000249static void sigsegv_handler(int sig)
250{
251 perf_hooks__recover();
252 sighandler_dump_stack(sig);
253}
254
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300255static void record__sig_exit(void)
256{
257 if (signr == -1)
258 return;
259
260 signal(signr, SIG_DFL);
261 raise(signr);
262}
263
Adrian Huntere31f0d02015-04-30 17:37:27 +0300264#ifdef HAVE_AUXTRACE_SUPPORT
265
Adrian Hunteref149c22015-04-09 18:53:45 +0300266static int record__process_auxtrace(struct perf_tool *tool,
267 union perf_event *event, void *data1,
268 size_t len1, void *data2, size_t len2)
269{
270 struct record *rec = container_of(tool, struct record, tool);
Adrian Hunter99fa2982015-04-30 17:37:25 +0300271 struct perf_data_file *file = &rec->file;
Adrian Hunteref149c22015-04-09 18:53:45 +0300272 size_t padding;
273 u8 pad[8] = {0};
274
Adrian Hunter99fa2982015-04-30 17:37:25 +0300275 if (!perf_data_file__is_pipe(file)) {
276 off_t file_offset;
277 int fd = perf_data_file__fd(file);
278 int err;
279
280 file_offset = lseek(fd, 0, SEEK_CUR);
281 if (file_offset == -1)
282 return -1;
283 err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index,
284 event, file_offset);
285 if (err)
286 return err;
287 }
288
Adrian Hunteref149c22015-04-09 18:53:45 +0300289 /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */
290 padding = (len1 + len2) & 7;
291 if (padding)
292 padding = 8 - padding;
293
294 record__write(rec, event, event->header.size);
295 record__write(rec, data1, len1);
296 if (len2)
297 record__write(rec, data2, len2);
298 record__write(rec, &pad, padding);
299
300 return 0;
301}
302
303static int record__auxtrace_mmap_read(struct record *rec,
304 struct auxtrace_mmap *mm)
305{
306 int ret;
307
308 ret = auxtrace_mmap__read(mm, rec->itr, &rec->tool,
309 record__process_auxtrace);
310 if (ret < 0)
311 return ret;
312
313 if (ret)
314 rec->samples++;
315
316 return 0;
317}
318
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300319static int record__auxtrace_mmap_read_snapshot(struct record *rec,
320 struct auxtrace_mmap *mm)
321{
322 int ret;
323
324 ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool,
325 record__process_auxtrace,
326 rec->opts.auxtrace_snapshot_size);
327 if (ret < 0)
328 return ret;
329
330 if (ret)
331 rec->samples++;
332
333 return 0;
334}
335
336static int record__auxtrace_read_snapshot_all(struct record *rec)
337{
338 int i;
339 int rc = 0;
340
341 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
342 struct auxtrace_mmap *mm =
343 &rec->evlist->mmap[i].auxtrace_mmap;
344
345 if (!mm->base)
346 continue;
347
348 if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) {
349 rc = -1;
350 goto out;
351 }
352 }
353out:
354 return rc;
355}
356
357static void record__read_auxtrace_snapshot(struct record *rec)
358{
359 pr_debug("Recording AUX area tracing snapshot\n");
360 if (record__auxtrace_read_snapshot_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000361 trigger_error(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300362 } else {
Wang Nan5f9cf592016-04-20 18:59:49 +0000363 if (auxtrace_record__snapshot_finish(rec->itr))
364 trigger_error(&auxtrace_snapshot_trigger);
365 else
366 trigger_ready(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300367 }
368}
369
Adrian Huntere31f0d02015-04-30 17:37:27 +0300370#else
371
372static inline
373int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
374 struct auxtrace_mmap *mm __maybe_unused)
375{
376 return 0;
377}
378
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300379static inline
380void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
381{
382}
383
384static inline
385int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
386{
387 return 0;
388}
389
Adrian Huntere31f0d02015-04-30 17:37:27 +0300390#endif
391
Wang Nancda57a82016-06-27 10:24:03 +0000392static int record__mmap_evlist(struct record *rec,
393 struct perf_evlist *evlist)
394{
395 struct record_opts *opts = &rec->opts;
396 char msg[512];
397
398 if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
399 opts->auxtrace_mmap_pages,
400 opts->auxtrace_snapshot_mode) < 0) {
401 if (errno == EPERM) {
402 pr_err("Permission error mapping pages.\n"
403 "Consider increasing "
404 "/proc/sys/kernel/perf_event_mlock_kb,\n"
405 "or try again with a smaller value of -m/--mmap_pages.\n"
406 "(current value: %u,%u)\n",
407 opts->mmap_pages, opts->auxtrace_mmap_pages);
408 return -errno;
409 } else {
410 pr_err("failed to mmap with %d (%s)\n", errno,
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300411 str_error_r(errno, msg, sizeof(msg)));
Wang Nancda57a82016-06-27 10:24:03 +0000412 if (errno)
413 return -errno;
414 else
415 return -EINVAL;
416 }
417 }
418 return 0;
419}
420
421static int record__mmap(struct record *rec)
422{
423 return record__mmap_evlist(rec, rec->evlist);
424}
425
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300426static int record__open(struct record *rec)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200427{
Arnaldo Carvalho de Melod6195a62017-02-13 16:45:24 -0300428 char msg[BUFSIZ];
Jiri Olsa6a4bb042012-08-08 12:22:36 +0200429 struct perf_evsel *pos;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200430 struct perf_evlist *evlist = rec->evlist;
431 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300432 struct record_opts *opts = &rec->opts;
Mathieu Poirier5d8bb1e2016-09-16 09:50:03 -0600433 struct perf_evsel_config_term *err_term;
David Ahern8d3eca22012-08-26 12:24:47 -0600434 int rc = 0;
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200435
Arnaldo Carvalho de Meloe68ae9c2016-04-11 18:15:29 -0300436 perf_evlist__config(evlist, opts, &callchain_param);
Jiri Olsacac21422012-11-12 18:34:00 +0100437
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -0300438 evlist__for_each_entry(evlist, pos) {
Ingo Molnar3da297a2009-06-07 17:39:02 +0200439try_again:
Kan Liangd988d5e2015-08-21 02:23:14 -0400440 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300441 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
Namhyung Kimbb963e12017-02-17 17:17:38 +0900442 if (verbose > 0)
Arnaldo Carvalho de Meloc0a54342012-12-13 14:16:30 -0300443 ui__warning("%s\n", msg);
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300444 goto try_again;
445 }
David Ahernca6a4252011-03-25 13:11:11 -0600446
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300447 rc = -errno;
448 perf_evsel__open_strerror(pos, &opts->target,
449 errno, msg, sizeof(msg));
450 ui__error("%s\n", msg);
David Ahern8d3eca22012-08-26 12:24:47 -0600451 goto out;
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300452 }
Li Zefanc171b552009-10-15 11:22:07 +0800453 }
Arnaldo Carvalho de Meloa43d3f02010-12-25 12:12:25 -0200454
Arnaldo Carvalho de Melo23d4aad2015-03-24 19:23:47 -0300455 if (perf_evlist__apply_filters(evlist, &pos)) {
Arnaldo Carvalho de Melo62d94b02017-06-27 11:22:31 -0300456 pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
Arnaldo Carvalho de Melo23d4aad2015-03-24 19:23:47 -0300457 pos->filter, perf_evsel__name(pos), errno,
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300458 str_error_r(errno, msg, sizeof(msg)));
David Ahern8d3eca22012-08-26 12:24:47 -0600459 rc = -1;
460 goto out;
Frederic Weisbecker0a102472011-02-26 04:51:54 +0100461 }
462
Mathieu Poirier5d8bb1e2016-09-16 09:50:03 -0600463 if (perf_evlist__apply_drv_configs(evlist, &pos, &err_term)) {
Arnaldo Carvalho de Melo62d94b02017-06-27 11:22:31 -0300464 pr_err("failed to set config \"%s\" on event %s with %d (%s)\n",
Mathieu Poirier5d8bb1e2016-09-16 09:50:03 -0600465 err_term->val.drv_cfg, perf_evsel__name(pos), errno,
466 str_error_r(errno, msg, sizeof(msg)));
467 rc = -1;
468 goto out;
469 }
470
Wang Nancda57a82016-06-27 10:24:03 +0000471 rc = record__mmap(rec);
472 if (rc)
David Ahern8d3eca22012-08-26 12:24:47 -0600473 goto out;
Arnaldo Carvalho de Melo0a27d7f2011-01-14 15:50:51 -0200474
Jiri Olsa563aecb2013-06-05 13:35:06 +0200475 session->evlist = evlist;
Arnaldo Carvalho de Melo7b56cce2012-08-01 19:31:00 -0300476 perf_session__set_id_hdr_size(session);
David Ahern8d3eca22012-08-26 12:24:47 -0600477out:
478 return rc;
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200479}
480
Namhyung Kime3d59112015-01-29 17:06:44 +0900481static int process_sample_event(struct perf_tool *tool,
482 union perf_event *event,
483 struct perf_sample *sample,
484 struct perf_evsel *evsel,
485 struct machine *machine)
486{
487 struct record *rec = container_of(tool, struct record, tool);
488
489 rec->samples++;
490
491 return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
492}
493
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300494static int process_buildids(struct record *rec)
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200495{
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200496 struct perf_data_file *file = &rec->file;
497 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200498
He Kuang457ae942015-05-28 13:17:30 +0000499 if (file->size == 0)
Arnaldo Carvalho de Melo9f591fd2010-03-11 15:53:11 -0300500 return 0;
501
Namhyung Kim00dc8652014-11-04 10:14:32 +0900502 /*
503 * During this process, it'll load kernel map and replace the
504 * dso->long_name to a real pathname it found. In this case
505 * we prefer the vmlinux path like
506 * /lib/modules/3.16.4/build/vmlinux
507 *
508 * rather than build-id path (in debug directory).
509 * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551
510 */
511 symbol_conf.ignore_vmlinux_buildid = true;
512
Namhyung Kim61566812016-01-11 22:37:09 +0900513 /*
514 * If --buildid-all is given, it marks all DSO regardless of hits,
515 * so no need to process samples.
516 */
517 if (rec->buildid_all)
518 rec->tool.sample = NULL;
519
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300520 return perf_session__process_events(session);
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200521}
522
Arnaldo Carvalho de Melo8115d602011-01-29 14:01:45 -0200523static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800524{
525 int err;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200526 struct perf_tool *tool = data;
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800527 /*
528 *As for guest kernel when processing subcommand record&report,
529 *we arrange module mmap prior to guest kernel mmap and trigger
530 *a preload dso because default guest module symbols are loaded
531 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
532 *method is used to avoid symbol missing when the first addr is
533 *in module instead of in guest kernel.
534 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200535 err = perf_event__synthesize_modules(tool, process_synthesized_event,
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200536 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800537 if (err < 0)
538 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300539 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800540
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800541 /*
542 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
543 * have no _text sometimes.
544 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200545 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
Adrian Hunter0ae617b2014-01-29 16:14:40 +0200546 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800547 if (err < 0)
548 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300549 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800550}
551
Frederic Weisbecker98402802010-05-02 22:05:29 +0200552static struct perf_event_header finished_round_event = {
553 .size = sizeof(struct perf_event_header),
554 .type = PERF_RECORD_FINISHED_ROUND,
555};
556
Wang Nana4ea0ec2016-07-14 08:34:36 +0000557static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist,
558 bool backward)
Frederic Weisbecker98402802010-05-02 22:05:29 +0200559{
Jiri Olsadcabb502014-07-25 16:56:16 +0200560 u64 bytes_written = rec->bytes_written;
Peter Zijlstra0e2e63d2010-05-20 14:45:26 +0200561 int i;
David Ahern8d3eca22012-08-26 12:24:47 -0600562 int rc = 0;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000563 struct perf_mmap *maps;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200564
Wang Nancb216862016-06-27 10:24:04 +0000565 if (!evlist)
566 return 0;
Adrian Hunteref149c22015-04-09 18:53:45 +0300567
Wang Nanb2cb6152016-07-14 08:34:39 +0000568 maps = backward ? evlist->backward_mmap : evlist->mmap;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000569 if (!maps)
570 return 0;
Wang Nancb216862016-06-27 10:24:04 +0000571
Wang Nan54cc54d2016-07-14 08:34:42 +0000572 if (backward && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING)
573 return 0;
574
Wang Nana4ea0ec2016-07-14 08:34:36 +0000575 for (i = 0; i < evlist->nr_mmaps; i++) {
576 struct auxtrace_mmap *mm = &maps[i].auxtrace_mmap;
577
578 if (maps[i].base) {
579 if (record__mmap_read(rec, &maps[i],
580 evlist->overwrite, backward) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600581 rc = -1;
582 goto out;
583 }
584 }
Adrian Hunteref149c22015-04-09 18:53:45 +0300585
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300586 if (mm->base && !rec->opts.auxtrace_snapshot_mode &&
Adrian Hunteref149c22015-04-09 18:53:45 +0300587 record__auxtrace_mmap_read(rec, mm) != 0) {
588 rc = -1;
589 goto out;
590 }
Frederic Weisbecker98402802010-05-02 22:05:29 +0200591 }
592
Jiri Olsadcabb502014-07-25 16:56:16 +0200593 /*
594 * Mark the round finished in case we wrote
595 * at least one event.
596 */
597 if (bytes_written != rec->bytes_written)
598 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
David Ahern8d3eca22012-08-26 12:24:47 -0600599
Wang Nan54cc54d2016-07-14 08:34:42 +0000600 if (backward)
601 perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY);
David Ahern8d3eca22012-08-26 12:24:47 -0600602out:
603 return rc;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200604}
605
Wang Nancb216862016-06-27 10:24:04 +0000606static int record__mmap_read_all(struct record *rec)
607{
608 int err;
609
Wang Nana4ea0ec2016-07-14 08:34:36 +0000610 err = record__mmap_read_evlist(rec, rec->evlist, false);
Wang Nancb216862016-06-27 10:24:04 +0000611 if (err)
612 return err;
613
Wang Nan057374642016-07-14 08:34:43 +0000614 return record__mmap_read_evlist(rec, rec->evlist, true);
Wang Nancb216862016-06-27 10:24:04 +0000615}
616
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300617static void record__init_features(struct record *rec)
David Ahern57706ab2013-11-06 11:41:34 -0700618{
David Ahern57706ab2013-11-06 11:41:34 -0700619 struct perf_session *session = rec->session;
620 int feat;
621
622 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
623 perf_header__set_feat(&session->header, feat);
624
625 if (rec->no_buildid)
626 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
627
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300628 if (!have_tracepoints(&rec->evlist->entries))
David Ahern57706ab2013-11-06 11:41:34 -0700629 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
630
631 if (!rec->opts.branch_stack)
632 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
Adrian Hunteref149c22015-04-09 18:53:45 +0300633
634 if (!rec->opts.full_auxtrace)
635 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
Jiri Olsaffa517a2015-10-25 15:51:43 +0100636
637 perf_header__clear_feat(&session->header, HEADER_STAT);
David Ahern57706ab2013-11-06 11:41:34 -0700638}
639
Wang Nane1ab48b2016-02-26 09:32:10 +0000640static void
641record__finish_output(struct record *rec)
642{
643 struct perf_data_file *file = &rec->file;
644 int fd = perf_data_file__fd(file);
645
646 if (file->is_pipe)
647 return;
648
649 rec->session->header.data_size += rec->bytes_written;
650 file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR);
651
652 if (!rec->no_buildid) {
653 process_buildids(rec);
654
655 if (rec->buildid_all)
656 dsos__hit_all(rec->session);
657 }
658 perf_session__write_header(rec->session, rec->evlist, fd, true);
659
660 return;
661}
662
Wang Nan4ea648a2016-07-14 08:34:47 +0000663static int record__synthesize_workload(struct record *rec, bool tail)
Wang Nanbe7b0c92016-04-20 18:59:54 +0000664{
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -0300665 int err;
666 struct thread_map *thread_map;
Wang Nanbe7b0c92016-04-20 18:59:54 +0000667
Wang Nan4ea648a2016-07-14 08:34:47 +0000668 if (rec->opts.tail_synthesize != tail)
669 return 0;
670
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -0300671 thread_map = thread_map__new_by_tid(rec->evlist->workload.pid);
672 if (thread_map == NULL)
673 return -1;
674
675 err = perf_event__synthesize_thread_map(&rec->tool, thread_map,
Wang Nanbe7b0c92016-04-20 18:59:54 +0000676 process_synthesized_event,
677 &rec->session->machines.host,
678 rec->opts.sample_address,
679 rec->opts.proc_map_timeout);
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -0300680 thread_map__put(thread_map);
681 return err;
Wang Nanbe7b0c92016-04-20 18:59:54 +0000682}
683
Wang Nan4ea648a2016-07-14 08:34:47 +0000684static int record__synthesize(struct record *rec, bool tail);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000685
Wang Nanecfd7a92016-04-13 08:21:07 +0000686static int
687record__switch_output(struct record *rec, bool at_exit)
688{
689 struct perf_data_file *file = &rec->file;
690 int fd, err;
691
692 /* Same Size: "2015122520103046"*/
693 char timestamp[] = "InvalidTimestamp";
694
Wang Nan4ea648a2016-07-14 08:34:47 +0000695 record__synthesize(rec, true);
696 if (target__none(&rec->opts.target))
697 record__synthesize_workload(rec, true);
698
Wang Nanecfd7a92016-04-13 08:21:07 +0000699 rec->samples = 0;
700 record__finish_output(rec);
701 err = fetch_current_timestamp(timestamp, sizeof(timestamp));
702 if (err) {
703 pr_err("Failed to get current timestamp\n");
704 return -EINVAL;
705 }
706
707 fd = perf_data_file__switch(file, timestamp,
708 rec->session->header.data_offset,
709 at_exit);
710 if (fd >= 0 && !at_exit) {
711 rec->bytes_written = 0;
712 rec->session->header.data_size = 0;
713 }
714
715 if (!quiet)
716 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
717 file->path, timestamp);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000718
719 /* Output tracking events */
Wang Nanbe7b0c92016-04-20 18:59:54 +0000720 if (!at_exit) {
Wang Nan4ea648a2016-07-14 08:34:47 +0000721 record__synthesize(rec, false);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000722
Wang Nanbe7b0c92016-04-20 18:59:54 +0000723 /*
724 * In 'perf record --switch-output' without -a,
725 * record__synthesize() in record__switch_output() won't
726 * generate tracking events because there's no thread_map
727 * in evlist. Which causes newly created perf.data doesn't
728 * contain map and comm information.
729 * Create a fake thread_map and directly call
730 * perf_event__synthesize_thread_map() for those events.
731 */
732 if (target__none(&rec->opts.target))
Wang Nan4ea648a2016-07-14 08:34:47 +0000733 record__synthesize_workload(rec, false);
Wang Nanbe7b0c92016-04-20 18:59:54 +0000734 }
Wang Nanecfd7a92016-04-13 08:21:07 +0000735 return fd;
736}
737
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300738static volatile int workload_exec_errno;
739
740/*
741 * perf_evlist__prepare_workload will send a SIGUSR1
742 * if the fork fails, since we asked by setting its
743 * want_signal to true.
744 */
Namhyung Kim45604712014-05-12 09:47:24 +0900745static void workload_exec_failed_signal(int signo __maybe_unused,
746 siginfo_t *info,
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300747 void *ucontext __maybe_unused)
748{
749 workload_exec_errno = info->si_value.sival_int;
750 done = 1;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300751 child_finished = 1;
752}
753
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300754static void snapshot_sig_handler(int sig);
Jiri Olsabfacbe32017-01-09 10:52:00 +0100755static void alarm_sig_handler(int sig);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300756
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200757int __weak
758perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
759 struct perf_tool *tool __maybe_unused,
760 perf_event__handler_t process __maybe_unused,
761 struct machine *machine __maybe_unused)
762{
763 return 0;
764}
765
Wang Nanee667f92016-06-27 10:24:05 +0000766static const struct perf_event_mmap_page *
767perf_evlist__pick_pc(struct perf_evlist *evlist)
768{
Wang Nanb2cb6152016-07-14 08:34:39 +0000769 if (evlist) {
770 if (evlist->mmap && evlist->mmap[0].base)
771 return evlist->mmap[0].base;
772 if (evlist->backward_mmap && evlist->backward_mmap[0].base)
773 return evlist->backward_mmap[0].base;
774 }
Wang Nanee667f92016-06-27 10:24:05 +0000775 return NULL;
776}
777
Wang Nanc45628b2016-05-24 02:28:59 +0000778static const struct perf_event_mmap_page *record__pick_pc(struct record *rec)
779{
Wang Nanee667f92016-06-27 10:24:05 +0000780 const struct perf_event_mmap_page *pc;
781
782 pc = perf_evlist__pick_pc(rec->evlist);
783 if (pc)
784 return pc;
Wang Nanc45628b2016-05-24 02:28:59 +0000785 return NULL;
786}
787
Wang Nan4ea648a2016-07-14 08:34:47 +0000788static int record__synthesize(struct record *rec, bool tail)
Wang Nanc45c86e2016-02-26 09:32:07 +0000789{
790 struct perf_session *session = rec->session;
791 struct machine *machine = &session->machines.host;
792 struct perf_data_file *file = &rec->file;
793 struct record_opts *opts = &rec->opts;
794 struct perf_tool *tool = &rec->tool;
795 int fd = perf_data_file__fd(file);
796 int err = 0;
797
Wang Nan4ea648a2016-07-14 08:34:47 +0000798 if (rec->opts.tail_synthesize != tail)
799 return 0;
800
Wang Nanc45c86e2016-02-26 09:32:07 +0000801 if (file->is_pipe) {
David Carrillo-Cisnerose9def1b2017-07-17 21:25:48 -0700802 err = perf_event__synthesize_features(
803 tool, session, rec->evlist, process_synthesized_event);
804 if (err < 0) {
805 pr_err("Couldn't synthesize features.\n");
806 return err;
807 }
808
Wang Nanc45c86e2016-02-26 09:32:07 +0000809 err = perf_event__synthesize_attrs(tool, session,
810 process_synthesized_event);
811 if (err < 0) {
812 pr_err("Couldn't synthesize attrs.\n");
813 goto out;
814 }
815
816 if (have_tracepoints(&rec->evlist->entries)) {
817 /*
818 * FIXME err <= 0 here actually means that
819 * there were no tracepoints so its not really
820 * an error, just that we don't need to
821 * synthesize anything. We really have to
822 * return this more properly and also
823 * propagate errors that now are calling die()
824 */
825 err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
826 process_synthesized_event);
827 if (err <= 0) {
828 pr_err("Couldn't record tracing data.\n");
829 goto out;
830 }
831 rec->bytes_written += err;
832 }
833 }
834
Wang Nanc45628b2016-05-24 02:28:59 +0000835 err = perf_event__synth_time_conv(record__pick_pc(rec), tool,
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200836 process_synthesized_event, machine);
837 if (err)
838 goto out;
839
Wang Nanc45c86e2016-02-26 09:32:07 +0000840 if (rec->opts.full_auxtrace) {
841 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
842 session, process_synthesized_event);
843 if (err)
844 goto out;
845 }
846
847 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
848 machine);
849 WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
850 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
851 "Check /proc/kallsyms permission or run as root.\n");
852
853 err = perf_event__synthesize_modules(tool, process_synthesized_event,
854 machine);
855 WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
856 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
857 "Check /proc/modules permission or run as root.\n");
858
859 if (perf_guest) {
860 machines__process_guests(&session->machines,
861 perf_event__synthesize_guest_os, tool);
862 }
863
864 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
865 process_synthesized_event, opts->sample_address,
Kan Liang340b47f2017-09-29 07:47:54 -0700866 opts->proc_map_timeout, 1);
Wang Nanc45c86e2016-02-26 09:32:07 +0000867out:
868 return err;
869}
870
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300871static int __cmd_record(struct record *rec, int argc, const char **argv)
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200872{
David Ahern57706ab2013-11-06 11:41:34 -0700873 int err;
Namhyung Kim45604712014-05-12 09:47:24 +0900874 int status = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200875 unsigned long waking = 0;
Zhang, Yanmin46be6042010-03-18 11:36:04 -0300876 const bool forks = argc > 0;
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300877 struct machine *machine;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200878 struct perf_tool *tool = &rec->tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300879 struct record_opts *opts = &rec->opts;
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200880 struct perf_data_file *file = &rec->file;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200881 struct perf_session *session;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300882 bool disabled = false, draining = false;
Namhyung Kim42aa2762015-01-29 17:06:48 +0900883 int fd;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200884
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200885 rec->progname = argv[0];
Andi Kleen33e49ea2011-09-15 14:31:40 -0700886
Namhyung Kim45604712014-05-12 09:47:24 +0900887 atexit(record__sig_exit);
Peter Zijlstraf5970552009-06-18 23:22:55 +0200888 signal(SIGCHLD, sig_handler);
889 signal(SIGINT, sig_handler);
David Ahern804f7ac2013-05-06 12:24:23 -0600890 signal(SIGTERM, sig_handler);
Wang Nana0748652016-11-26 07:03:28 +0000891 signal(SIGSEGV, sigsegv_handler);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000892
Hari Bathinif3b36142017-03-08 02:11:43 +0530893 if (rec->opts.record_namespaces)
894 tool->namespace_events = true;
895
Jiri Olsadc0c6122017-01-09 10:51:58 +0100896 if (rec->opts.auxtrace_snapshot_mode || rec->switch_output.enabled) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300897 signal(SIGUSR2, snapshot_sig_handler);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000898 if (rec->opts.auxtrace_snapshot_mode)
899 trigger_on(&auxtrace_snapshot_trigger);
Jiri Olsadc0c6122017-01-09 10:51:58 +0100900 if (rec->switch_output.enabled)
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000901 trigger_on(&switch_output_trigger);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000902 } else {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300903 signal(SIGUSR2, SIG_IGN);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000904 }
Peter Zijlstraf5970552009-06-18 23:22:55 +0200905
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300906 session = perf_session__new(file, false, tool);
Arnaldo Carvalho de Melo94c744b2009-12-11 21:24:02 -0200907 if (session == NULL) {
Adrien BAKffa91882014-04-18 11:00:43 +0900908 pr_err("Perf session creation failed.\n");
Arnaldo Carvalho de Meloa9a70bb2009-11-17 01:18:11 -0200909 return -1;
910 }
911
Namhyung Kim42aa2762015-01-29 17:06:48 +0900912 fd = perf_data_file__fd(file);
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200913 rec->session = session;
914
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300915 record__init_features(rec);
Stephane Eranian330aa672012-03-08 23:47:46 +0100916
Arnaldo Carvalho de Melod4db3f12009-12-27 21:36:57 -0200917 if (forks) {
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300918 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200919 argv, file->is_pipe,
Arnaldo Carvalho de Melo735f7e02014-01-03 14:56:49 -0300920 workload_exec_failed_signal);
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200921 if (err < 0) {
922 pr_err("Couldn't run the workload!\n");
Namhyung Kim45604712014-05-12 09:47:24 +0900923 status = err;
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200924 goto out_delete_session;
Jens Axboe0a5ac842009-08-12 11:18:01 +0200925 }
Peter Zijlstra856e9662009-12-16 17:55:55 +0100926 }
927
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300928 if (record__open(rec) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600929 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900930 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600931 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200932
Wang Nan8690a2a2016-02-22 09:10:32 +0000933 err = bpf__apply_obj_config();
934 if (err) {
935 char errbuf[BUFSIZ];
936
937 bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
938 pr_err("ERROR: Apply config to BPF failed: %s\n",
939 errbuf);
940 goto out_child;
941 }
942
Adrian Huntercca84822015-08-19 17:29:21 +0300943 /*
944 * Normally perf_session__new would do this, but it doesn't have the
945 * evlist.
946 */
947 if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
948 pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
949 rec->tool.ordered_events = false;
950 }
951
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300952 if (!rec->evlist->nr_groups)
Namhyung Kima8bb5592013-01-22 18:09:31 +0900953 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
954
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200955 if (file->is_pipe) {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900956 err = perf_header__write_pipe(fd);
Tom Zanussi529870e2010-04-01 23:59:16 -0500957 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900958 goto out_child;
Jiri Olsa563aecb2013-06-05 13:35:06 +0200959 } else {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900960 err = perf_session__write_header(session, rec->evlist, fd, false);
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200961 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900962 goto out_child;
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200963 }
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +0200964
David Ahernd3665492012-02-06 15:27:52 -0700965 if (!rec->no_buildid
Robert Richtere20960c2011-12-07 10:02:55 +0100966 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
David Ahernd3665492012-02-06 15:27:52 -0700967 pr_err("Couldn't generate buildids. "
Robert Richtere20960c2011-12-07 10:02:55 +0100968 "Use --no-buildid to profile anyway.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600969 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900970 goto out_child;
Robert Richtere20960c2011-12-07 10:02:55 +0100971 }
972
Arnaldo Carvalho de Melo34ba5122012-12-19 09:04:24 -0300973 machine = &session->machines.host;
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200974
Wang Nan4ea648a2016-07-14 08:34:47 +0000975 err = record__synthesize(rec, false);
Wang Nanc45c86e2016-02-26 09:32:07 +0000976 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900977 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600978
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200979 if (rec->realtime_prio) {
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200980 struct sched_param param;
981
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200982 param.sched_priority = rec->realtime_prio;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200983 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
Arnaldo Carvalho de Melo6beba7a2009-10-21 17:34:06 -0200984 pr_err("Could not set realtime priority.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600985 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900986 goto out_child;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200987 }
988 }
989
Jiri Olsa774cb492012-11-12 18:34:01 +0100990 /*
991 * When perf is starting the traced process, all the events
992 * (apart from group members) have enable_on_exec=1 set,
993 * so don't spoil it by prematurely enabling them.
994 */
Andi Kleen6619a532014-01-11 13:38:27 -0800995 if (!target__none(&opts->target) && !opts->initial_delay)
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300996 perf_evlist__enable(rec->evlist);
David Ahern764e16a32011-08-25 10:17:55 -0600997
Peter Zijlstra856e9662009-12-16 17:55:55 +0100998 /*
999 * Let the child rip
1000 */
Namhyung Kime803cf92015-09-22 09:24:55 +09001001 if (forks) {
Namhyung Kime5bed5642015-09-30 10:45:24 +09001002 union perf_event *event;
Hari Bathinie907caf2017-03-08 02:11:51 +05301003 pid_t tgid;
Namhyung Kime5bed5642015-09-30 10:45:24 +09001004
1005 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
1006 if (event == NULL) {
1007 err = -ENOMEM;
1008 goto out_child;
1009 }
1010
Namhyung Kime803cf92015-09-22 09:24:55 +09001011 /*
1012 * Some H/W events are generated before COMM event
1013 * which is emitted during exec(), so perf script
1014 * cannot see a correct process name for those events.
1015 * Synthesize COMM event to prevent it.
1016 */
Hari Bathinie907caf2017-03-08 02:11:51 +05301017 tgid = perf_event__synthesize_comm(tool, event,
1018 rec->evlist->workload.pid,
1019 process_synthesized_event,
1020 machine);
1021 free(event);
1022
1023 if (tgid == -1)
1024 goto out_child;
1025
1026 event = malloc(sizeof(event->namespaces) +
1027 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
1028 machine->id_hdr_size);
1029 if (event == NULL) {
1030 err = -ENOMEM;
1031 goto out_child;
1032 }
1033
1034 /*
1035 * Synthesize NAMESPACES event for the command specified.
1036 */
1037 perf_event__synthesize_namespaces(tool, event,
1038 rec->evlist->workload.pid,
1039 tgid, process_synthesized_event,
1040 machine);
Namhyung Kime5bed5642015-09-30 10:45:24 +09001041 free(event);
Namhyung Kime803cf92015-09-22 09:24:55 +09001042
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001043 perf_evlist__start_workload(rec->evlist);
Namhyung Kime803cf92015-09-22 09:24:55 +09001044 }
Peter Zijlstra856e9662009-12-16 17:55:55 +01001045
Andi Kleen6619a532014-01-11 13:38:27 -08001046 if (opts->initial_delay) {
Arnaldo Carvalho de Melo0693e682016-08-08 15:05:46 -03001047 usleep(opts->initial_delay * USEC_PER_MSEC);
Andi Kleen6619a532014-01-11 13:38:27 -08001048 perf_evlist__enable(rec->evlist);
1049 }
1050
Wang Nan5f9cf592016-04-20 18:59:49 +00001051 trigger_ready(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001052 trigger_ready(&switch_output_trigger);
Wang Nana0748652016-11-26 07:03:28 +00001053 perf_hooks__invoke_record_start();
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001054 for (;;) {
Yang Shi9f065192015-09-29 14:49:43 -07001055 unsigned long long hits = rec->samples;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001056
Wang Nan057374642016-07-14 08:34:43 +00001057 /*
1058 * rec->evlist->bkw_mmap_state is possible to be
1059 * BKW_MMAP_EMPTY here: when done == true and
1060 * hits != rec->samples in previous round.
1061 *
1062 * perf_evlist__toggle_bkw_mmap ensure we never
1063 * convert BKW_MMAP_EMPTY to BKW_MMAP_DATA_PENDING.
1064 */
1065 if (trigger_is_hit(&switch_output_trigger) || done || draining)
1066 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_DATA_PENDING);
1067
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001068 if (record__mmap_read_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +00001069 trigger_error(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001070 trigger_error(&switch_output_trigger);
David Ahern8d3eca22012-08-26 12:24:47 -06001071 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001072 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -06001073 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001074
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001075 if (auxtrace_record__snapshot_started) {
1076 auxtrace_record__snapshot_started = 0;
Wang Nan5f9cf592016-04-20 18:59:49 +00001077 if (!trigger_is_error(&auxtrace_snapshot_trigger))
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001078 record__read_auxtrace_snapshot(rec);
Wang Nan5f9cf592016-04-20 18:59:49 +00001079 if (trigger_is_error(&auxtrace_snapshot_trigger)) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001080 pr_err("AUX area tracing snapshot failed\n");
1081 err = -1;
1082 goto out_child;
1083 }
1084 }
1085
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001086 if (trigger_is_hit(&switch_output_trigger)) {
Wang Nan057374642016-07-14 08:34:43 +00001087 /*
1088 * If switch_output_trigger is hit, the data in
1089 * overwritable ring buffer should have been collected,
1090 * so bkw_mmap_state should be set to BKW_MMAP_EMPTY.
1091 *
1092 * If SIGUSR2 raise after or during record__mmap_read_all(),
1093 * record__mmap_read_all() didn't collect data from
1094 * overwritable ring buffer. Read again.
1095 */
1096 if (rec->evlist->bkw_mmap_state == BKW_MMAP_RUNNING)
1097 continue;
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001098 trigger_ready(&switch_output_trigger);
1099
Wang Nan057374642016-07-14 08:34:43 +00001100 /*
1101 * Reenable events in overwrite ring buffer after
1102 * record__mmap_read_all(): we should have collected
1103 * data from it.
1104 */
1105 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_RUNNING);
1106
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001107 if (!quiet)
1108 fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
1109 waking);
1110 waking = 0;
1111 fd = record__switch_output(rec, false);
1112 if (fd < 0) {
1113 pr_err("Failed to switch to new file\n");
1114 trigger_error(&switch_output_trigger);
1115 err = fd;
1116 goto out_child;
1117 }
Jiri Olsabfacbe32017-01-09 10:52:00 +01001118
1119 /* re-arm the alarm */
1120 if (rec->switch_output.time)
1121 alarm(rec->switch_output.time);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001122 }
1123
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001124 if (hits == rec->samples) {
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001125 if (done || draining)
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001126 break;
Arnaldo Carvalho de Melof66a889d2014-08-18 17:25:59 -03001127 err = perf_evlist__poll(rec->evlist, -1);
Jiri Olsaa5151142014-06-02 13:44:23 -04001128 /*
1129 * Propagate error, only if there's any. Ignore positive
1130 * number of returned events and interrupt error.
1131 */
1132 if (err > 0 || (err < 0 && errno == EINTR))
Namhyung Kim45604712014-05-12 09:47:24 +09001133 err = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001134 waking++;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001135
1136 if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
1137 draining = true;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001138 }
1139
Jiri Olsa774cb492012-11-12 18:34:01 +01001140 /*
1141 * When perf is starting the traced process, at the end events
1142 * die with the process and we wait for that. Thus no need to
1143 * disable events in this case.
1144 */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001145 if (done && !disabled && !target__none(&opts->target)) {
Wang Nan5f9cf592016-04-20 18:59:49 +00001146 trigger_off(&auxtrace_snapshot_trigger);
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001147 perf_evlist__disable(rec->evlist);
Jiri Olsa27119262012-11-12 18:34:02 +01001148 disabled = true;
1149 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001150 }
Wang Nan5f9cf592016-04-20 18:59:49 +00001151 trigger_off(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001152 trigger_off(&switch_output_trigger);
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001153
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001154 if (forks && workload_exec_errno) {
Masami Hiramatsu35550da2014-08-14 02:22:43 +00001155 char msg[STRERR_BUFSIZE];
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -03001156 const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001157 pr_err("Workload failed: %s\n", emsg);
1158 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001159 goto out_child;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001160 }
1161
Namhyung Kime3d59112015-01-29 17:06:44 +09001162 if (!quiet)
Namhyung Kim45604712014-05-12 09:47:24 +09001163 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001164
Wang Nan4ea648a2016-07-14 08:34:47 +00001165 if (target__none(&rec->opts.target))
1166 record__synthesize_workload(rec, true);
1167
Namhyung Kim45604712014-05-12 09:47:24 +09001168out_child:
1169 if (forks) {
1170 int exit_status;
Ingo Molnaraddc2782009-06-02 23:43:11 +02001171
Namhyung Kim45604712014-05-12 09:47:24 +09001172 if (!child_finished)
1173 kill(rec->evlist->workload.pid, SIGTERM);
1174
1175 wait(&exit_status);
1176
1177 if (err < 0)
1178 status = err;
1179 else if (WIFEXITED(exit_status))
1180 status = WEXITSTATUS(exit_status);
1181 else if (WIFSIGNALED(exit_status))
1182 signr = WTERMSIG(exit_status);
1183 } else
1184 status = err;
1185
Wang Nan4ea648a2016-07-14 08:34:47 +00001186 record__synthesize(rec, true);
Namhyung Kime3d59112015-01-29 17:06:44 +09001187 /* this will be recalculated during process_buildids() */
1188 rec->samples = 0;
1189
Wang Nanecfd7a92016-04-13 08:21:07 +00001190 if (!err) {
1191 if (!rec->timestamp_filename) {
1192 record__finish_output(rec);
1193 } else {
1194 fd = record__switch_output(rec, true);
1195 if (fd < 0) {
1196 status = fd;
1197 goto out_delete_session;
1198 }
1199 }
1200 }
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001201
Wang Nana0748652016-11-26 07:03:28 +00001202 perf_hooks__invoke_record_end();
1203
Namhyung Kime3d59112015-01-29 17:06:44 +09001204 if (!err && !quiet) {
1205 char samples[128];
Wang Nanecfd7a92016-04-13 08:21:07 +00001206 const char *postfix = rec->timestamp_filename ?
1207 ".<timestamp>" : "";
Namhyung Kime3d59112015-01-29 17:06:44 +09001208
Adrian Hunteref149c22015-04-09 18:53:45 +03001209 if (rec->samples && !rec->opts.full_auxtrace)
Namhyung Kime3d59112015-01-29 17:06:44 +09001210 scnprintf(samples, sizeof(samples),
1211 " (%" PRIu64 " samples)", rec->samples);
1212 else
1213 samples[0] = '\0';
1214
Wang Nanecfd7a92016-04-13 08:21:07 +00001215 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
Namhyung Kime3d59112015-01-29 17:06:44 +09001216 perf_data_file__size(file) / 1024.0 / 1024.0,
Wang Nanecfd7a92016-04-13 08:21:07 +00001217 file->path, postfix, samples);
Namhyung Kime3d59112015-01-29 17:06:44 +09001218 }
1219
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001220out_delete_session:
1221 perf_session__delete(session);
Namhyung Kim45604712014-05-12 09:47:24 +09001222 return status;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001223}
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001224
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001225static void callchain_debug(struct callchain_param *callchain)
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001226{
Kan Liangaad2b212015-01-05 13:23:04 -05001227 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
Jiri Olsaa601fdf2014-02-03 12:44:43 +01001228
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001229 pr_debug("callchain: type %s\n", str[callchain->record_mode]);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001230
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001231 if (callchain->record_mode == CALLCHAIN_DWARF)
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001232 pr_debug("callchain: stack dump size %d\n",
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001233 callchain->dump_size);
1234}
1235
1236int record_opts__parse_callchain(struct record_opts *record,
1237 struct callchain_param *callchain,
1238 const char *arg, bool unset)
1239{
1240 int ret;
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001241 callchain->enabled = !unset;
1242
1243 /* --no-call-graph */
1244 if (unset) {
1245 callchain->record_mode = CALLCHAIN_NONE;
1246 pr_debug("callchain: disabled\n");
1247 return 0;
1248 }
1249
1250 ret = parse_callchain_record_opt(arg, callchain);
1251 if (!ret) {
1252 /* Enable data address sampling for DWARF unwind. */
1253 if (callchain->record_mode == CALLCHAIN_DWARF)
1254 record->sample_address = true;
1255 callchain_debug(callchain);
1256 }
1257
1258 return ret;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001259}
1260
Kan Liangc421e802015-07-29 05:42:12 -04001261int record_parse_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001262 const char *arg,
1263 int unset)
1264{
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001265 return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
Jiri Olsa26d33022012-08-07 15:20:47 +02001266}
1267
Kan Liangc421e802015-07-29 05:42:12 -04001268int record_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001269 const char *arg __maybe_unused,
1270 int unset __maybe_unused)
1271{
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001272 struct callchain_param *callchain = opt->value;
Kan Liangc421e802015-07-29 05:42:12 -04001273
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001274 callchain->enabled = true;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001275
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001276 if (callchain->record_mode == CALLCHAIN_NONE)
1277 callchain->record_mode = CALLCHAIN_FP;
Jiri Olsaeb853e82014-02-03 12:44:42 +01001278
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001279 callchain_debug(callchain);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001280 return 0;
1281}
1282
Jiri Olsaeb853e82014-02-03 12:44:42 +01001283static int perf_record_config(const char *var, const char *value, void *cb)
1284{
Namhyung Kim7a29c082015-12-15 10:49:56 +09001285 struct record *rec = cb;
1286
1287 if (!strcmp(var, "record.build-id")) {
1288 if (!strcmp(value, "cache"))
1289 rec->no_buildid_cache = false;
1290 else if (!strcmp(value, "no-cache"))
1291 rec->no_buildid_cache = true;
1292 else if (!strcmp(value, "skip"))
1293 rec->no_buildid = true;
1294 else
1295 return -1;
1296 return 0;
1297 }
Jiri Olsaeb853e82014-02-03 12:44:42 +01001298 if (!strcmp(var, "record.call-graph"))
Namhyung Kim5a2e5e82014-09-23 10:01:44 +09001299 var = "call-graph.record-mode"; /* fall-through */
Jiri Olsaeb853e82014-02-03 12:44:42 +01001300
1301 return perf_default_config(var, value, cb);
1302}
1303
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001304struct clockid_map {
1305 const char *name;
1306 int clockid;
1307};
1308
1309#define CLOCKID_MAP(n, c) \
1310 { .name = n, .clockid = (c), }
1311
1312#define CLOCKID_END { .name = NULL, }
1313
1314
1315/*
1316 * Add the missing ones, we need to build on many distros...
1317 */
1318#ifndef CLOCK_MONOTONIC_RAW
1319#define CLOCK_MONOTONIC_RAW 4
1320#endif
1321#ifndef CLOCK_BOOTTIME
1322#define CLOCK_BOOTTIME 7
1323#endif
1324#ifndef CLOCK_TAI
1325#define CLOCK_TAI 11
1326#endif
1327
1328static const struct clockid_map clockids[] = {
1329 /* available for all events, NMI safe */
1330 CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
1331 CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
1332
1333 /* available for some events */
1334 CLOCKID_MAP("realtime", CLOCK_REALTIME),
1335 CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
1336 CLOCKID_MAP("tai", CLOCK_TAI),
1337
1338 /* available for the lazy */
1339 CLOCKID_MAP("mono", CLOCK_MONOTONIC),
1340 CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
1341 CLOCKID_MAP("real", CLOCK_REALTIME),
1342 CLOCKID_MAP("boot", CLOCK_BOOTTIME),
1343
1344 CLOCKID_END,
1345};
1346
1347static int parse_clockid(const struct option *opt, const char *str, int unset)
1348{
1349 struct record_opts *opts = (struct record_opts *)opt->value;
1350 const struct clockid_map *cm;
1351 const char *ostr = str;
1352
1353 if (unset) {
1354 opts->use_clockid = 0;
1355 return 0;
1356 }
1357
1358 /* no arg passed */
1359 if (!str)
1360 return 0;
1361
1362 /* no setting it twice */
1363 if (opts->use_clockid)
1364 return -1;
1365
1366 opts->use_clockid = true;
1367
1368 /* if its a number, we're done */
1369 if (sscanf(str, "%d", &opts->clockid) == 1)
1370 return 0;
1371
1372 /* allow a "CLOCK_" prefix to the name */
1373 if (!strncasecmp(str, "CLOCK_", 6))
1374 str += 6;
1375
1376 for (cm = clockids; cm->name; cm++) {
1377 if (!strcasecmp(str, cm->name)) {
1378 opts->clockid = cm->clockid;
1379 return 0;
1380 }
1381 }
1382
1383 opts->use_clockid = false;
1384 ui__warning("unknown clockid %s, check man page\n", ostr);
1385 return -1;
1386}
1387
Adrian Huntere9db1312015-04-09 18:53:46 +03001388static int record__parse_mmap_pages(const struct option *opt,
1389 const char *str,
1390 int unset __maybe_unused)
1391{
1392 struct record_opts *opts = opt->value;
1393 char *s, *p;
1394 unsigned int mmap_pages;
1395 int ret;
1396
1397 if (!str)
1398 return -EINVAL;
1399
1400 s = strdup(str);
1401 if (!s)
1402 return -ENOMEM;
1403
1404 p = strchr(s, ',');
1405 if (p)
1406 *p = '\0';
1407
1408 if (*s) {
1409 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
1410 if (ret)
1411 goto out_free;
1412 opts->mmap_pages = mmap_pages;
1413 }
1414
1415 if (!p) {
1416 ret = 0;
1417 goto out_free;
1418 }
1419
1420 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
1421 if (ret)
1422 goto out_free;
1423
1424 opts->auxtrace_mmap_pages = mmap_pages;
1425
1426out_free:
1427 free(s);
1428 return ret;
1429}
1430
Jiri Olsa0c582442017-01-09 10:51:59 +01001431static void switch_output_size_warn(struct record *rec)
1432{
1433 u64 wakeup_size = perf_evlist__mmap_size(rec->opts.mmap_pages);
1434 struct switch_output *s = &rec->switch_output;
1435
1436 wakeup_size /= 2;
1437
1438 if (s->size < wakeup_size) {
1439 char buf[100];
1440
1441 unit_number__scnprintf(buf, sizeof(buf), wakeup_size);
1442 pr_warning("WARNING: switch-output data size lower than "
1443 "wakeup kernel buffer size (%s) "
1444 "expect bigger perf.data sizes\n", buf);
1445 }
1446}
1447
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001448static int switch_output_setup(struct record *rec)
1449{
1450 struct switch_output *s = &rec->switch_output;
Jiri Olsadc0c6122017-01-09 10:51:58 +01001451 static struct parse_tag tags_size[] = {
1452 { .tag = 'B', .mult = 1 },
1453 { .tag = 'K', .mult = 1 << 10 },
1454 { .tag = 'M', .mult = 1 << 20 },
1455 { .tag = 'G', .mult = 1 << 30 },
1456 { .tag = 0 },
1457 };
Jiri Olsabfacbe32017-01-09 10:52:00 +01001458 static struct parse_tag tags_time[] = {
1459 { .tag = 's', .mult = 1 },
1460 { .tag = 'm', .mult = 60 },
1461 { .tag = 'h', .mult = 60*60 },
1462 { .tag = 'd', .mult = 60*60*24 },
1463 { .tag = 0 },
1464 };
Jiri Olsadc0c6122017-01-09 10:51:58 +01001465 unsigned long val;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001466
1467 if (!s->set)
1468 return 0;
1469
1470 if (!strcmp(s->str, "signal")) {
1471 s->signal = true;
1472 pr_debug("switch-output with SIGUSR2 signal\n");
Jiri Olsadc0c6122017-01-09 10:51:58 +01001473 goto enabled;
1474 }
1475
1476 val = parse_tag_value(s->str, tags_size);
1477 if (val != (unsigned long) -1) {
1478 s->size = val;
1479 pr_debug("switch-output with %s size threshold\n", s->str);
1480 goto enabled;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001481 }
1482
Jiri Olsabfacbe32017-01-09 10:52:00 +01001483 val = parse_tag_value(s->str, tags_time);
1484 if (val != (unsigned long) -1) {
1485 s->time = val;
1486 pr_debug("switch-output with %s time threshold (%lu seconds)\n",
1487 s->str, s->time);
1488 goto enabled;
1489 }
1490
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001491 return -1;
Jiri Olsadc0c6122017-01-09 10:51:58 +01001492
1493enabled:
1494 rec->timestamp_filename = true;
1495 s->enabled = true;
Jiri Olsa0c582442017-01-09 10:51:59 +01001496
1497 if (s->size && !rec->opts.no_buffering)
1498 switch_output_size_warn(rec);
1499
Jiri Olsadc0c6122017-01-09 10:51:58 +01001500 return 0;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001501}
1502
Namhyung Kime5b2c202014-10-23 00:15:46 +09001503static const char * const __record_usage[] = {
Mike Galbraith9e0967532009-05-28 16:25:34 +02001504 "perf record [<options>] [<command>]",
1505 "perf record [<options>] -- <command> [<options>]",
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001506 NULL
1507};
Namhyung Kime5b2c202014-10-23 00:15:46 +09001508const char * const *record_usage = __record_usage;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001509
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001510/*
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001511 * XXX Ideally would be local to cmd_record() and passed to a record__new
1512 * because we need to have access to it in record__exit, that is called
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001513 * after cmd_record() exits, but since record_options need to be accessible to
1514 * builtin-script, leave it here.
1515 *
1516 * At least we don't ouch it in all the other functions here directly.
1517 *
1518 * Just say no to tons of global variables, sigh.
1519 */
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001520static struct record record = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001521 .opts = {
Andi Kleen8affc2b2014-07-31 14:45:04 +08001522 .sample_time = true,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001523 .mmap_pages = UINT_MAX,
1524 .user_freq = UINT_MAX,
1525 .user_interval = ULLONG_MAX,
Arnaldo Carvalho de Melo447a6012012-05-22 13:14:18 -03001526 .freq = 4000,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001527 .target = {
1528 .uses_mmap = true,
Adrian Hunter3aa59392013-11-15 15:52:29 +02001529 .default_per_cpu = true,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001530 },
Kan Liang9d9cad72015-06-17 09:51:11 -04001531 .proc_map_timeout = 500,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001532 },
Namhyung Kime3d59112015-01-29 17:06:44 +09001533 .tool = {
1534 .sample = process_sample_event,
1535 .fork = perf_event__process_fork,
Adrian Huntercca84822015-08-19 17:29:21 +03001536 .exit = perf_event__process_exit,
Namhyung Kime3d59112015-01-29 17:06:44 +09001537 .comm = perf_event__process_comm,
Hari Bathinif3b36142017-03-08 02:11:43 +05301538 .namespaces = perf_event__process_namespaces,
Namhyung Kime3d59112015-01-29 17:06:44 +09001539 .mmap = perf_event__process_mmap,
1540 .mmap2 = perf_event__process_mmap2,
Adrian Huntercca84822015-08-19 17:29:21 +03001541 .ordered_events = true,
Namhyung Kime3d59112015-01-29 17:06:44 +09001542 },
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001543};
Frederic Weisbecker7865e812010-04-14 19:42:07 +02001544
Namhyung Kim76a26542015-10-22 23:28:32 +09001545const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1546 "\n\t\t\t\tDefault: fp";
Arnaldo Carvalho de Melo61eaa3b2012-10-01 15:20:58 -03001547
Wang Nan0aab2132016-06-16 08:02:41 +00001548static bool dry_run;
1549
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001550/*
1551 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
1552 * with it and switch to use the library functions in perf_evlist that came
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001553 * from builtin-record.c, i.e. use record_opts,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001554 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
1555 * using pipes, etc.
1556 */
Jiri Olsaefd21302017-01-03 09:19:55 +01001557static struct option __record_options[] = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001558 OPT_CALLBACK('e', "event", &record.evlist, "event",
Thomas Gleixner86847b62009-06-06 12:24:17 +02001559 "event selector. use 'perf list' to list available events",
Jiri Olsaf120f9d2011-07-14 11:25:32 +02001560 parse_events_option),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001561 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
Li Zefanc171b552009-10-15 11:22:07 +08001562 "event filter", parse_filter),
Wang Nan4ba1faa2015-07-10 07:36:10 +00001563 OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
1564 NULL, "don't record events from perf itself",
1565 exclude_perf),
Namhyung Kimbea03402012-04-26 14:15:15 +09001566 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001567 "record events on existing process id"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001568 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001569 "record events on existing thread id"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001570 OPT_INTEGER('r', "realtime", &record.realtime_prio,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001571 "collect data with this RT SCHED_FIFO priority"),
Arnaldo Carvalho de Melo509051e2014-01-14 17:52:14 -03001572 OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
Kirill Smelkovacac03f2011-01-12 17:59:36 +03001573 "collect data without buffering"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001574 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
Frederic Weisbeckerdaac07b2009-08-13 10:27:19 +02001575 "collect raw sample records from all opened counters"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001576 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001577 "system-wide collection from all CPUs"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001578 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
Stephane Eranianc45c6ea2010-05-28 12:00:01 +02001579 "list of cpus to monitor"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001580 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
Jiri Olsaf5fc14122013-10-15 16:27:32 +02001581 OPT_STRING('o', "output", &record.file.path, "file",
Ingo Molnarabaff322009-06-02 22:59:57 +02001582 "output file name"),
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001583 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1584 &record.opts.no_inherit_set,
1585 "child tasks do not inherit counters"),
Wang Nan4ea648a2016-07-14 08:34:47 +00001586 OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize,
1587 "synthesize non-sample events at the end of output"),
Wang Nan626a6b72016-07-14 08:34:45 +00001588 OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001589 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
Adrian Huntere9db1312015-04-09 18:53:46 +03001590 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
1591 "number of mmap data pages and AUX area tracing mmap pages",
1592 record__parse_mmap_pages),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001593 OPT_BOOLEAN(0, "group", &record.opts.group,
Lin Ming43bece72011-08-17 18:42:07 +08001594 "put the counters into a counter group"),
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001595 OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001596 NULL, "enables call-graph recording" ,
1597 &record_callchain_opt),
1598 OPT_CALLBACK(0, "call-graph", &record.opts,
Namhyung Kim76a26542015-10-22 23:28:32 +09001599 "record_mode[,record_size]", record_callchain_help,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001600 &record_parse_callchain_opt),
Ian Munsiec0555642010-04-13 18:37:33 +10001601 OPT_INCR('v', "verbose", &verbose,
Ingo Molnar3da297a2009-06-07 17:39:02 +02001602 "be more verbose (show counter open errors, etc)"),
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001603 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001604 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001605 "per thread counts"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001606 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
Kan Liang3b0a5da2017-08-29 13:11:08 -04001607 OPT_BOOLEAN(0, "phys-data", &record.opts.sample_phys_addr,
1608 "Record the sample physical addresses"),
Jiri Olsab6f35ed2016-08-01 20:02:35 +02001609 OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"),
Adrian Hunter3abebc52015-07-06 14:51:01 +03001610 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
1611 &record.opts.sample_time_set,
1612 "Record the sample timestamps"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001613 OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001614 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001615 "don't sample"),
Wang Nand2db9a92016-01-25 09:56:19 +00001616 OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
1617 &record.no_buildid_cache_set,
1618 "do not update the buildid cache"),
1619 OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
1620 &record.no_buildid_set,
1621 "do not collect buildids in perf.data"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001622 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
Stephane Eranian023695d2011-02-14 11:20:01 +02001623 "monitor event in cgroup name only",
1624 parse_cgroups),
Arnaldo Carvalho de Meloa6205a32014-01-14 17:58:12 -03001625 OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
Andi Kleen6619a532014-01-11 13:38:27 -08001626 "ms to wait before starting measurement after program start"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001627 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
1628 "user to profile"),
Stephane Eraniana5aabda2012-03-08 23:47:45 +01001629
1630 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
1631 "branch any", "sample any taken branches",
1632 parse_branch_stack),
1633
1634 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
1635 "branch filter mask", "branch stack filter modes",
Roberto Agostino Vitillobdfebd82012-02-09 23:21:02 +01001636 parse_branch_stack),
Andi Kleen05484292013-01-24 16:10:29 +01001637 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
1638 "sample by weight (on special events only)"),
Andi Kleen475eeab2013-09-20 07:40:43 -07001639 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
1640 "sample transaction flags (special events only)"),
Adrian Hunter3aa59392013-11-15 15:52:29 +02001641 OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
1642 "use per-thread mmaps"),
Stephane Eranianbcc84ec2015-08-31 18:41:12 +02001643 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
1644 "sample selected machine registers on interrupt,"
1645 " use -I ? to list register names", parse_regs),
Andi Kleen84c41742017-09-05 10:00:28 -07001646 OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register",
1647 "sample selected machine registers on interrupt,"
1648 " use -I ? to list register names", parse_regs),
Andi Kleen85c273d2015-02-24 15:13:40 -08001649 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
1650 "Record running/enabled time of read (:S) events"),
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001651 OPT_CALLBACK('k', "clockid", &record.opts,
1652 "clockid", "clockid to use for events, see clock_gettime()",
1653 parse_clockid),
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001654 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
1655 "opts", "AUX area tracing Snapshot Mode", ""),
Kan Liang9d9cad72015-06-17 09:51:11 -04001656 OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
1657 "per thread proc mmap processing timeout in ms"),
Hari Bathinif3b36142017-03-08 02:11:43 +05301658 OPT_BOOLEAN(0, "namespaces", &record.opts.record_namespaces,
1659 "Record namespaces events"),
Adrian Hunterb757bb02015-07-21 12:44:04 +03001660 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1661 "Record context switch events"),
Jiri Olsa85723882016-02-15 09:34:31 +01001662 OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
1663 "Configure all used events to run in kernel space.",
1664 PARSE_OPT_EXCLUSIVE),
1665 OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
1666 "Configure all used events to run in user space.",
1667 PARSE_OPT_EXCLUSIVE),
Wang Nan71dc23262015-10-14 12:41:19 +00001668 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1669 "clang binary to use for compiling BPF scriptlets"),
1670 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1671 "options passed to clang when compiling BPF scriptlets"),
He Kuang7efe0e02015-12-14 10:39:23 +00001672 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1673 "file", "vmlinux pathname"),
Namhyung Kim61566812016-01-11 22:37:09 +09001674 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
1675 "Record build-id of all DSOs regardless of hits"),
Wang Nanecfd7a92016-04-13 08:21:07 +00001676 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1677 "append timestamp to output filename"),
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001678 OPT_STRING_OPTARG_SET(0, "switch-output", &record.switch_output.str,
Jiri Olsabfacbe32017-01-09 10:52:00 +01001679 &record.switch_output.set, "signal,size,time",
1680 "Switch output when receive SIGUSR2 or cross size,time threshold",
Jiri Olsadc0c6122017-01-09 10:51:58 +01001681 "signal"),
Wang Nan0aab2132016-06-16 08:02:41 +00001682 OPT_BOOLEAN(0, "dry-run", &dry_run,
1683 "Parse options then exit"),
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001684 OPT_END()
1685};
1686
Namhyung Kime5b2c202014-10-23 00:15:46 +09001687struct option *record_options = __record_options;
1688
Arnaldo Carvalho de Melob0ad8ea2017-03-27 11:47:20 -03001689int cmd_record(int argc, const char **argv)
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001690{
Adrian Hunteref149c22015-04-09 18:53:45 +03001691 int err;
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001692 struct record *rec = &record;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001693 char errbuf[BUFSIZ];
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001694
Wang Nan48e1cab2015-12-14 10:39:22 +00001695#ifndef HAVE_LIBBPF_SUPPORT
1696# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
1697 set_nobuild('\0', "clang-path", true);
1698 set_nobuild('\0', "clang-opt", true);
1699# undef set_nobuild
1700#endif
1701
He Kuang7efe0e02015-12-14 10:39:23 +00001702#ifndef HAVE_BPF_PROLOGUE
1703# if !defined (HAVE_DWARF_SUPPORT)
1704# define REASON "NO_DWARF=1"
1705# elif !defined (HAVE_LIBBPF_SUPPORT)
1706# define REASON "NO_LIBBPF=1"
1707# else
1708# define REASON "this architecture doesn't support BPF prologue"
1709# endif
1710# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
1711 set_nobuild('\0', "vmlinux", true);
1712# undef set_nobuild
1713# undef REASON
1714#endif
1715
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001716 rec->evlist = perf_evlist__new();
1717 if (rec->evlist == NULL)
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -02001718 return -ENOMEM;
1719
Arnaldo Carvalho de Meloecc4c562017-01-24 13:44:10 -03001720 err = perf_config(perf_record_config, rec);
1721 if (err)
1722 return err;
Jiri Olsaeb853e82014-02-03 12:44:42 +01001723
Tom Zanussibca647a2010-11-10 08:11:30 -06001724 argc = parse_options(argc, argv, record_options, record_usage,
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001725 PARSE_OPT_STOP_AT_NON_OPTION);
Namhyung Kim68ba3232017-02-17 17:17:42 +09001726 if (quiet)
1727 perf_quiet_option();
Jiri Olsa483635a2017-02-17 18:00:18 +01001728
1729 /* Make system wide (-a) the default target. */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001730 if (!argc && target__none(&rec->opts.target))
Jiri Olsa483635a2017-02-17 18:00:18 +01001731 rec->opts.target.system_wide = true;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001732
Namhyung Kimbea03402012-04-26 14:15:15 +09001733 if (nr_cgroups && !rec->opts.target.system_wide) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001734 usage_with_options_msg(record_usage, record_options,
1735 "cgroup monitoring only available in system-wide mode");
1736
Stephane Eranian023695d2011-02-14 11:20:01 +02001737 }
Adrian Hunterb757bb02015-07-21 12:44:04 +03001738 if (rec->opts.record_switch_events &&
1739 !perf_can_record_switch_events()) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001740 ui__error("kernel does not support recording context switch events\n");
1741 parse_options_usage(record_usage, record_options, "switch-events", 0);
1742 return -EINVAL;
Adrian Hunterb757bb02015-07-21 12:44:04 +03001743 }
Stephane Eranian023695d2011-02-14 11:20:01 +02001744
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001745 if (switch_output_setup(rec)) {
1746 parse_options_usage(record_usage, record_options, "switch-output", 0);
1747 return -EINVAL;
1748 }
1749
Jiri Olsabfacbe32017-01-09 10:52:00 +01001750 if (rec->switch_output.time) {
1751 signal(SIGALRM, alarm_sig_handler);
1752 alarm(rec->switch_output.time);
1753 }
1754
Adrian Hunteref149c22015-04-09 18:53:45 +03001755 if (!rec->itr) {
1756 rec->itr = auxtrace_record__init(rec->evlist, &err);
1757 if (err)
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001758 goto out;
Adrian Hunteref149c22015-04-09 18:53:45 +03001759 }
1760
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001761 err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
1762 rec->opts.auxtrace_snapshot_opts);
1763 if (err)
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001764 goto out;
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001765
Adrian Hunter1b36c032016-09-23 17:38:39 +03001766 /*
1767 * Allow aliases to facilitate the lookup of symbols for address
1768 * filters. Refer to auxtrace_parse_filters().
1769 */
1770 symbol_conf.allow_aliases = true;
1771
1772 symbol__init(NULL);
1773
1774 err = auxtrace_parse_filters(rec->evlist);
1775 if (err)
1776 goto out;
1777
Wang Nan0aab2132016-06-16 08:02:41 +00001778 if (dry_run)
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001779 goto out;
Wang Nan0aab2132016-06-16 08:02:41 +00001780
Wang Nand7888572016-04-08 15:07:24 +00001781 err = bpf__setup_stdout(rec->evlist);
1782 if (err) {
1783 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
1784 pr_err("ERROR: Setup BPF stdout failed: %s\n",
1785 errbuf);
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001786 goto out;
Wang Nand7888572016-04-08 15:07:24 +00001787 }
1788
Adrian Hunteref149c22015-04-09 18:53:45 +03001789 err = -ENOMEM;
1790
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001791 if (symbol_conf.kptr_restrict)
Arnaldo Carvalho de Melo646aaea2011-05-27 11:00:41 -03001792 pr_warning(
1793"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
1794"check /proc/sys/kernel/kptr_restrict.\n\n"
1795"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
1796"file is not found in the buildid cache or in the vmlinux path.\n\n"
1797"Samples in kernel modules won't be resolved at all.\n\n"
1798"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
1799"even with a suitable vmlinux or kallsyms file.\n\n");
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001800
Wang Nan0c1d46a2016-04-20 18:59:52 +00001801 if (rec->no_buildid_cache || rec->no_buildid) {
Stephane Eraniana1ac1d32010-06-17 11:39:01 +02001802 disable_buildid_cache();
Jiri Olsadc0c6122017-01-09 10:51:58 +01001803 } else if (rec->switch_output.enabled) {
Wang Nan0c1d46a2016-04-20 18:59:52 +00001804 /*
1805 * In 'perf record --switch-output', disable buildid
1806 * generation by default to reduce data file switching
1807 * overhead. Still generate buildid if they are required
1808 * explicitly using
1809 *
Jiri Olsa60437ac2017-01-03 09:19:56 +01001810 * perf record --switch-output --no-no-buildid \
Wang Nan0c1d46a2016-04-20 18:59:52 +00001811 * --no-no-buildid-cache
1812 *
1813 * Following code equals to:
1814 *
1815 * if ((rec->no_buildid || !rec->no_buildid_set) &&
1816 * (rec->no_buildid_cache || !rec->no_buildid_cache_set))
1817 * disable_buildid_cache();
1818 */
1819 bool disable = true;
1820
1821 if (rec->no_buildid_set && !rec->no_buildid)
1822 disable = false;
1823 if (rec->no_buildid_cache_set && !rec->no_buildid_cache)
1824 disable = false;
1825 if (disable) {
1826 rec->no_buildid = true;
1827 rec->no_buildid_cache = true;
1828 disable_buildid_cache();
1829 }
1830 }
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001831
Wang Nan4ea648a2016-07-14 08:34:47 +00001832 if (record.opts.overwrite)
1833 record.opts.tail_synthesize = true;
1834
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001835 if (rec->evlist->nr_entries == 0 &&
Arnaldo Carvalho de Melo4b4cd502017-07-03 13:26:32 -03001836 __perf_evlist__add_default(rec->evlist, !record.opts.no_samples) < 0) {
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001837 pr_err("Not enough memory for event selector list\n");
Adrian Hunter394c01e2016-09-23 17:38:36 +03001838 goto out;
Peter Zijlstrabbd36e52009-06-11 23:11:50 +02001839 }
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001840
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001841 if (rec->opts.target.tid && !rec->opts.no_inherit_set)
1842 rec->opts.no_inherit = true;
1843
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001844 err = target__validate(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001845 if (err) {
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001846 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001847 ui__warning("%s", errbuf);
1848 }
Namhyung Kim4bd0f2d2012-04-26 14:15:18 +09001849
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001850 err = target__parse_uid(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001851 if (err) {
1852 int saved_errno = errno;
1853
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001854 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim3780f482012-05-29 13:22:57 +09001855 ui__error("%s", errbuf);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001856
1857 err = -saved_errno;
Adrian Hunter394c01e2016-09-23 17:38:36 +03001858 goto out;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001859 }
Arnaldo Carvalho de Melo0d37aa32012-01-19 14:08:15 -02001860
Jiri Olsa23dc4f12016-12-12 11:35:43 +01001861 /* Enable ignoring missing threads when -u option is defined. */
1862 rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX;
1863
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001864 err = -ENOMEM;
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001865 if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -02001866 usage_with_options(record_usage, record_options);
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001867
Adrian Hunteref149c22015-04-09 18:53:45 +03001868 err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
1869 if (err)
Adrian Hunter394c01e2016-09-23 17:38:36 +03001870 goto out;
Adrian Hunteref149c22015-04-09 18:53:45 +03001871
Namhyung Kim61566812016-01-11 22:37:09 +09001872 /*
1873 * We take all buildids when the file contains
1874 * AUX area tracing data because we do not decode the
1875 * trace because it would take too long.
1876 */
1877 if (rec->opts.full_auxtrace)
1878 rec->buildid_all = true;
1879
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001880 if (record_opts__config(&rec->opts)) {
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001881 err = -EINVAL;
Adrian Hunter394c01e2016-09-23 17:38:36 +03001882 goto out;
Mike Galbraith7e4ff9e2009-10-12 07:56:03 +02001883 }
1884
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001885 err = __cmd_record(&record, argc, argv);
Adrian Hunter394c01e2016-09-23 17:38:36 +03001886out:
Namhyung Kim45604712014-05-12 09:47:24 +09001887 perf_evlist__delete(rec->evlist);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03001888 symbol__exit();
Adrian Hunteref149c22015-04-09 18:53:45 +03001889 auxtrace_record__free(rec->itr);
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001890 return err;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001891}
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001892
1893static void snapshot_sig_handler(int sig __maybe_unused)
1894{
Jiri Olsadc0c6122017-01-09 10:51:58 +01001895 struct record *rec = &record;
1896
Wang Nan5f9cf592016-04-20 18:59:49 +00001897 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1898 trigger_hit(&auxtrace_snapshot_trigger);
1899 auxtrace_record__snapshot_started = 1;
1900 if (auxtrace_record__snapshot_start(record.itr))
1901 trigger_error(&auxtrace_snapshot_trigger);
1902 }
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001903
Jiri Olsadc0c6122017-01-09 10:51:58 +01001904 if (switch_output_signal(rec))
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001905 trigger_hit(&switch_output_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001906}
Jiri Olsabfacbe32017-01-09 10:52:00 +01001907
1908static void alarm_sig_handler(int sig __maybe_unused)
1909{
1910 struct record *rec = &record;
1911
1912 if (switch_output_time(rec))
1913 trigger_hit(&switch_output_trigger);
1914}