blob: 17a14bcce34accf2ce1cf9a466cee97cf8b72b36 [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 Olsaf5fc1412013-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 Zijlstra97124d52009-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 Olsaf5fc1412013-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 Olsaf5fc1412013-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) {
802 err = perf_event__synthesize_attrs(tool, session,
803 process_synthesized_event);
804 if (err < 0) {
805 pr_err("Couldn't synthesize attrs.\n");
806 goto out;
807 }
808
809 if (have_tracepoints(&rec->evlist->entries)) {
810 /*
811 * FIXME err <= 0 here actually means that
812 * there were no tracepoints so its not really
813 * an error, just that we don't need to
814 * synthesize anything. We really have to
815 * return this more properly and also
816 * propagate errors that now are calling die()
817 */
818 err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
819 process_synthesized_event);
820 if (err <= 0) {
821 pr_err("Couldn't record tracing data.\n");
822 goto out;
823 }
824 rec->bytes_written += err;
825 }
826 }
827
Wang Nanc45628b2016-05-24 02:28:59 +0000828 err = perf_event__synth_time_conv(record__pick_pc(rec), tool,
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200829 process_synthesized_event, machine);
830 if (err)
831 goto out;
832
Wang Nanc45c86e2016-02-26 09:32:07 +0000833 if (rec->opts.full_auxtrace) {
834 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
835 session, process_synthesized_event);
836 if (err)
837 goto out;
838 }
839
840 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
841 machine);
842 WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
843 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
844 "Check /proc/kallsyms permission or run as root.\n");
845
846 err = perf_event__synthesize_modules(tool, process_synthesized_event,
847 machine);
848 WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
849 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
850 "Check /proc/modules permission or run as root.\n");
851
852 if (perf_guest) {
853 machines__process_guests(&session->machines,
854 perf_event__synthesize_guest_os, tool);
855 }
856
857 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
858 process_synthesized_event, opts->sample_address,
859 opts->proc_map_timeout);
860out:
861 return err;
862}
863
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300864static int __cmd_record(struct record *rec, int argc, const char **argv)
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200865{
David Ahern57706ab2013-11-06 11:41:34 -0700866 int err;
Namhyung Kim45604712014-05-12 09:47:24 +0900867 int status = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200868 unsigned long waking = 0;
Zhang, Yanmin46be6042010-03-18 11:36:04 -0300869 const bool forks = argc > 0;
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300870 struct machine *machine;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200871 struct perf_tool *tool = &rec->tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300872 struct record_opts *opts = &rec->opts;
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200873 struct perf_data_file *file = &rec->file;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200874 struct perf_session *session;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300875 bool disabled = false, draining = false;
Namhyung Kim42aa2762015-01-29 17:06:48 +0900876 int fd;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200877
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200878 rec->progname = argv[0];
Andi Kleen33e49ea2011-09-15 14:31:40 -0700879
Namhyung Kim45604712014-05-12 09:47:24 +0900880 atexit(record__sig_exit);
Peter Zijlstraf5970552009-06-18 23:22:55 +0200881 signal(SIGCHLD, sig_handler);
882 signal(SIGINT, sig_handler);
David Ahern804f7ac2013-05-06 12:24:23 -0600883 signal(SIGTERM, sig_handler);
Wang Nana0748652016-11-26 07:03:28 +0000884 signal(SIGSEGV, sigsegv_handler);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000885
Hari Bathinif3b36142017-03-08 02:11:43 +0530886 if (rec->opts.record_namespaces)
887 tool->namespace_events = true;
888
Jiri Olsadc0c6122017-01-09 10:51:58 +0100889 if (rec->opts.auxtrace_snapshot_mode || rec->switch_output.enabled) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300890 signal(SIGUSR2, snapshot_sig_handler);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000891 if (rec->opts.auxtrace_snapshot_mode)
892 trigger_on(&auxtrace_snapshot_trigger);
Jiri Olsadc0c6122017-01-09 10:51:58 +0100893 if (rec->switch_output.enabled)
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000894 trigger_on(&switch_output_trigger);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000895 } else {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300896 signal(SIGUSR2, SIG_IGN);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000897 }
Peter Zijlstraf5970552009-06-18 23:22:55 +0200898
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300899 session = perf_session__new(file, false, tool);
Arnaldo Carvalho de Melo94c744b2009-12-11 21:24:02 -0200900 if (session == NULL) {
Adrien BAKffa91882014-04-18 11:00:43 +0900901 pr_err("Perf session creation failed.\n");
Arnaldo Carvalho de Meloa9a70bb2009-11-17 01:18:11 -0200902 return -1;
903 }
904
Namhyung Kim42aa2762015-01-29 17:06:48 +0900905 fd = perf_data_file__fd(file);
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200906 rec->session = session;
907
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300908 record__init_features(rec);
Stephane Eranian330aa672012-03-08 23:47:46 +0100909
Arnaldo Carvalho de Melod4db3f12009-12-27 21:36:57 -0200910 if (forks) {
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300911 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200912 argv, file->is_pipe,
Arnaldo Carvalho de Melo735f7e02014-01-03 14:56:49 -0300913 workload_exec_failed_signal);
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200914 if (err < 0) {
915 pr_err("Couldn't run the workload!\n");
Namhyung Kim45604712014-05-12 09:47:24 +0900916 status = err;
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200917 goto out_delete_session;
Jens Axboe0a5ac842009-08-12 11:18:01 +0200918 }
Peter Zijlstra856e9662009-12-16 17:55:55 +0100919 }
920
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300921 if (record__open(rec) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600922 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900923 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600924 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200925
Wang Nan8690a2a2016-02-22 09:10:32 +0000926 err = bpf__apply_obj_config();
927 if (err) {
928 char errbuf[BUFSIZ];
929
930 bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
931 pr_err("ERROR: Apply config to BPF failed: %s\n",
932 errbuf);
933 goto out_child;
934 }
935
Adrian Huntercca84822015-08-19 17:29:21 +0300936 /*
937 * Normally perf_session__new would do this, but it doesn't have the
938 * evlist.
939 */
940 if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
941 pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
942 rec->tool.ordered_events = false;
943 }
944
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300945 if (!rec->evlist->nr_groups)
Namhyung Kima8bb5592013-01-22 18:09:31 +0900946 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
947
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200948 if (file->is_pipe) {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900949 err = perf_header__write_pipe(fd);
Tom Zanussi529870e2010-04-01 23:59:16 -0500950 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900951 goto out_child;
Jiri Olsa563aecb2013-06-05 13:35:06 +0200952 } else {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900953 err = perf_session__write_header(session, rec->evlist, fd, false);
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200954 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900955 goto out_child;
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200956 }
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +0200957
David Ahernd3665492012-02-06 15:27:52 -0700958 if (!rec->no_buildid
Robert Richtere20960c2011-12-07 10:02:55 +0100959 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
David Ahernd3665492012-02-06 15:27:52 -0700960 pr_err("Couldn't generate buildids. "
Robert Richtere20960c2011-12-07 10:02:55 +0100961 "Use --no-buildid to profile anyway.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600962 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900963 goto out_child;
Robert Richtere20960c2011-12-07 10:02:55 +0100964 }
965
Arnaldo Carvalho de Melo34ba5122012-12-19 09:04:24 -0300966 machine = &session->machines.host;
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200967
Wang Nan4ea648a2016-07-14 08:34:47 +0000968 err = record__synthesize(rec, false);
Wang Nanc45c86e2016-02-26 09:32:07 +0000969 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900970 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600971
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200972 if (rec->realtime_prio) {
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200973 struct sched_param param;
974
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200975 param.sched_priority = rec->realtime_prio;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200976 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
Arnaldo Carvalho de Melo6beba7a2009-10-21 17:34:06 -0200977 pr_err("Could not set realtime priority.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600978 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900979 goto out_child;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200980 }
981 }
982
Jiri Olsa774cb492012-11-12 18:34:01 +0100983 /*
984 * When perf is starting the traced process, all the events
985 * (apart from group members) have enable_on_exec=1 set,
986 * so don't spoil it by prematurely enabling them.
987 */
Andi Kleen6619a532014-01-11 13:38:27 -0800988 if (!target__none(&opts->target) && !opts->initial_delay)
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300989 perf_evlist__enable(rec->evlist);
David Ahern764e16a32011-08-25 10:17:55 -0600990
Peter Zijlstra856e9662009-12-16 17:55:55 +0100991 /*
992 * Let the child rip
993 */
Namhyung Kime803cf92015-09-22 09:24:55 +0900994 if (forks) {
Namhyung Kime5bed562015-09-30 10:45:24 +0900995 union perf_event *event;
Hari Bathinie907caf2017-03-08 02:11:51 +0530996 pid_t tgid;
Namhyung Kime5bed562015-09-30 10:45:24 +0900997
998 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
999 if (event == NULL) {
1000 err = -ENOMEM;
1001 goto out_child;
1002 }
1003
Namhyung Kime803cf92015-09-22 09:24:55 +09001004 /*
1005 * Some H/W events are generated before COMM event
1006 * which is emitted during exec(), so perf script
1007 * cannot see a correct process name for those events.
1008 * Synthesize COMM event to prevent it.
1009 */
Hari Bathinie907caf2017-03-08 02:11:51 +05301010 tgid = perf_event__synthesize_comm(tool, event,
1011 rec->evlist->workload.pid,
1012 process_synthesized_event,
1013 machine);
1014 free(event);
1015
1016 if (tgid == -1)
1017 goto out_child;
1018
1019 event = malloc(sizeof(event->namespaces) +
1020 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
1021 machine->id_hdr_size);
1022 if (event == NULL) {
1023 err = -ENOMEM;
1024 goto out_child;
1025 }
1026
1027 /*
1028 * Synthesize NAMESPACES event for the command specified.
1029 */
1030 perf_event__synthesize_namespaces(tool, event,
1031 rec->evlist->workload.pid,
1032 tgid, process_synthesized_event,
1033 machine);
Namhyung Kime5bed562015-09-30 10:45:24 +09001034 free(event);
Namhyung Kime803cf92015-09-22 09:24:55 +09001035
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001036 perf_evlist__start_workload(rec->evlist);
Namhyung Kime803cf92015-09-22 09:24:55 +09001037 }
Peter Zijlstra856e9662009-12-16 17:55:55 +01001038
Andi Kleen6619a532014-01-11 13:38:27 -08001039 if (opts->initial_delay) {
Arnaldo Carvalho de Melo0693e682016-08-08 15:05:46 -03001040 usleep(opts->initial_delay * USEC_PER_MSEC);
Andi Kleen6619a532014-01-11 13:38:27 -08001041 perf_evlist__enable(rec->evlist);
1042 }
1043
Wang Nan5f9cf592016-04-20 18:59:49 +00001044 trigger_ready(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001045 trigger_ready(&switch_output_trigger);
Wang Nana0748652016-11-26 07:03:28 +00001046 perf_hooks__invoke_record_start();
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001047 for (;;) {
Yang Shi9f065192015-09-29 14:49:43 -07001048 unsigned long long hits = rec->samples;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001049
Wang Nan057374642016-07-14 08:34:43 +00001050 /*
1051 * rec->evlist->bkw_mmap_state is possible to be
1052 * BKW_MMAP_EMPTY here: when done == true and
1053 * hits != rec->samples in previous round.
1054 *
1055 * perf_evlist__toggle_bkw_mmap ensure we never
1056 * convert BKW_MMAP_EMPTY to BKW_MMAP_DATA_PENDING.
1057 */
1058 if (trigger_is_hit(&switch_output_trigger) || done || draining)
1059 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_DATA_PENDING);
1060
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001061 if (record__mmap_read_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +00001062 trigger_error(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001063 trigger_error(&switch_output_trigger);
David Ahern8d3eca22012-08-26 12:24:47 -06001064 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001065 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -06001066 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001067
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001068 if (auxtrace_record__snapshot_started) {
1069 auxtrace_record__snapshot_started = 0;
Wang Nan5f9cf592016-04-20 18:59:49 +00001070 if (!trigger_is_error(&auxtrace_snapshot_trigger))
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001071 record__read_auxtrace_snapshot(rec);
Wang Nan5f9cf592016-04-20 18:59:49 +00001072 if (trigger_is_error(&auxtrace_snapshot_trigger)) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001073 pr_err("AUX area tracing snapshot failed\n");
1074 err = -1;
1075 goto out_child;
1076 }
1077 }
1078
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001079 if (trigger_is_hit(&switch_output_trigger)) {
Wang Nan057374642016-07-14 08:34:43 +00001080 /*
1081 * If switch_output_trigger is hit, the data in
1082 * overwritable ring buffer should have been collected,
1083 * so bkw_mmap_state should be set to BKW_MMAP_EMPTY.
1084 *
1085 * If SIGUSR2 raise after or during record__mmap_read_all(),
1086 * record__mmap_read_all() didn't collect data from
1087 * overwritable ring buffer. Read again.
1088 */
1089 if (rec->evlist->bkw_mmap_state == BKW_MMAP_RUNNING)
1090 continue;
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001091 trigger_ready(&switch_output_trigger);
1092
Wang Nan057374642016-07-14 08:34:43 +00001093 /*
1094 * Reenable events in overwrite ring buffer after
1095 * record__mmap_read_all(): we should have collected
1096 * data from it.
1097 */
1098 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_RUNNING);
1099
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001100 if (!quiet)
1101 fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
1102 waking);
1103 waking = 0;
1104 fd = record__switch_output(rec, false);
1105 if (fd < 0) {
1106 pr_err("Failed to switch to new file\n");
1107 trigger_error(&switch_output_trigger);
1108 err = fd;
1109 goto out_child;
1110 }
Jiri Olsabfacbe32017-01-09 10:52:00 +01001111
1112 /* re-arm the alarm */
1113 if (rec->switch_output.time)
1114 alarm(rec->switch_output.time);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001115 }
1116
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001117 if (hits == rec->samples) {
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001118 if (done || draining)
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001119 break;
Arnaldo Carvalho de Melof66a8892014-08-18 17:25:59 -03001120 err = perf_evlist__poll(rec->evlist, -1);
Jiri Olsaa5151142014-06-02 13:44:23 -04001121 /*
1122 * Propagate error, only if there's any. Ignore positive
1123 * number of returned events and interrupt error.
1124 */
1125 if (err > 0 || (err < 0 && errno == EINTR))
Namhyung Kim45604712014-05-12 09:47:24 +09001126 err = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001127 waking++;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001128
1129 if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
1130 draining = true;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001131 }
1132
Jiri Olsa774cb492012-11-12 18:34:01 +01001133 /*
1134 * When perf is starting the traced process, at the end events
1135 * die with the process and we wait for that. Thus no need to
1136 * disable events in this case.
1137 */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001138 if (done && !disabled && !target__none(&opts->target)) {
Wang Nan5f9cf592016-04-20 18:59:49 +00001139 trigger_off(&auxtrace_snapshot_trigger);
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001140 perf_evlist__disable(rec->evlist);
Jiri Olsa27119262012-11-12 18:34:02 +01001141 disabled = true;
1142 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001143 }
Wang Nan5f9cf592016-04-20 18:59:49 +00001144 trigger_off(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001145 trigger_off(&switch_output_trigger);
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001146
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001147 if (forks && workload_exec_errno) {
Masami Hiramatsu35550da2014-08-14 02:22:43 +00001148 char msg[STRERR_BUFSIZE];
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -03001149 const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001150 pr_err("Workload failed: %s\n", emsg);
1151 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001152 goto out_child;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001153 }
1154
Namhyung Kime3d59112015-01-29 17:06:44 +09001155 if (!quiet)
Namhyung Kim45604712014-05-12 09:47:24 +09001156 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001157
Wang Nan4ea648a2016-07-14 08:34:47 +00001158 if (target__none(&rec->opts.target))
1159 record__synthesize_workload(rec, true);
1160
Namhyung Kim45604712014-05-12 09:47:24 +09001161out_child:
1162 if (forks) {
1163 int exit_status;
Ingo Molnaraddc2782009-06-02 23:43:11 +02001164
Namhyung Kim45604712014-05-12 09:47:24 +09001165 if (!child_finished)
1166 kill(rec->evlist->workload.pid, SIGTERM);
1167
1168 wait(&exit_status);
1169
1170 if (err < 0)
1171 status = err;
1172 else if (WIFEXITED(exit_status))
1173 status = WEXITSTATUS(exit_status);
1174 else if (WIFSIGNALED(exit_status))
1175 signr = WTERMSIG(exit_status);
1176 } else
1177 status = err;
1178
Wang Nan4ea648a2016-07-14 08:34:47 +00001179 record__synthesize(rec, true);
Namhyung Kime3d59112015-01-29 17:06:44 +09001180 /* this will be recalculated during process_buildids() */
1181 rec->samples = 0;
1182
Wang Nanecfd7a92016-04-13 08:21:07 +00001183 if (!err) {
1184 if (!rec->timestamp_filename) {
1185 record__finish_output(rec);
1186 } else {
1187 fd = record__switch_output(rec, true);
1188 if (fd < 0) {
1189 status = fd;
1190 goto out_delete_session;
1191 }
1192 }
1193 }
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001194
Wang Nana0748652016-11-26 07:03:28 +00001195 perf_hooks__invoke_record_end();
1196
Namhyung Kime3d59112015-01-29 17:06:44 +09001197 if (!err && !quiet) {
1198 char samples[128];
Wang Nanecfd7a92016-04-13 08:21:07 +00001199 const char *postfix = rec->timestamp_filename ?
1200 ".<timestamp>" : "";
Namhyung Kime3d59112015-01-29 17:06:44 +09001201
Adrian Hunteref149c22015-04-09 18:53:45 +03001202 if (rec->samples && !rec->opts.full_auxtrace)
Namhyung Kime3d59112015-01-29 17:06:44 +09001203 scnprintf(samples, sizeof(samples),
1204 " (%" PRIu64 " samples)", rec->samples);
1205 else
1206 samples[0] = '\0';
1207
Wang Nanecfd7a92016-04-13 08:21:07 +00001208 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
Namhyung Kime3d59112015-01-29 17:06:44 +09001209 perf_data_file__size(file) / 1024.0 / 1024.0,
Wang Nanecfd7a92016-04-13 08:21:07 +00001210 file->path, postfix, samples);
Namhyung Kime3d59112015-01-29 17:06:44 +09001211 }
1212
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001213out_delete_session:
1214 perf_session__delete(session);
Namhyung Kim45604712014-05-12 09:47:24 +09001215 return status;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001216}
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001217
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001218static void callchain_debug(struct callchain_param *callchain)
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001219{
Kan Liangaad2b212015-01-05 13:23:04 -05001220 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
Jiri Olsaa601fdf2014-02-03 12:44:43 +01001221
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001222 pr_debug("callchain: type %s\n", str[callchain->record_mode]);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001223
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001224 if (callchain->record_mode == CALLCHAIN_DWARF)
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001225 pr_debug("callchain: stack dump size %d\n",
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001226 callchain->dump_size);
1227}
1228
1229int record_opts__parse_callchain(struct record_opts *record,
1230 struct callchain_param *callchain,
1231 const char *arg, bool unset)
1232{
1233 int ret;
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001234 callchain->enabled = !unset;
1235
1236 /* --no-call-graph */
1237 if (unset) {
1238 callchain->record_mode = CALLCHAIN_NONE;
1239 pr_debug("callchain: disabled\n");
1240 return 0;
1241 }
1242
1243 ret = parse_callchain_record_opt(arg, callchain);
1244 if (!ret) {
1245 /* Enable data address sampling for DWARF unwind. */
1246 if (callchain->record_mode == CALLCHAIN_DWARF)
1247 record->sample_address = true;
1248 callchain_debug(callchain);
1249 }
1250
1251 return ret;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001252}
1253
Kan Liangc421e802015-07-29 05:42:12 -04001254int record_parse_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001255 const char *arg,
1256 int unset)
1257{
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001258 return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
Jiri Olsa26d33022012-08-07 15:20:47 +02001259}
1260
Kan Liangc421e802015-07-29 05:42:12 -04001261int record_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001262 const char *arg __maybe_unused,
1263 int unset __maybe_unused)
1264{
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001265 struct callchain_param *callchain = opt->value;
Kan Liangc421e802015-07-29 05:42:12 -04001266
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001267 callchain->enabled = true;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001268
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001269 if (callchain->record_mode == CALLCHAIN_NONE)
1270 callchain->record_mode = CALLCHAIN_FP;
Jiri Olsaeb853e82014-02-03 12:44:42 +01001271
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001272 callchain_debug(callchain);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001273 return 0;
1274}
1275
Jiri Olsaeb853e82014-02-03 12:44:42 +01001276static int perf_record_config(const char *var, const char *value, void *cb)
1277{
Namhyung Kim7a29c082015-12-15 10:49:56 +09001278 struct record *rec = cb;
1279
1280 if (!strcmp(var, "record.build-id")) {
1281 if (!strcmp(value, "cache"))
1282 rec->no_buildid_cache = false;
1283 else if (!strcmp(value, "no-cache"))
1284 rec->no_buildid_cache = true;
1285 else if (!strcmp(value, "skip"))
1286 rec->no_buildid = true;
1287 else
1288 return -1;
1289 return 0;
1290 }
Jiri Olsaeb853e82014-02-03 12:44:42 +01001291 if (!strcmp(var, "record.call-graph"))
Namhyung Kim5a2e5e82014-09-23 10:01:44 +09001292 var = "call-graph.record-mode"; /* fall-through */
Jiri Olsaeb853e82014-02-03 12:44:42 +01001293
1294 return perf_default_config(var, value, cb);
1295}
1296
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001297struct clockid_map {
1298 const char *name;
1299 int clockid;
1300};
1301
1302#define CLOCKID_MAP(n, c) \
1303 { .name = n, .clockid = (c), }
1304
1305#define CLOCKID_END { .name = NULL, }
1306
1307
1308/*
1309 * Add the missing ones, we need to build on many distros...
1310 */
1311#ifndef CLOCK_MONOTONIC_RAW
1312#define CLOCK_MONOTONIC_RAW 4
1313#endif
1314#ifndef CLOCK_BOOTTIME
1315#define CLOCK_BOOTTIME 7
1316#endif
1317#ifndef CLOCK_TAI
1318#define CLOCK_TAI 11
1319#endif
1320
1321static const struct clockid_map clockids[] = {
1322 /* available for all events, NMI safe */
1323 CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
1324 CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
1325
1326 /* available for some events */
1327 CLOCKID_MAP("realtime", CLOCK_REALTIME),
1328 CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
1329 CLOCKID_MAP("tai", CLOCK_TAI),
1330
1331 /* available for the lazy */
1332 CLOCKID_MAP("mono", CLOCK_MONOTONIC),
1333 CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
1334 CLOCKID_MAP("real", CLOCK_REALTIME),
1335 CLOCKID_MAP("boot", CLOCK_BOOTTIME),
1336
1337 CLOCKID_END,
1338};
1339
1340static int parse_clockid(const struct option *opt, const char *str, int unset)
1341{
1342 struct record_opts *opts = (struct record_opts *)opt->value;
1343 const struct clockid_map *cm;
1344 const char *ostr = str;
1345
1346 if (unset) {
1347 opts->use_clockid = 0;
1348 return 0;
1349 }
1350
1351 /* no arg passed */
1352 if (!str)
1353 return 0;
1354
1355 /* no setting it twice */
1356 if (opts->use_clockid)
1357 return -1;
1358
1359 opts->use_clockid = true;
1360
1361 /* if its a number, we're done */
1362 if (sscanf(str, "%d", &opts->clockid) == 1)
1363 return 0;
1364
1365 /* allow a "CLOCK_" prefix to the name */
1366 if (!strncasecmp(str, "CLOCK_", 6))
1367 str += 6;
1368
1369 for (cm = clockids; cm->name; cm++) {
1370 if (!strcasecmp(str, cm->name)) {
1371 opts->clockid = cm->clockid;
1372 return 0;
1373 }
1374 }
1375
1376 opts->use_clockid = false;
1377 ui__warning("unknown clockid %s, check man page\n", ostr);
1378 return -1;
1379}
1380
Adrian Huntere9db1312015-04-09 18:53:46 +03001381static int record__parse_mmap_pages(const struct option *opt,
1382 const char *str,
1383 int unset __maybe_unused)
1384{
1385 struct record_opts *opts = opt->value;
1386 char *s, *p;
1387 unsigned int mmap_pages;
1388 int ret;
1389
1390 if (!str)
1391 return -EINVAL;
1392
1393 s = strdup(str);
1394 if (!s)
1395 return -ENOMEM;
1396
1397 p = strchr(s, ',');
1398 if (p)
1399 *p = '\0';
1400
1401 if (*s) {
1402 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
1403 if (ret)
1404 goto out_free;
1405 opts->mmap_pages = mmap_pages;
1406 }
1407
1408 if (!p) {
1409 ret = 0;
1410 goto out_free;
1411 }
1412
1413 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
1414 if (ret)
1415 goto out_free;
1416
1417 opts->auxtrace_mmap_pages = mmap_pages;
1418
1419out_free:
1420 free(s);
1421 return ret;
1422}
1423
Jiri Olsa0c582442017-01-09 10:51:59 +01001424static void switch_output_size_warn(struct record *rec)
1425{
1426 u64 wakeup_size = perf_evlist__mmap_size(rec->opts.mmap_pages);
1427 struct switch_output *s = &rec->switch_output;
1428
1429 wakeup_size /= 2;
1430
1431 if (s->size < wakeup_size) {
1432 char buf[100];
1433
1434 unit_number__scnprintf(buf, sizeof(buf), wakeup_size);
1435 pr_warning("WARNING: switch-output data size lower than "
1436 "wakeup kernel buffer size (%s) "
1437 "expect bigger perf.data sizes\n", buf);
1438 }
1439}
1440
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001441static int switch_output_setup(struct record *rec)
1442{
1443 struct switch_output *s = &rec->switch_output;
Jiri Olsadc0c6122017-01-09 10:51:58 +01001444 static struct parse_tag tags_size[] = {
1445 { .tag = 'B', .mult = 1 },
1446 { .tag = 'K', .mult = 1 << 10 },
1447 { .tag = 'M', .mult = 1 << 20 },
1448 { .tag = 'G', .mult = 1 << 30 },
1449 { .tag = 0 },
1450 };
Jiri Olsabfacbe32017-01-09 10:52:00 +01001451 static struct parse_tag tags_time[] = {
1452 { .tag = 's', .mult = 1 },
1453 { .tag = 'm', .mult = 60 },
1454 { .tag = 'h', .mult = 60*60 },
1455 { .tag = 'd', .mult = 60*60*24 },
1456 { .tag = 0 },
1457 };
Jiri Olsadc0c6122017-01-09 10:51:58 +01001458 unsigned long val;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001459
1460 if (!s->set)
1461 return 0;
1462
1463 if (!strcmp(s->str, "signal")) {
1464 s->signal = true;
1465 pr_debug("switch-output with SIGUSR2 signal\n");
Jiri Olsadc0c6122017-01-09 10:51:58 +01001466 goto enabled;
1467 }
1468
1469 val = parse_tag_value(s->str, tags_size);
1470 if (val != (unsigned long) -1) {
1471 s->size = val;
1472 pr_debug("switch-output with %s size threshold\n", s->str);
1473 goto enabled;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001474 }
1475
Jiri Olsabfacbe32017-01-09 10:52:00 +01001476 val = parse_tag_value(s->str, tags_time);
1477 if (val != (unsigned long) -1) {
1478 s->time = val;
1479 pr_debug("switch-output with %s time threshold (%lu seconds)\n",
1480 s->str, s->time);
1481 goto enabled;
1482 }
1483
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001484 return -1;
Jiri Olsadc0c6122017-01-09 10:51:58 +01001485
1486enabled:
1487 rec->timestamp_filename = true;
1488 s->enabled = true;
Jiri Olsa0c582442017-01-09 10:51:59 +01001489
1490 if (s->size && !rec->opts.no_buffering)
1491 switch_output_size_warn(rec);
1492
Jiri Olsadc0c6122017-01-09 10:51:58 +01001493 return 0;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001494}
1495
Namhyung Kime5b2c202014-10-23 00:15:46 +09001496static const char * const __record_usage[] = {
Mike Galbraith9e0967532009-05-28 16:25:34 +02001497 "perf record [<options>] [<command>]",
1498 "perf record [<options>] -- <command> [<options>]",
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001499 NULL
1500};
Namhyung Kime5b2c202014-10-23 00:15:46 +09001501const char * const *record_usage = __record_usage;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001502
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001503/*
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001504 * XXX Ideally would be local to cmd_record() and passed to a record__new
1505 * because we need to have access to it in record__exit, that is called
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001506 * after cmd_record() exits, but since record_options need to be accessible to
1507 * builtin-script, leave it here.
1508 *
1509 * At least we don't ouch it in all the other functions here directly.
1510 *
1511 * Just say no to tons of global variables, sigh.
1512 */
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001513static struct record record = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001514 .opts = {
Andi Kleen8affc2b2014-07-31 14:45:04 +08001515 .sample_time = true,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001516 .mmap_pages = UINT_MAX,
1517 .user_freq = UINT_MAX,
1518 .user_interval = ULLONG_MAX,
Arnaldo Carvalho de Melo447a6012012-05-22 13:14:18 -03001519 .freq = 4000,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001520 .target = {
1521 .uses_mmap = true,
Adrian Hunter3aa59392013-11-15 15:52:29 +02001522 .default_per_cpu = true,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001523 },
Kan Liang9d9cad72015-06-17 09:51:11 -04001524 .proc_map_timeout = 500,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001525 },
Namhyung Kime3d59112015-01-29 17:06:44 +09001526 .tool = {
1527 .sample = process_sample_event,
1528 .fork = perf_event__process_fork,
Adrian Huntercca84822015-08-19 17:29:21 +03001529 .exit = perf_event__process_exit,
Namhyung Kime3d59112015-01-29 17:06:44 +09001530 .comm = perf_event__process_comm,
Hari Bathinif3b36142017-03-08 02:11:43 +05301531 .namespaces = perf_event__process_namespaces,
Namhyung Kime3d59112015-01-29 17:06:44 +09001532 .mmap = perf_event__process_mmap,
1533 .mmap2 = perf_event__process_mmap2,
Adrian Huntercca84822015-08-19 17:29:21 +03001534 .ordered_events = true,
Namhyung Kime3d59112015-01-29 17:06:44 +09001535 },
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001536};
Frederic Weisbecker7865e812010-04-14 19:42:07 +02001537
Namhyung Kim76a26542015-10-22 23:28:32 +09001538const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1539 "\n\t\t\t\tDefault: fp";
Arnaldo Carvalho de Melo61eaa3b2012-10-01 15:20:58 -03001540
Wang Nan0aab2132016-06-16 08:02:41 +00001541static bool dry_run;
1542
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001543/*
1544 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
1545 * with it and switch to use the library functions in perf_evlist that came
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001546 * from builtin-record.c, i.e. use record_opts,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001547 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
1548 * using pipes, etc.
1549 */
Jiri Olsaefd21302017-01-03 09:19:55 +01001550static struct option __record_options[] = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001551 OPT_CALLBACK('e', "event", &record.evlist, "event",
Thomas Gleixner86847b62009-06-06 12:24:17 +02001552 "event selector. use 'perf list' to list available events",
Jiri Olsaf120f9d2011-07-14 11:25:32 +02001553 parse_events_option),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001554 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
Li Zefanc171b552009-10-15 11:22:07 +08001555 "event filter", parse_filter),
Wang Nan4ba1faa2015-07-10 07:36:10 +00001556 OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
1557 NULL, "don't record events from perf itself",
1558 exclude_perf),
Namhyung Kimbea03402012-04-26 14:15:15 +09001559 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001560 "record events on existing process id"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001561 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001562 "record events on existing thread id"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001563 OPT_INTEGER('r', "realtime", &record.realtime_prio,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001564 "collect data with this RT SCHED_FIFO priority"),
Arnaldo Carvalho de Melo509051e2014-01-14 17:52:14 -03001565 OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
Kirill Smelkovacac03f2011-01-12 17:59:36 +03001566 "collect data without buffering"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001567 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
Frederic Weisbeckerdaac07b2009-08-13 10:27:19 +02001568 "collect raw sample records from all opened counters"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001569 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001570 "system-wide collection from all CPUs"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001571 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
Stephane Eranianc45c6ea2010-05-28 12:00:01 +02001572 "list of cpus to monitor"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001573 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
Jiri Olsaf5fc1412013-10-15 16:27:32 +02001574 OPT_STRING('o', "output", &record.file.path, "file",
Ingo Molnarabaff322009-06-02 22:59:57 +02001575 "output file name"),
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001576 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1577 &record.opts.no_inherit_set,
1578 "child tasks do not inherit counters"),
Wang Nan4ea648a2016-07-14 08:34:47 +00001579 OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize,
1580 "synthesize non-sample events at the end of output"),
Wang Nan626a6b72016-07-14 08:34:45 +00001581 OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001582 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
Adrian Huntere9db1312015-04-09 18:53:46 +03001583 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
1584 "number of mmap data pages and AUX area tracing mmap pages",
1585 record__parse_mmap_pages),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001586 OPT_BOOLEAN(0, "group", &record.opts.group,
Lin Ming43bece72011-08-17 18:42:07 +08001587 "put the counters into a counter group"),
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001588 OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001589 NULL, "enables call-graph recording" ,
1590 &record_callchain_opt),
1591 OPT_CALLBACK(0, "call-graph", &record.opts,
Namhyung Kim76a26542015-10-22 23:28:32 +09001592 "record_mode[,record_size]", record_callchain_help,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001593 &record_parse_callchain_opt),
Ian Munsiec0555642010-04-13 18:37:33 +10001594 OPT_INCR('v', "verbose", &verbose,
Ingo Molnar3da297a2009-06-07 17:39:02 +02001595 "be more verbose (show counter open errors, etc)"),
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001596 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001597 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001598 "per thread counts"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001599 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
Jiri Olsab6f35ed2016-08-01 20:02:35 +02001600 OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"),
Adrian Hunter3abebc52015-07-06 14:51:01 +03001601 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
1602 &record.opts.sample_time_set,
1603 "Record the sample timestamps"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001604 OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001605 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001606 "don't sample"),
Wang Nand2db9a92016-01-25 09:56:19 +00001607 OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
1608 &record.no_buildid_cache_set,
1609 "do not update the buildid cache"),
1610 OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
1611 &record.no_buildid_set,
1612 "do not collect buildids in perf.data"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001613 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
Stephane Eranian023695d2011-02-14 11:20:01 +02001614 "monitor event in cgroup name only",
1615 parse_cgroups),
Arnaldo Carvalho de Meloa6205a32014-01-14 17:58:12 -03001616 OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
Andi Kleen6619a532014-01-11 13:38:27 -08001617 "ms to wait before starting measurement after program start"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001618 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
1619 "user to profile"),
Stephane Eraniana5aabda2012-03-08 23:47:45 +01001620
1621 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
1622 "branch any", "sample any taken branches",
1623 parse_branch_stack),
1624
1625 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
1626 "branch filter mask", "branch stack filter modes",
Roberto Agostino Vitillobdfebd82012-02-09 23:21:02 +01001627 parse_branch_stack),
Andi Kleen05484292013-01-24 16:10:29 +01001628 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
1629 "sample by weight (on special events only)"),
Andi Kleen475eeab2013-09-20 07:40:43 -07001630 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
1631 "sample transaction flags (special events only)"),
Adrian Hunter3aa59392013-11-15 15:52:29 +02001632 OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
1633 "use per-thread mmaps"),
Stephane Eranianbcc84ec2015-08-31 18:41:12 +02001634 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
1635 "sample selected machine registers on interrupt,"
1636 " use -I ? to list register names", parse_regs),
Andi Kleen85c273d2015-02-24 15:13:40 -08001637 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
1638 "Record running/enabled time of read (:S) events"),
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001639 OPT_CALLBACK('k', "clockid", &record.opts,
1640 "clockid", "clockid to use for events, see clock_gettime()",
1641 parse_clockid),
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001642 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
1643 "opts", "AUX area tracing Snapshot Mode", ""),
Kan Liang9d9cad72015-06-17 09:51:11 -04001644 OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
1645 "per thread proc mmap processing timeout in ms"),
Hari Bathinif3b36142017-03-08 02:11:43 +05301646 OPT_BOOLEAN(0, "namespaces", &record.opts.record_namespaces,
1647 "Record namespaces events"),
Adrian Hunterb757bb02015-07-21 12:44:04 +03001648 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1649 "Record context switch events"),
Jiri Olsa85723882016-02-15 09:34:31 +01001650 OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
1651 "Configure all used events to run in kernel space.",
1652 PARSE_OPT_EXCLUSIVE),
1653 OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
1654 "Configure all used events to run in user space.",
1655 PARSE_OPT_EXCLUSIVE),
Wang Nan71dc23262015-10-14 12:41:19 +00001656 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1657 "clang binary to use for compiling BPF scriptlets"),
1658 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1659 "options passed to clang when compiling BPF scriptlets"),
He Kuang7efe0e02015-12-14 10:39:23 +00001660 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1661 "file", "vmlinux pathname"),
Namhyung Kim61566812016-01-11 22:37:09 +09001662 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
1663 "Record build-id of all DSOs regardless of hits"),
Wang Nanecfd7a92016-04-13 08:21:07 +00001664 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1665 "append timestamp to output filename"),
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001666 OPT_STRING_OPTARG_SET(0, "switch-output", &record.switch_output.str,
Jiri Olsabfacbe32017-01-09 10:52:00 +01001667 &record.switch_output.set, "signal,size,time",
1668 "Switch output when receive SIGUSR2 or cross size,time threshold",
Jiri Olsadc0c6122017-01-09 10:51:58 +01001669 "signal"),
Wang Nan0aab2132016-06-16 08:02:41 +00001670 OPT_BOOLEAN(0, "dry-run", &dry_run,
1671 "Parse options then exit"),
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001672 OPT_END()
1673};
1674
Namhyung Kime5b2c202014-10-23 00:15:46 +09001675struct option *record_options = __record_options;
1676
Arnaldo Carvalho de Melob0ad8ea2017-03-27 11:47:20 -03001677int cmd_record(int argc, const char **argv)
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001678{
Adrian Hunteref149c22015-04-09 18:53:45 +03001679 int err;
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001680 struct record *rec = &record;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001681 char errbuf[BUFSIZ];
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001682
Wang Nan48e1cab2015-12-14 10:39:22 +00001683#ifndef HAVE_LIBBPF_SUPPORT
1684# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
1685 set_nobuild('\0', "clang-path", true);
1686 set_nobuild('\0', "clang-opt", true);
1687# undef set_nobuild
1688#endif
1689
He Kuang7efe0e02015-12-14 10:39:23 +00001690#ifndef HAVE_BPF_PROLOGUE
1691# if !defined (HAVE_DWARF_SUPPORT)
1692# define REASON "NO_DWARF=1"
1693# elif !defined (HAVE_LIBBPF_SUPPORT)
1694# define REASON "NO_LIBBPF=1"
1695# else
1696# define REASON "this architecture doesn't support BPF prologue"
1697# endif
1698# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
1699 set_nobuild('\0', "vmlinux", true);
1700# undef set_nobuild
1701# undef REASON
1702#endif
1703
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001704 rec->evlist = perf_evlist__new();
1705 if (rec->evlist == NULL)
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -02001706 return -ENOMEM;
1707
Arnaldo Carvalho de Meloecc4c562017-01-24 13:44:10 -03001708 err = perf_config(perf_record_config, rec);
1709 if (err)
1710 return err;
Jiri Olsaeb853e82014-02-03 12:44:42 +01001711
Tom Zanussibca647a2010-11-10 08:11:30 -06001712 argc = parse_options(argc, argv, record_options, record_usage,
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001713 PARSE_OPT_STOP_AT_NON_OPTION);
Namhyung Kim68ba3232017-02-17 17:17:42 +09001714 if (quiet)
1715 perf_quiet_option();
Jiri Olsa483635a2017-02-17 18:00:18 +01001716
1717 /* Make system wide (-a) the default target. */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001718 if (!argc && target__none(&rec->opts.target))
Jiri Olsa483635a2017-02-17 18:00:18 +01001719 rec->opts.target.system_wide = true;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001720
Namhyung Kimbea03402012-04-26 14:15:15 +09001721 if (nr_cgroups && !rec->opts.target.system_wide) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001722 usage_with_options_msg(record_usage, record_options,
1723 "cgroup monitoring only available in system-wide mode");
1724
Stephane Eranian023695d2011-02-14 11:20:01 +02001725 }
Adrian Hunterb757bb02015-07-21 12:44:04 +03001726 if (rec->opts.record_switch_events &&
1727 !perf_can_record_switch_events()) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001728 ui__error("kernel does not support recording context switch events\n");
1729 parse_options_usage(record_usage, record_options, "switch-events", 0);
1730 return -EINVAL;
Adrian Hunterb757bb02015-07-21 12:44:04 +03001731 }
Stephane Eranian023695d2011-02-14 11:20:01 +02001732
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001733 if (switch_output_setup(rec)) {
1734 parse_options_usage(record_usage, record_options, "switch-output", 0);
1735 return -EINVAL;
1736 }
1737
Jiri Olsabfacbe32017-01-09 10:52:00 +01001738 if (rec->switch_output.time) {
1739 signal(SIGALRM, alarm_sig_handler);
1740 alarm(rec->switch_output.time);
1741 }
1742
Adrian Hunteref149c22015-04-09 18:53:45 +03001743 if (!rec->itr) {
1744 rec->itr = auxtrace_record__init(rec->evlist, &err);
1745 if (err)
Adrian Hunter5c01ad62016-09-23 17:38:37 +03001746 goto out;
Adrian Hunteref149c22015-04-09 18:53:45 +03001747 }
1748
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001749 err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
1750 rec->opts.auxtrace_snapshot_opts);
1751 if (err)
Adrian Hunter5c01ad62016-09-23 17:38:37 +03001752 goto out;
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001753
Adrian Hunter1b36c032016-09-23 17:38:39 +03001754 /*
1755 * Allow aliases to facilitate the lookup of symbols for address
1756 * filters. Refer to auxtrace_parse_filters().
1757 */
1758 symbol_conf.allow_aliases = true;
1759
1760 symbol__init(NULL);
1761
1762 err = auxtrace_parse_filters(rec->evlist);
1763 if (err)
1764 goto out;
1765
Wang Nan0aab2132016-06-16 08:02:41 +00001766 if (dry_run)
Adrian Hunter5c01ad62016-09-23 17:38:37 +03001767 goto out;
Wang Nan0aab2132016-06-16 08:02:41 +00001768
Wang Nand7888572016-04-08 15:07:24 +00001769 err = bpf__setup_stdout(rec->evlist);
1770 if (err) {
1771 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
1772 pr_err("ERROR: Setup BPF stdout failed: %s\n",
1773 errbuf);
Adrian Hunter5c01ad62016-09-23 17:38:37 +03001774 goto out;
Wang Nand7888572016-04-08 15:07:24 +00001775 }
1776
Adrian Hunteref149c22015-04-09 18:53:45 +03001777 err = -ENOMEM;
1778
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001779 if (symbol_conf.kptr_restrict)
Arnaldo Carvalho de Melo646aaea62011-05-27 11:00:41 -03001780 pr_warning(
1781"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
1782"check /proc/sys/kernel/kptr_restrict.\n\n"
1783"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
1784"file is not found in the buildid cache or in the vmlinux path.\n\n"
1785"Samples in kernel modules won't be resolved at all.\n\n"
1786"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
1787"even with a suitable vmlinux or kallsyms file.\n\n");
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001788
Wang Nan0c1d46a2016-04-20 18:59:52 +00001789 if (rec->no_buildid_cache || rec->no_buildid) {
Stephane Eraniana1ac1d32010-06-17 11:39:01 +02001790 disable_buildid_cache();
Jiri Olsadc0c6122017-01-09 10:51:58 +01001791 } else if (rec->switch_output.enabled) {
Wang Nan0c1d46a2016-04-20 18:59:52 +00001792 /*
1793 * In 'perf record --switch-output', disable buildid
1794 * generation by default to reduce data file switching
1795 * overhead. Still generate buildid if they are required
1796 * explicitly using
1797 *
Jiri Olsa60437ac2017-01-03 09:19:56 +01001798 * perf record --switch-output --no-no-buildid \
Wang Nan0c1d46a2016-04-20 18:59:52 +00001799 * --no-no-buildid-cache
1800 *
1801 * Following code equals to:
1802 *
1803 * if ((rec->no_buildid || !rec->no_buildid_set) &&
1804 * (rec->no_buildid_cache || !rec->no_buildid_cache_set))
1805 * disable_buildid_cache();
1806 */
1807 bool disable = true;
1808
1809 if (rec->no_buildid_set && !rec->no_buildid)
1810 disable = false;
1811 if (rec->no_buildid_cache_set && !rec->no_buildid_cache)
1812 disable = false;
1813 if (disable) {
1814 rec->no_buildid = true;
1815 rec->no_buildid_cache = true;
1816 disable_buildid_cache();
1817 }
1818 }
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001819
Wang Nan4ea648a2016-07-14 08:34:47 +00001820 if (record.opts.overwrite)
1821 record.opts.tail_synthesize = true;
1822
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001823 if (rec->evlist->nr_entries == 0 &&
1824 perf_evlist__add_default(rec->evlist) < 0) {
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001825 pr_err("Not enough memory for event selector list\n");
Adrian Hunter394c01e2016-09-23 17:38:36 +03001826 goto out;
Peter Zijlstrabbd36e52009-06-11 23:11:50 +02001827 }
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001828
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001829 if (rec->opts.target.tid && !rec->opts.no_inherit_set)
1830 rec->opts.no_inherit = true;
1831
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001832 err = target__validate(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001833 if (err) {
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001834 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001835 ui__warning("%s", errbuf);
1836 }
Namhyung Kim4bd0f2d2012-04-26 14:15:18 +09001837
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001838 err = target__parse_uid(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001839 if (err) {
1840 int saved_errno = errno;
1841
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001842 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim3780f482012-05-29 13:22:57 +09001843 ui__error("%s", errbuf);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001844
1845 err = -saved_errno;
Adrian Hunter394c01e2016-09-23 17:38:36 +03001846 goto out;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001847 }
Arnaldo Carvalho de Melo0d37aa32012-01-19 14:08:15 -02001848
Jiri Olsa23dc4f12016-12-12 11:35:43 +01001849 /* Enable ignoring missing threads when -u option is defined. */
1850 rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX;
1851
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001852 err = -ENOMEM;
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001853 if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -02001854 usage_with_options(record_usage, record_options);
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001855
Adrian Hunteref149c22015-04-09 18:53:45 +03001856 err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
1857 if (err)
Adrian Hunter394c01e2016-09-23 17:38:36 +03001858 goto out;
Adrian Hunteref149c22015-04-09 18:53:45 +03001859
Namhyung Kim61566812016-01-11 22:37:09 +09001860 /*
1861 * We take all buildids when the file contains
1862 * AUX area tracing data because we do not decode the
1863 * trace because it would take too long.
1864 */
1865 if (rec->opts.full_auxtrace)
1866 rec->buildid_all = true;
1867
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001868 if (record_opts__config(&rec->opts)) {
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001869 err = -EINVAL;
Adrian Hunter394c01e2016-09-23 17:38:36 +03001870 goto out;
Mike Galbraith7e4ff9e2009-10-12 07:56:03 +02001871 }
1872
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001873 err = __cmd_record(&record, argc, argv);
Adrian Hunter394c01e2016-09-23 17:38:36 +03001874out:
Namhyung Kim45604712014-05-12 09:47:24 +09001875 perf_evlist__delete(rec->evlist);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03001876 symbol__exit();
Adrian Hunteref149c22015-04-09 18:53:45 +03001877 auxtrace_record__free(rec->itr);
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001878 return err;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001879}
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001880
1881static void snapshot_sig_handler(int sig __maybe_unused)
1882{
Jiri Olsadc0c6122017-01-09 10:51:58 +01001883 struct record *rec = &record;
1884
Wang Nan5f9cf592016-04-20 18:59:49 +00001885 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1886 trigger_hit(&auxtrace_snapshot_trigger);
1887 auxtrace_record__snapshot_started = 1;
1888 if (auxtrace_record__snapshot_start(record.itr))
1889 trigger_error(&auxtrace_snapshot_trigger);
1890 }
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001891
Jiri Olsadc0c6122017-01-09 10:51:58 +01001892 if (switch_output_signal(rec))
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001893 trigger_hit(&switch_output_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001894}
Jiri Olsabfacbe32017-01-09 10:52:00 +01001895
1896static void alarm_sig_handler(int sig __maybe_unused)
1897{
1898 struct record *rec = &record;
1899
1900 if (switch_output_time(rec))
1901 trigger_hit(&switch_output_trigger);
1902}