blob: 65429d1b29c880dd8b8b328026f64c0ebf5c0f5d [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"
Wang Nand8871ea2016-02-26 09:32:06 +000041#include "asm/bug.h"
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +020042
Arnaldo Carvalho de Melofd20e812017-04-17 15:23:08 -030043#include <inttypes.h>
Peter Zijlstra97124d5e2009-06-02 15:52:24 +020044#include <unistd.h>
Peter Zijlstrade9ac072009-04-08 15:01:31 +020045#include <sched.h>
Arnaldo Carvalho de Meloa41794c2010-05-18 18:29:23 -030046#include <sys/mman.h>
Wang Nan2d11c652016-05-23 07:13:39 +000047#include <asm/bug.h>
Arnaldo Carvalho de Melo0693e682016-08-08 15:05:46 -030048#include <linux/time64.h>
Bernhard Rosenkraenzer78da39f2012-10-08 09:43:26 +030049
Jiri Olsa1b43b702017-01-09 10:51:56 +010050struct switch_output {
Jiri Olsadc0c6122017-01-09 10:51:58 +010051 bool enabled;
Jiri Olsa1b43b702017-01-09 10:51:56 +010052 bool signal;
Jiri Olsadc0c6122017-01-09 10:51:58 +010053 unsigned long size;
Jiri Olsabfacbe32017-01-09 10:52:00 +010054 unsigned long time;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +010055 const char *str;
56 bool set;
Jiri Olsa1b43b702017-01-09 10:51:56 +010057};
58
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -030059struct record {
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020060 struct perf_tool tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -030061 struct record_opts opts;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020062 u64 bytes_written;
Jiri Olsaf5fc14122013-10-15 16:27:32 +020063 struct perf_data_file file;
Adrian Hunteref149c22015-04-09 18:53:45 +030064 struct auxtrace_record *itr;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020065 struct perf_evlist *evlist;
66 struct perf_session *session;
67 const char *progname;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020068 int realtime_prio;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020069 bool no_buildid;
Wang Nand2db9a92016-01-25 09:56:19 +000070 bool no_buildid_set;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020071 bool no_buildid_cache;
Wang Nand2db9a92016-01-25 09:56:19 +000072 bool no_buildid_cache_set;
Namhyung Kim61566812016-01-11 22:37:09 +090073 bool buildid_all;
Wang Nanecfd7a92016-04-13 08:21:07 +000074 bool timestamp_filename;
Jiri Olsa1b43b702017-01-09 10:51:56 +010075 struct switch_output switch_output;
Yang Shi9f065192015-09-29 14:49:43 -070076 unsigned long long samples;
Arnaldo Carvalho de Melo0f82ebc2011-11-08 14:41:57 -020077};
Ingo Molnara21ca2c2009-06-06 09:58:57 +020078
Jiri Olsadc0c6122017-01-09 10:51:58 +010079static volatile int auxtrace_record__snapshot_started;
80static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
81static DEFINE_TRIGGER(switch_output_trigger);
82
83static bool switch_output_signal(struct record *rec)
84{
85 return rec->switch_output.signal &&
86 trigger_is_ready(&switch_output_trigger);
87}
88
89static bool switch_output_size(struct record *rec)
90{
91 return rec->switch_output.size &&
92 trigger_is_ready(&switch_output_trigger) &&
93 (rec->bytes_written >= rec->switch_output.size);
94}
95
Jiri Olsabfacbe32017-01-09 10:52:00 +010096static bool switch_output_time(struct record *rec)
97{
98 return rec->switch_output.time &&
99 trigger_is_ready(&switch_output_trigger);
100}
101
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300102static int record__write(struct record *rec, void *bf, size_t size)
Peter Zijlstraf5970552009-06-18 23:22:55 +0200103{
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -0300104 if (perf_data_file__write(rec->session->file, bf, size) < 0) {
Jiri Olsa50a9b862013-11-22 13:11:24 +0100105 pr_err("failed to write perf data, error: %m\n");
106 return -1;
Peter Zijlstraf5970552009-06-18 23:22:55 +0200107 }
David Ahern8d3eca22012-08-26 12:24:47 -0600108
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -0300109 rec->bytes_written += size;
Jiri Olsadc0c6122017-01-09 10:51:58 +0100110
111 if (switch_output_size(rec))
112 trigger_hit(&switch_output_trigger);
113
David Ahern8d3eca22012-08-26 12:24:47 -0600114 return 0;
Peter Zijlstraf5970552009-06-18 23:22:55 +0200115}
116
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200117static int process_synthesized_event(struct perf_tool *tool,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200118 union perf_event *event,
Irina Tirdea1d037ca2012-09-11 01:15:03 +0300119 struct perf_sample *sample __maybe_unused,
120 struct machine *machine __maybe_unused)
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -0200121{
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300122 struct record *rec = container_of(tool, struct record, tool);
123 return record__write(rec, event, event->header.size);
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -0200124}
125
Wang Nan3a62a7b2016-05-23 07:13:41 +0000126static int
127backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end)
128{
129 struct perf_event_header *pheader;
130 u64 evt_head = head;
131 int size = mask + 1;
132
133 pr_debug2("backward_rb_find_range: buf=%p, head=%"PRIx64"\n", buf, head);
134 pheader = (struct perf_event_header *)(buf + (head & mask));
135 *start = head;
136 while (true) {
137 if (evt_head - head >= (unsigned int)size) {
Colin Ian King5e30d552016-08-22 19:30:08 +0100138 pr_debug("Finished reading backward ring buffer: rewind\n");
Wang Nan3a62a7b2016-05-23 07:13:41 +0000139 if (evt_head - head > (unsigned int)size)
140 evt_head -= pheader->size;
141 *end = evt_head;
142 return 0;
143 }
144
145 pheader = (struct perf_event_header *)(buf + (evt_head & mask));
146
147 if (pheader->size == 0) {
Colin Ian King5e30d552016-08-22 19:30:08 +0100148 pr_debug("Finished reading backward ring buffer: get start\n");
Wang Nan3a62a7b2016-05-23 07:13:41 +0000149 *end = evt_head;
150 return 0;
151 }
152
153 evt_head += pheader->size;
154 pr_debug3("move evt_head: %"PRIx64"\n", evt_head);
155 }
156 WARN_ONCE(1, "Shouldn't get here\n");
157 return -1;
158}
159
160static int
Wang Nana4ea0ec2016-07-14 08:34:36 +0000161rb_find_range(void *data, int mask, u64 head, u64 old,
162 u64 *start, u64 *end, bool backward)
Wang Nan3a62a7b2016-05-23 07:13:41 +0000163{
Wang Nana4ea0ec2016-07-14 08:34:36 +0000164 if (!backward) {
Wang Nan3a62a7b2016-05-23 07:13:41 +0000165 *start = old;
166 *end = head;
167 return 0;
168 }
169
170 return backward_rb_find_range(data, mask, head, start, end);
171}
172
Wang Nana4ea0ec2016-07-14 08:34:36 +0000173static int
174record__mmap_read(struct record *rec, struct perf_mmap *md,
175 bool overwrite, bool backward)
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200176{
David Ahern7b8283b52015-04-07 09:20:37 -0600177 u64 head = perf_mmap__read_head(md);
178 u64 old = md->prev;
Wang Nan09fa4f42016-05-23 07:13:40 +0000179 u64 end = head, start = old;
Jiri Olsa918512b2013-09-12 18:39:35 +0200180 unsigned char *data = md->base + page_size;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200181 unsigned long size;
182 void *buf;
David Ahern8d3eca22012-08-26 12:24:47 -0600183 int rc = 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200184
Wang Nana4ea0ec2016-07-14 08:34:36 +0000185 if (rb_find_range(data, md->mask, head,
186 old, &start, &end, backward))
Wang Nan3a62a7b2016-05-23 07:13:41 +0000187 return -1;
188
Wang Nan09fa4f42016-05-23 07:13:40 +0000189 if (start == end)
David Ahern8d3eca22012-08-26 12:24:47 -0600190 return 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200191
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200192 rec->samples++;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200193
Wang Nan09fa4f42016-05-23 07:13:40 +0000194 size = end - start;
Wang Nan2d11c652016-05-23 07:13:39 +0000195 if (size > (unsigned long)(md->mask) + 1) {
196 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
197
198 md->prev = head;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000199 perf_mmap__consume(md, overwrite || backward);
Wang Nan2d11c652016-05-23 07:13:39 +0000200 return 0;
201 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200202
Wang Nan09fa4f42016-05-23 07:13:40 +0000203 if ((start & md->mask) + size != (end & md->mask)) {
204 buf = &data[start & md->mask];
205 size = md->mask + 1 - (start & md->mask);
206 start += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200207
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300208 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600209 rc = -1;
210 goto out;
211 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200212 }
213
Wang Nan09fa4f42016-05-23 07:13:40 +0000214 buf = &data[start & md->mask];
215 size = end - start;
216 start += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200217
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300218 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600219 rc = -1;
220 goto out;
221 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200222
Wang Nan09fa4f42016-05-23 07:13:40 +0000223 md->prev = head;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000224 perf_mmap__consume(md, overwrite || backward);
David Ahern8d3eca22012-08-26 12:24:47 -0600225out:
226 return rc;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200227}
228
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300229static volatile int done;
230static volatile int signr = -1;
231static volatile int child_finished;
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000232
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300233static void sig_handler(int sig)
234{
235 if (sig == SIGCHLD)
236 child_finished = 1;
237 else
238 signr = sig;
239
240 done = 1;
241}
242
Wang Nana0748652016-11-26 07:03:28 +0000243static void sigsegv_handler(int sig)
244{
245 perf_hooks__recover();
246 sighandler_dump_stack(sig);
247}
248
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300249static void record__sig_exit(void)
250{
251 if (signr == -1)
252 return;
253
254 signal(signr, SIG_DFL);
255 raise(signr);
256}
257
Adrian Huntere31f0d02015-04-30 17:37:27 +0300258#ifdef HAVE_AUXTRACE_SUPPORT
259
Adrian Hunteref149c22015-04-09 18:53:45 +0300260static int record__process_auxtrace(struct perf_tool *tool,
261 union perf_event *event, void *data1,
262 size_t len1, void *data2, size_t len2)
263{
264 struct record *rec = container_of(tool, struct record, tool);
Adrian Hunter99fa2982015-04-30 17:37:25 +0300265 struct perf_data_file *file = &rec->file;
Adrian Hunteref149c22015-04-09 18:53:45 +0300266 size_t padding;
267 u8 pad[8] = {0};
268
Adrian Hunter99fa2982015-04-30 17:37:25 +0300269 if (!perf_data_file__is_pipe(file)) {
270 off_t file_offset;
271 int fd = perf_data_file__fd(file);
272 int err;
273
274 file_offset = lseek(fd, 0, SEEK_CUR);
275 if (file_offset == -1)
276 return -1;
277 err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index,
278 event, file_offset);
279 if (err)
280 return err;
281 }
282
Adrian Hunteref149c22015-04-09 18:53:45 +0300283 /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */
284 padding = (len1 + len2) & 7;
285 if (padding)
286 padding = 8 - padding;
287
288 record__write(rec, event, event->header.size);
289 record__write(rec, data1, len1);
290 if (len2)
291 record__write(rec, data2, len2);
292 record__write(rec, &pad, padding);
293
294 return 0;
295}
296
297static int record__auxtrace_mmap_read(struct record *rec,
298 struct auxtrace_mmap *mm)
299{
300 int ret;
301
302 ret = auxtrace_mmap__read(mm, rec->itr, &rec->tool,
303 record__process_auxtrace);
304 if (ret < 0)
305 return ret;
306
307 if (ret)
308 rec->samples++;
309
310 return 0;
311}
312
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300313static int record__auxtrace_mmap_read_snapshot(struct record *rec,
314 struct auxtrace_mmap *mm)
315{
316 int ret;
317
318 ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool,
319 record__process_auxtrace,
320 rec->opts.auxtrace_snapshot_size);
321 if (ret < 0)
322 return ret;
323
324 if (ret)
325 rec->samples++;
326
327 return 0;
328}
329
330static int record__auxtrace_read_snapshot_all(struct record *rec)
331{
332 int i;
333 int rc = 0;
334
335 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
336 struct auxtrace_mmap *mm =
337 &rec->evlist->mmap[i].auxtrace_mmap;
338
339 if (!mm->base)
340 continue;
341
342 if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) {
343 rc = -1;
344 goto out;
345 }
346 }
347out:
348 return rc;
349}
350
351static void record__read_auxtrace_snapshot(struct record *rec)
352{
353 pr_debug("Recording AUX area tracing snapshot\n");
354 if (record__auxtrace_read_snapshot_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000355 trigger_error(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300356 } else {
Wang Nan5f9cf592016-04-20 18:59:49 +0000357 if (auxtrace_record__snapshot_finish(rec->itr))
358 trigger_error(&auxtrace_snapshot_trigger);
359 else
360 trigger_ready(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300361 }
362}
363
Adrian Huntere31f0d02015-04-30 17:37:27 +0300364#else
365
366static inline
367int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
368 struct auxtrace_mmap *mm __maybe_unused)
369{
370 return 0;
371}
372
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300373static inline
374void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
375{
376}
377
378static inline
379int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
380{
381 return 0;
382}
383
Adrian Huntere31f0d02015-04-30 17:37:27 +0300384#endif
385
Wang Nancda57a82016-06-27 10:24:03 +0000386static int record__mmap_evlist(struct record *rec,
387 struct perf_evlist *evlist)
388{
389 struct record_opts *opts = &rec->opts;
390 char msg[512];
391
392 if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
393 opts->auxtrace_mmap_pages,
394 opts->auxtrace_snapshot_mode) < 0) {
395 if (errno == EPERM) {
396 pr_err("Permission error mapping pages.\n"
397 "Consider increasing "
398 "/proc/sys/kernel/perf_event_mlock_kb,\n"
399 "or try again with a smaller value of -m/--mmap_pages.\n"
400 "(current value: %u,%u)\n",
401 opts->mmap_pages, opts->auxtrace_mmap_pages);
402 return -errno;
403 } else {
404 pr_err("failed to mmap with %d (%s)\n", errno,
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300405 str_error_r(errno, msg, sizeof(msg)));
Wang Nancda57a82016-06-27 10:24:03 +0000406 if (errno)
407 return -errno;
408 else
409 return -EINVAL;
410 }
411 }
412 return 0;
413}
414
415static int record__mmap(struct record *rec)
416{
417 return record__mmap_evlist(rec, rec->evlist);
418}
419
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300420static int record__open(struct record *rec)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200421{
Arnaldo Carvalho de Melod6195a62017-02-13 16:45:24 -0300422 char msg[BUFSIZ];
Jiri Olsa6a4bb042012-08-08 12:22:36 +0200423 struct perf_evsel *pos;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200424 struct perf_evlist *evlist = rec->evlist;
425 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300426 struct record_opts *opts = &rec->opts;
Mathieu Poirier5d8bb1e2016-09-16 09:50:03 -0600427 struct perf_evsel_config_term *err_term;
David Ahern8d3eca22012-08-26 12:24:47 -0600428 int rc = 0;
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200429
Arnaldo Carvalho de Meloe68ae9c2016-04-11 18:15:29 -0300430 perf_evlist__config(evlist, opts, &callchain_param);
Jiri Olsacac21422012-11-12 18:34:00 +0100431
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -0300432 evlist__for_each_entry(evlist, pos) {
Ingo Molnar3da297a2009-06-07 17:39:02 +0200433try_again:
Kan Liangd988d5e2015-08-21 02:23:14 -0400434 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300435 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
Namhyung Kimbb963e12017-02-17 17:17:38 +0900436 if (verbose > 0)
Arnaldo Carvalho de Meloc0a54342012-12-13 14:16:30 -0300437 ui__warning("%s\n", msg);
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300438 goto try_again;
439 }
David Ahernca6a4252011-03-25 13:11:11 -0600440
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300441 rc = -errno;
442 perf_evsel__open_strerror(pos, &opts->target,
443 errno, msg, sizeof(msg));
444 ui__error("%s\n", msg);
David Ahern8d3eca22012-08-26 12:24:47 -0600445 goto out;
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300446 }
Li Zefanc171b552009-10-15 11:22:07 +0800447 }
Arnaldo Carvalho de Meloa43d3f02010-12-25 12:12:25 -0200448
Arnaldo Carvalho de Melo23d4aad2015-03-24 19:23:47 -0300449 if (perf_evlist__apply_filters(evlist, &pos)) {
450 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
451 pos->filter, perf_evsel__name(pos), errno,
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300452 str_error_r(errno, msg, sizeof(msg)));
David Ahern8d3eca22012-08-26 12:24:47 -0600453 rc = -1;
454 goto out;
Frederic Weisbecker0a102472011-02-26 04:51:54 +0100455 }
456
Mathieu Poirier5d8bb1e2016-09-16 09:50:03 -0600457 if (perf_evlist__apply_drv_configs(evlist, &pos, &err_term)) {
458 error("failed to set config \"%s\" on event %s with %d (%s)\n",
459 err_term->val.drv_cfg, perf_evsel__name(pos), errno,
460 str_error_r(errno, msg, sizeof(msg)));
461 rc = -1;
462 goto out;
463 }
464
Wang Nancda57a82016-06-27 10:24:03 +0000465 rc = record__mmap(rec);
466 if (rc)
David Ahern8d3eca22012-08-26 12:24:47 -0600467 goto out;
Arnaldo Carvalho de Melo0a27d7f2011-01-14 15:50:51 -0200468
Jiri Olsa563aecb2013-06-05 13:35:06 +0200469 session->evlist = evlist;
Arnaldo Carvalho de Melo7b56cce2012-08-01 19:31:00 -0300470 perf_session__set_id_hdr_size(session);
David Ahern8d3eca22012-08-26 12:24:47 -0600471out:
472 return rc;
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200473}
474
Namhyung Kime3d59112015-01-29 17:06:44 +0900475static int process_sample_event(struct perf_tool *tool,
476 union perf_event *event,
477 struct perf_sample *sample,
478 struct perf_evsel *evsel,
479 struct machine *machine)
480{
481 struct record *rec = container_of(tool, struct record, tool);
482
483 rec->samples++;
484
485 return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
486}
487
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300488static int process_buildids(struct record *rec)
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200489{
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200490 struct perf_data_file *file = &rec->file;
491 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200492
He Kuang457ae942015-05-28 13:17:30 +0000493 if (file->size == 0)
Arnaldo Carvalho de Melo9f591fd2010-03-11 15:53:11 -0300494 return 0;
495
Namhyung Kim00dc8652014-11-04 10:14:32 +0900496 /*
497 * During this process, it'll load kernel map and replace the
498 * dso->long_name to a real pathname it found. In this case
499 * we prefer the vmlinux path like
500 * /lib/modules/3.16.4/build/vmlinux
501 *
502 * rather than build-id path (in debug directory).
503 * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551
504 */
505 symbol_conf.ignore_vmlinux_buildid = true;
506
Namhyung Kim61566812016-01-11 22:37:09 +0900507 /*
508 * If --buildid-all is given, it marks all DSO regardless of hits,
509 * so no need to process samples.
510 */
511 if (rec->buildid_all)
512 rec->tool.sample = NULL;
513
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300514 return perf_session__process_events(session);
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200515}
516
Arnaldo Carvalho de Melo8115d602011-01-29 14:01:45 -0200517static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800518{
519 int err;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200520 struct perf_tool *tool = data;
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800521 /*
522 *As for guest kernel when processing subcommand record&report,
523 *we arrange module mmap prior to guest kernel mmap and trigger
524 *a preload dso because default guest module symbols are loaded
525 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
526 *method is used to avoid symbol missing when the first addr is
527 *in module instead of in guest kernel.
528 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200529 err = perf_event__synthesize_modules(tool, process_synthesized_event,
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200530 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800531 if (err < 0)
532 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300533 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800534
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800535 /*
536 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
537 * have no _text sometimes.
538 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200539 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
Adrian Hunter0ae617b2014-01-29 16:14:40 +0200540 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800541 if (err < 0)
542 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300543 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800544}
545
Frederic Weisbecker98402802010-05-02 22:05:29 +0200546static struct perf_event_header finished_round_event = {
547 .size = sizeof(struct perf_event_header),
548 .type = PERF_RECORD_FINISHED_ROUND,
549};
550
Wang Nana4ea0ec2016-07-14 08:34:36 +0000551static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist,
552 bool backward)
Frederic Weisbecker98402802010-05-02 22:05:29 +0200553{
Jiri Olsadcabb502014-07-25 16:56:16 +0200554 u64 bytes_written = rec->bytes_written;
Peter Zijlstra0e2e63d2010-05-20 14:45:26 +0200555 int i;
David Ahern8d3eca22012-08-26 12:24:47 -0600556 int rc = 0;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000557 struct perf_mmap *maps;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200558
Wang Nancb216862016-06-27 10:24:04 +0000559 if (!evlist)
560 return 0;
Adrian Hunteref149c22015-04-09 18:53:45 +0300561
Wang Nanb2cb6152016-07-14 08:34:39 +0000562 maps = backward ? evlist->backward_mmap : evlist->mmap;
Wang Nana4ea0ec2016-07-14 08:34:36 +0000563 if (!maps)
564 return 0;
Wang Nancb216862016-06-27 10:24:04 +0000565
Wang Nan54cc54d2016-07-14 08:34:42 +0000566 if (backward && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING)
567 return 0;
568
Wang Nana4ea0ec2016-07-14 08:34:36 +0000569 for (i = 0; i < evlist->nr_mmaps; i++) {
570 struct auxtrace_mmap *mm = &maps[i].auxtrace_mmap;
571
572 if (maps[i].base) {
573 if (record__mmap_read(rec, &maps[i],
574 evlist->overwrite, backward) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600575 rc = -1;
576 goto out;
577 }
578 }
Adrian Hunteref149c22015-04-09 18:53:45 +0300579
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300580 if (mm->base && !rec->opts.auxtrace_snapshot_mode &&
Adrian Hunteref149c22015-04-09 18:53:45 +0300581 record__auxtrace_mmap_read(rec, mm) != 0) {
582 rc = -1;
583 goto out;
584 }
Frederic Weisbecker98402802010-05-02 22:05:29 +0200585 }
586
Jiri Olsadcabb502014-07-25 16:56:16 +0200587 /*
588 * Mark the round finished in case we wrote
589 * at least one event.
590 */
591 if (bytes_written != rec->bytes_written)
592 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
David Ahern8d3eca22012-08-26 12:24:47 -0600593
Wang Nan54cc54d2016-07-14 08:34:42 +0000594 if (backward)
595 perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY);
David Ahern8d3eca22012-08-26 12:24:47 -0600596out:
597 return rc;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200598}
599
Wang Nancb216862016-06-27 10:24:04 +0000600static int record__mmap_read_all(struct record *rec)
601{
602 int err;
603
Wang Nana4ea0ec2016-07-14 08:34:36 +0000604 err = record__mmap_read_evlist(rec, rec->evlist, false);
Wang Nancb216862016-06-27 10:24:04 +0000605 if (err)
606 return err;
607
Wang Nan057374642016-07-14 08:34:43 +0000608 return record__mmap_read_evlist(rec, rec->evlist, true);
Wang Nancb216862016-06-27 10:24:04 +0000609}
610
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300611static void record__init_features(struct record *rec)
David Ahern57706ab2013-11-06 11:41:34 -0700612{
David Ahern57706ab2013-11-06 11:41:34 -0700613 struct perf_session *session = rec->session;
614 int feat;
615
616 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
617 perf_header__set_feat(&session->header, feat);
618
619 if (rec->no_buildid)
620 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
621
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300622 if (!have_tracepoints(&rec->evlist->entries))
David Ahern57706ab2013-11-06 11:41:34 -0700623 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
624
625 if (!rec->opts.branch_stack)
626 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
Adrian Hunteref149c22015-04-09 18:53:45 +0300627
628 if (!rec->opts.full_auxtrace)
629 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
Jiri Olsaffa517a2015-10-25 15:51:43 +0100630
631 perf_header__clear_feat(&session->header, HEADER_STAT);
David Ahern57706ab2013-11-06 11:41:34 -0700632}
633
Wang Nane1ab48b2016-02-26 09:32:10 +0000634static void
635record__finish_output(struct record *rec)
636{
637 struct perf_data_file *file = &rec->file;
638 int fd = perf_data_file__fd(file);
639
640 if (file->is_pipe)
641 return;
642
643 rec->session->header.data_size += rec->bytes_written;
644 file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR);
645
646 if (!rec->no_buildid) {
647 process_buildids(rec);
648
649 if (rec->buildid_all)
650 dsos__hit_all(rec->session);
651 }
652 perf_session__write_header(rec->session, rec->evlist, fd, true);
653
654 return;
655}
656
Wang Nan4ea648a2016-07-14 08:34:47 +0000657static int record__synthesize_workload(struct record *rec, bool tail)
Wang Nanbe7b0c92016-04-20 18:59:54 +0000658{
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -0300659 int err;
660 struct thread_map *thread_map;
Wang Nanbe7b0c92016-04-20 18:59:54 +0000661
Wang Nan4ea648a2016-07-14 08:34:47 +0000662 if (rec->opts.tail_synthesize != tail)
663 return 0;
664
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -0300665 thread_map = thread_map__new_by_tid(rec->evlist->workload.pid);
666 if (thread_map == NULL)
667 return -1;
668
669 err = perf_event__synthesize_thread_map(&rec->tool, thread_map,
Wang Nanbe7b0c92016-04-20 18:59:54 +0000670 process_synthesized_event,
671 &rec->session->machines.host,
672 rec->opts.sample_address,
673 rec->opts.proc_map_timeout);
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -0300674 thread_map__put(thread_map);
675 return err;
Wang Nanbe7b0c92016-04-20 18:59:54 +0000676}
677
Wang Nan4ea648a2016-07-14 08:34:47 +0000678static int record__synthesize(struct record *rec, bool tail);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000679
Wang Nanecfd7a92016-04-13 08:21:07 +0000680static int
681record__switch_output(struct record *rec, bool at_exit)
682{
683 struct perf_data_file *file = &rec->file;
684 int fd, err;
685
686 /* Same Size: "2015122520103046"*/
687 char timestamp[] = "InvalidTimestamp";
688
Wang Nan4ea648a2016-07-14 08:34:47 +0000689 record__synthesize(rec, true);
690 if (target__none(&rec->opts.target))
691 record__synthesize_workload(rec, true);
692
Wang Nanecfd7a92016-04-13 08:21:07 +0000693 rec->samples = 0;
694 record__finish_output(rec);
695 err = fetch_current_timestamp(timestamp, sizeof(timestamp));
696 if (err) {
697 pr_err("Failed to get current timestamp\n");
698 return -EINVAL;
699 }
700
701 fd = perf_data_file__switch(file, timestamp,
702 rec->session->header.data_offset,
703 at_exit);
704 if (fd >= 0 && !at_exit) {
705 rec->bytes_written = 0;
706 rec->session->header.data_size = 0;
707 }
708
709 if (!quiet)
710 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
711 file->path, timestamp);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000712
713 /* Output tracking events */
Wang Nanbe7b0c92016-04-20 18:59:54 +0000714 if (!at_exit) {
Wang Nan4ea648a2016-07-14 08:34:47 +0000715 record__synthesize(rec, false);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000716
Wang Nanbe7b0c92016-04-20 18:59:54 +0000717 /*
718 * In 'perf record --switch-output' without -a,
719 * record__synthesize() in record__switch_output() won't
720 * generate tracking events because there's no thread_map
721 * in evlist. Which causes newly created perf.data doesn't
722 * contain map and comm information.
723 * Create a fake thread_map and directly call
724 * perf_event__synthesize_thread_map() for those events.
725 */
726 if (target__none(&rec->opts.target))
Wang Nan4ea648a2016-07-14 08:34:47 +0000727 record__synthesize_workload(rec, false);
Wang Nanbe7b0c92016-04-20 18:59:54 +0000728 }
Wang Nanecfd7a92016-04-13 08:21:07 +0000729 return fd;
730}
731
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300732static volatile int workload_exec_errno;
733
734/*
735 * perf_evlist__prepare_workload will send a SIGUSR1
736 * if the fork fails, since we asked by setting its
737 * want_signal to true.
738 */
Namhyung Kim45604712014-05-12 09:47:24 +0900739static void workload_exec_failed_signal(int signo __maybe_unused,
740 siginfo_t *info,
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300741 void *ucontext __maybe_unused)
742{
743 workload_exec_errno = info->si_value.sival_int;
744 done = 1;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300745 child_finished = 1;
746}
747
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300748static void snapshot_sig_handler(int sig);
Jiri Olsabfacbe32017-01-09 10:52:00 +0100749static void alarm_sig_handler(int sig);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300750
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200751int __weak
752perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
753 struct perf_tool *tool __maybe_unused,
754 perf_event__handler_t process __maybe_unused,
755 struct machine *machine __maybe_unused)
756{
757 return 0;
758}
759
Wang Nanee667f92016-06-27 10:24:05 +0000760static const struct perf_event_mmap_page *
761perf_evlist__pick_pc(struct perf_evlist *evlist)
762{
Wang Nanb2cb6152016-07-14 08:34:39 +0000763 if (evlist) {
764 if (evlist->mmap && evlist->mmap[0].base)
765 return evlist->mmap[0].base;
766 if (evlist->backward_mmap && evlist->backward_mmap[0].base)
767 return evlist->backward_mmap[0].base;
768 }
Wang Nanee667f92016-06-27 10:24:05 +0000769 return NULL;
770}
771
Wang Nanc45628b2016-05-24 02:28:59 +0000772static const struct perf_event_mmap_page *record__pick_pc(struct record *rec)
773{
Wang Nanee667f92016-06-27 10:24:05 +0000774 const struct perf_event_mmap_page *pc;
775
776 pc = perf_evlist__pick_pc(rec->evlist);
777 if (pc)
778 return pc;
Wang Nanc45628b2016-05-24 02:28:59 +0000779 return NULL;
780}
781
Wang Nan4ea648a2016-07-14 08:34:47 +0000782static int record__synthesize(struct record *rec, bool tail)
Wang Nanc45c86e2016-02-26 09:32:07 +0000783{
784 struct perf_session *session = rec->session;
785 struct machine *machine = &session->machines.host;
786 struct perf_data_file *file = &rec->file;
787 struct record_opts *opts = &rec->opts;
788 struct perf_tool *tool = &rec->tool;
789 int fd = perf_data_file__fd(file);
790 int err = 0;
791
Wang Nan4ea648a2016-07-14 08:34:47 +0000792 if (rec->opts.tail_synthesize != tail)
793 return 0;
794
Wang Nanc45c86e2016-02-26 09:32:07 +0000795 if (file->is_pipe) {
796 err = perf_event__synthesize_attrs(tool, session,
797 process_synthesized_event);
798 if (err < 0) {
799 pr_err("Couldn't synthesize attrs.\n");
800 goto out;
801 }
802
803 if (have_tracepoints(&rec->evlist->entries)) {
804 /*
805 * FIXME err <= 0 here actually means that
806 * there were no tracepoints so its not really
807 * an error, just that we don't need to
808 * synthesize anything. We really have to
809 * return this more properly and also
810 * propagate errors that now are calling die()
811 */
812 err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
813 process_synthesized_event);
814 if (err <= 0) {
815 pr_err("Couldn't record tracing data.\n");
816 goto out;
817 }
818 rec->bytes_written += err;
819 }
820 }
821
Wang Nanc45628b2016-05-24 02:28:59 +0000822 err = perf_event__synth_time_conv(record__pick_pc(rec), tool,
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200823 process_synthesized_event, machine);
824 if (err)
825 goto out;
826
Wang Nanc45c86e2016-02-26 09:32:07 +0000827 if (rec->opts.full_auxtrace) {
828 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
829 session, process_synthesized_event);
830 if (err)
831 goto out;
832 }
833
834 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
835 machine);
836 WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
837 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
838 "Check /proc/kallsyms permission or run as root.\n");
839
840 err = perf_event__synthesize_modules(tool, process_synthesized_event,
841 machine);
842 WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
843 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
844 "Check /proc/modules permission or run as root.\n");
845
846 if (perf_guest) {
847 machines__process_guests(&session->machines,
848 perf_event__synthesize_guest_os, tool);
849 }
850
851 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
852 process_synthesized_event, opts->sample_address,
853 opts->proc_map_timeout);
854out:
855 return err;
856}
857
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300858static int __cmd_record(struct record *rec, int argc, const char **argv)
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200859{
David Ahern57706ab2013-11-06 11:41:34 -0700860 int err;
Namhyung Kim45604712014-05-12 09:47:24 +0900861 int status = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200862 unsigned long waking = 0;
Zhang, Yanmin46be6042010-03-18 11:36:04 -0300863 const bool forks = argc > 0;
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300864 struct machine *machine;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200865 struct perf_tool *tool = &rec->tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300866 struct record_opts *opts = &rec->opts;
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200867 struct perf_data_file *file = &rec->file;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200868 struct perf_session *session;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300869 bool disabled = false, draining = false;
Namhyung Kim42aa2762015-01-29 17:06:48 +0900870 int fd;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200871
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200872 rec->progname = argv[0];
Andi Kleen33e49ea2011-09-15 14:31:40 -0700873
Namhyung Kim45604712014-05-12 09:47:24 +0900874 atexit(record__sig_exit);
Peter Zijlstraf5970552009-06-18 23:22:55 +0200875 signal(SIGCHLD, sig_handler);
876 signal(SIGINT, sig_handler);
David Ahern804f7ac2013-05-06 12:24:23 -0600877 signal(SIGTERM, sig_handler);
Wang Nana0748652016-11-26 07:03:28 +0000878 signal(SIGSEGV, sigsegv_handler);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000879
Hari Bathinif3b36142017-03-08 02:11:43 +0530880 if (rec->opts.record_namespaces)
881 tool->namespace_events = true;
882
Jiri Olsadc0c6122017-01-09 10:51:58 +0100883 if (rec->opts.auxtrace_snapshot_mode || rec->switch_output.enabled) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300884 signal(SIGUSR2, snapshot_sig_handler);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000885 if (rec->opts.auxtrace_snapshot_mode)
886 trigger_on(&auxtrace_snapshot_trigger);
Jiri Olsadc0c6122017-01-09 10:51:58 +0100887 if (rec->switch_output.enabled)
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000888 trigger_on(&switch_output_trigger);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000889 } else {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300890 signal(SIGUSR2, SIG_IGN);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000891 }
Peter Zijlstraf5970552009-06-18 23:22:55 +0200892
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300893 session = perf_session__new(file, false, tool);
Arnaldo Carvalho de Melo94c744b2009-12-11 21:24:02 -0200894 if (session == NULL) {
Adrien BAKffa91882014-04-18 11:00:43 +0900895 pr_err("Perf session creation failed.\n");
Arnaldo Carvalho de Meloa9a70bb2009-11-17 01:18:11 -0200896 return -1;
897 }
898
Namhyung Kim42aa2762015-01-29 17:06:48 +0900899 fd = perf_data_file__fd(file);
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200900 rec->session = session;
901
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300902 record__init_features(rec);
Stephane Eranian330aa672012-03-08 23:47:46 +0100903
Arnaldo Carvalho de Melod4db3f12009-12-27 21:36:57 -0200904 if (forks) {
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300905 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200906 argv, file->is_pipe,
Arnaldo Carvalho de Melo735f7e02014-01-03 14:56:49 -0300907 workload_exec_failed_signal);
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200908 if (err < 0) {
909 pr_err("Couldn't run the workload!\n");
Namhyung Kim45604712014-05-12 09:47:24 +0900910 status = err;
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200911 goto out_delete_session;
Jens Axboe0a5ac842009-08-12 11:18:01 +0200912 }
Peter Zijlstra856e9662009-12-16 17:55:55 +0100913 }
914
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300915 if (record__open(rec) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600916 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900917 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600918 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200919
Wang Nan8690a2a2016-02-22 09:10:32 +0000920 err = bpf__apply_obj_config();
921 if (err) {
922 char errbuf[BUFSIZ];
923
924 bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
925 pr_err("ERROR: Apply config to BPF failed: %s\n",
926 errbuf);
927 goto out_child;
928 }
929
Adrian Huntercca84822015-08-19 17:29:21 +0300930 /*
931 * Normally perf_session__new would do this, but it doesn't have the
932 * evlist.
933 */
934 if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
935 pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
936 rec->tool.ordered_events = false;
937 }
938
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300939 if (!rec->evlist->nr_groups)
Namhyung Kima8bb5592013-01-22 18:09:31 +0900940 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
941
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200942 if (file->is_pipe) {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900943 err = perf_header__write_pipe(fd);
Tom Zanussi529870e2010-04-01 23:59:16 -0500944 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900945 goto out_child;
Jiri Olsa563aecb2013-06-05 13:35:06 +0200946 } else {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900947 err = perf_session__write_header(session, rec->evlist, fd, false);
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200948 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900949 goto out_child;
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200950 }
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +0200951
David Ahernd3665492012-02-06 15:27:52 -0700952 if (!rec->no_buildid
Robert Richtere20960c2011-12-07 10:02:55 +0100953 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
David Ahernd3665492012-02-06 15:27:52 -0700954 pr_err("Couldn't generate buildids. "
Robert Richtere20960c2011-12-07 10:02:55 +0100955 "Use --no-buildid to profile anyway.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600956 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900957 goto out_child;
Robert Richtere20960c2011-12-07 10:02:55 +0100958 }
959
Arnaldo Carvalho de Melo34ba5122012-12-19 09:04:24 -0300960 machine = &session->machines.host;
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200961
Wang Nan4ea648a2016-07-14 08:34:47 +0000962 err = record__synthesize(rec, false);
Wang Nanc45c86e2016-02-26 09:32:07 +0000963 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900964 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600965
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200966 if (rec->realtime_prio) {
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200967 struct sched_param param;
968
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200969 param.sched_priority = rec->realtime_prio;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200970 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
Arnaldo Carvalho de Melo6beba7a2009-10-21 17:34:06 -0200971 pr_err("Could not set realtime priority.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600972 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900973 goto out_child;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200974 }
975 }
976
Jiri Olsa774cb492012-11-12 18:34:01 +0100977 /*
978 * When perf is starting the traced process, all the events
979 * (apart from group members) have enable_on_exec=1 set,
980 * so don't spoil it by prematurely enabling them.
981 */
Andi Kleen6619a532014-01-11 13:38:27 -0800982 if (!target__none(&opts->target) && !opts->initial_delay)
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300983 perf_evlist__enable(rec->evlist);
David Ahern764e16a32011-08-25 10:17:55 -0600984
Peter Zijlstra856e9662009-12-16 17:55:55 +0100985 /*
986 * Let the child rip
987 */
Namhyung Kime803cf92015-09-22 09:24:55 +0900988 if (forks) {
Namhyung Kime5bed562015-09-30 10:45:24 +0900989 union perf_event *event;
Hari Bathinie907caf2017-03-08 02:11:51 +0530990 pid_t tgid;
Namhyung Kime5bed562015-09-30 10:45:24 +0900991
992 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
993 if (event == NULL) {
994 err = -ENOMEM;
995 goto out_child;
996 }
997
Namhyung Kime803cf92015-09-22 09:24:55 +0900998 /*
999 * Some H/W events are generated before COMM event
1000 * which is emitted during exec(), so perf script
1001 * cannot see a correct process name for those events.
1002 * Synthesize COMM event to prevent it.
1003 */
Hari Bathinie907caf2017-03-08 02:11:51 +05301004 tgid = perf_event__synthesize_comm(tool, event,
1005 rec->evlist->workload.pid,
1006 process_synthesized_event,
1007 machine);
1008 free(event);
1009
1010 if (tgid == -1)
1011 goto out_child;
1012
1013 event = malloc(sizeof(event->namespaces) +
1014 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
1015 machine->id_hdr_size);
1016 if (event == NULL) {
1017 err = -ENOMEM;
1018 goto out_child;
1019 }
1020
1021 /*
1022 * Synthesize NAMESPACES event for the command specified.
1023 */
1024 perf_event__synthesize_namespaces(tool, event,
1025 rec->evlist->workload.pid,
1026 tgid, process_synthesized_event,
1027 machine);
Namhyung Kime5bed562015-09-30 10:45:24 +09001028 free(event);
Namhyung Kime803cf92015-09-22 09:24:55 +09001029
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001030 perf_evlist__start_workload(rec->evlist);
Namhyung Kime803cf92015-09-22 09:24:55 +09001031 }
Peter Zijlstra856e9662009-12-16 17:55:55 +01001032
Andi Kleen6619a532014-01-11 13:38:27 -08001033 if (opts->initial_delay) {
Arnaldo Carvalho de Melo0693e682016-08-08 15:05:46 -03001034 usleep(opts->initial_delay * USEC_PER_MSEC);
Andi Kleen6619a532014-01-11 13:38:27 -08001035 perf_evlist__enable(rec->evlist);
1036 }
1037
Wang Nan5f9cf592016-04-20 18:59:49 +00001038 trigger_ready(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001039 trigger_ready(&switch_output_trigger);
Wang Nana0748652016-11-26 07:03:28 +00001040 perf_hooks__invoke_record_start();
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001041 for (;;) {
Yang Shi9f065192015-09-29 14:49:43 -07001042 unsigned long long hits = rec->samples;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001043
Wang Nan057374642016-07-14 08:34:43 +00001044 /*
1045 * rec->evlist->bkw_mmap_state is possible to be
1046 * BKW_MMAP_EMPTY here: when done == true and
1047 * hits != rec->samples in previous round.
1048 *
1049 * perf_evlist__toggle_bkw_mmap ensure we never
1050 * convert BKW_MMAP_EMPTY to BKW_MMAP_DATA_PENDING.
1051 */
1052 if (trigger_is_hit(&switch_output_trigger) || done || draining)
1053 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_DATA_PENDING);
1054
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001055 if (record__mmap_read_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +00001056 trigger_error(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001057 trigger_error(&switch_output_trigger);
David Ahern8d3eca22012-08-26 12:24:47 -06001058 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001059 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -06001060 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001061
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001062 if (auxtrace_record__snapshot_started) {
1063 auxtrace_record__snapshot_started = 0;
Wang Nan5f9cf592016-04-20 18:59:49 +00001064 if (!trigger_is_error(&auxtrace_snapshot_trigger))
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001065 record__read_auxtrace_snapshot(rec);
Wang Nan5f9cf592016-04-20 18:59:49 +00001066 if (trigger_is_error(&auxtrace_snapshot_trigger)) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001067 pr_err("AUX area tracing snapshot failed\n");
1068 err = -1;
1069 goto out_child;
1070 }
1071 }
1072
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001073 if (trigger_is_hit(&switch_output_trigger)) {
Wang Nan057374642016-07-14 08:34:43 +00001074 /*
1075 * If switch_output_trigger is hit, the data in
1076 * overwritable ring buffer should have been collected,
1077 * so bkw_mmap_state should be set to BKW_MMAP_EMPTY.
1078 *
1079 * If SIGUSR2 raise after or during record__mmap_read_all(),
1080 * record__mmap_read_all() didn't collect data from
1081 * overwritable ring buffer. Read again.
1082 */
1083 if (rec->evlist->bkw_mmap_state == BKW_MMAP_RUNNING)
1084 continue;
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001085 trigger_ready(&switch_output_trigger);
1086
Wang Nan057374642016-07-14 08:34:43 +00001087 /*
1088 * Reenable events in overwrite ring buffer after
1089 * record__mmap_read_all(): we should have collected
1090 * data from it.
1091 */
1092 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_RUNNING);
1093
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001094 if (!quiet)
1095 fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
1096 waking);
1097 waking = 0;
1098 fd = record__switch_output(rec, false);
1099 if (fd < 0) {
1100 pr_err("Failed to switch to new file\n");
1101 trigger_error(&switch_output_trigger);
1102 err = fd;
1103 goto out_child;
1104 }
Jiri Olsabfacbe32017-01-09 10:52:00 +01001105
1106 /* re-arm the alarm */
1107 if (rec->switch_output.time)
1108 alarm(rec->switch_output.time);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001109 }
1110
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001111 if (hits == rec->samples) {
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001112 if (done || draining)
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001113 break;
Arnaldo Carvalho de Melof66a8892014-08-18 17:25:59 -03001114 err = perf_evlist__poll(rec->evlist, -1);
Jiri Olsaa5151142014-06-02 13:44:23 -04001115 /*
1116 * Propagate error, only if there's any. Ignore positive
1117 * number of returned events and interrupt error.
1118 */
1119 if (err > 0 || (err < 0 && errno == EINTR))
Namhyung Kim45604712014-05-12 09:47:24 +09001120 err = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001121 waking++;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001122
1123 if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
1124 draining = true;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001125 }
1126
Jiri Olsa774cb492012-11-12 18:34:01 +01001127 /*
1128 * When perf is starting the traced process, at the end events
1129 * die with the process and we wait for that. Thus no need to
1130 * disable events in this case.
1131 */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001132 if (done && !disabled && !target__none(&opts->target)) {
Wang Nan5f9cf592016-04-20 18:59:49 +00001133 trigger_off(&auxtrace_snapshot_trigger);
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001134 perf_evlist__disable(rec->evlist);
Jiri Olsa27119262012-11-12 18:34:02 +01001135 disabled = true;
1136 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001137 }
Wang Nan5f9cf592016-04-20 18:59:49 +00001138 trigger_off(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001139 trigger_off(&switch_output_trigger);
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001140
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001141 if (forks && workload_exec_errno) {
Masami Hiramatsu35550da2014-08-14 02:22:43 +00001142 char msg[STRERR_BUFSIZE];
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -03001143 const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001144 pr_err("Workload failed: %s\n", emsg);
1145 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001146 goto out_child;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001147 }
1148
Namhyung Kime3d59112015-01-29 17:06:44 +09001149 if (!quiet)
Namhyung Kim45604712014-05-12 09:47:24 +09001150 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001151
Wang Nan4ea648a2016-07-14 08:34:47 +00001152 if (target__none(&rec->opts.target))
1153 record__synthesize_workload(rec, true);
1154
Namhyung Kim45604712014-05-12 09:47:24 +09001155out_child:
1156 if (forks) {
1157 int exit_status;
Ingo Molnaraddc2782009-06-02 23:43:11 +02001158
Namhyung Kim45604712014-05-12 09:47:24 +09001159 if (!child_finished)
1160 kill(rec->evlist->workload.pid, SIGTERM);
1161
1162 wait(&exit_status);
1163
1164 if (err < 0)
1165 status = err;
1166 else if (WIFEXITED(exit_status))
1167 status = WEXITSTATUS(exit_status);
1168 else if (WIFSIGNALED(exit_status))
1169 signr = WTERMSIG(exit_status);
1170 } else
1171 status = err;
1172
Wang Nan4ea648a2016-07-14 08:34:47 +00001173 record__synthesize(rec, true);
Namhyung Kime3d59112015-01-29 17:06:44 +09001174 /* this will be recalculated during process_buildids() */
1175 rec->samples = 0;
1176
Wang Nanecfd7a92016-04-13 08:21:07 +00001177 if (!err) {
1178 if (!rec->timestamp_filename) {
1179 record__finish_output(rec);
1180 } else {
1181 fd = record__switch_output(rec, true);
1182 if (fd < 0) {
1183 status = fd;
1184 goto out_delete_session;
1185 }
1186 }
1187 }
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001188
Wang Nana0748652016-11-26 07:03:28 +00001189 perf_hooks__invoke_record_end();
1190
Namhyung Kime3d59112015-01-29 17:06:44 +09001191 if (!err && !quiet) {
1192 char samples[128];
Wang Nanecfd7a92016-04-13 08:21:07 +00001193 const char *postfix = rec->timestamp_filename ?
1194 ".<timestamp>" : "";
Namhyung Kime3d59112015-01-29 17:06:44 +09001195
Adrian Hunteref149c22015-04-09 18:53:45 +03001196 if (rec->samples && !rec->opts.full_auxtrace)
Namhyung Kime3d59112015-01-29 17:06:44 +09001197 scnprintf(samples, sizeof(samples),
1198 " (%" PRIu64 " samples)", rec->samples);
1199 else
1200 samples[0] = '\0';
1201
Wang Nanecfd7a92016-04-13 08:21:07 +00001202 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
Namhyung Kime3d59112015-01-29 17:06:44 +09001203 perf_data_file__size(file) / 1024.0 / 1024.0,
Wang Nanecfd7a92016-04-13 08:21:07 +00001204 file->path, postfix, samples);
Namhyung Kime3d59112015-01-29 17:06:44 +09001205 }
1206
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001207out_delete_session:
1208 perf_session__delete(session);
Namhyung Kim45604712014-05-12 09:47:24 +09001209 return status;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001210}
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001211
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001212static void callchain_debug(struct callchain_param *callchain)
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001213{
Kan Liangaad2b212015-01-05 13:23:04 -05001214 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
Jiri Olsaa601fdf2014-02-03 12:44:43 +01001215
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001216 pr_debug("callchain: type %s\n", str[callchain->record_mode]);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001217
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001218 if (callchain->record_mode == CALLCHAIN_DWARF)
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001219 pr_debug("callchain: stack dump size %d\n",
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001220 callchain->dump_size);
1221}
1222
1223int record_opts__parse_callchain(struct record_opts *record,
1224 struct callchain_param *callchain,
1225 const char *arg, bool unset)
1226{
1227 int ret;
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001228 callchain->enabled = !unset;
1229
1230 /* --no-call-graph */
1231 if (unset) {
1232 callchain->record_mode = CALLCHAIN_NONE;
1233 pr_debug("callchain: disabled\n");
1234 return 0;
1235 }
1236
1237 ret = parse_callchain_record_opt(arg, callchain);
1238 if (!ret) {
1239 /* Enable data address sampling for DWARF unwind. */
1240 if (callchain->record_mode == CALLCHAIN_DWARF)
1241 record->sample_address = true;
1242 callchain_debug(callchain);
1243 }
1244
1245 return ret;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001246}
1247
Kan Liangc421e802015-07-29 05:42:12 -04001248int record_parse_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001249 const char *arg,
1250 int unset)
1251{
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001252 return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
Jiri Olsa26d33022012-08-07 15:20:47 +02001253}
1254
Kan Liangc421e802015-07-29 05:42:12 -04001255int record_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001256 const char *arg __maybe_unused,
1257 int unset __maybe_unused)
1258{
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001259 struct callchain_param *callchain = opt->value;
Kan Liangc421e802015-07-29 05:42:12 -04001260
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001261 callchain->enabled = true;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001262
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001263 if (callchain->record_mode == CALLCHAIN_NONE)
1264 callchain->record_mode = CALLCHAIN_FP;
Jiri Olsaeb853e82014-02-03 12:44:42 +01001265
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001266 callchain_debug(callchain);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001267 return 0;
1268}
1269
Jiri Olsaeb853e82014-02-03 12:44:42 +01001270static int perf_record_config(const char *var, const char *value, void *cb)
1271{
Namhyung Kim7a29c082015-12-15 10:49:56 +09001272 struct record *rec = cb;
1273
1274 if (!strcmp(var, "record.build-id")) {
1275 if (!strcmp(value, "cache"))
1276 rec->no_buildid_cache = false;
1277 else if (!strcmp(value, "no-cache"))
1278 rec->no_buildid_cache = true;
1279 else if (!strcmp(value, "skip"))
1280 rec->no_buildid = true;
1281 else
1282 return -1;
1283 return 0;
1284 }
Jiri Olsaeb853e82014-02-03 12:44:42 +01001285 if (!strcmp(var, "record.call-graph"))
Namhyung Kim5a2e5e82014-09-23 10:01:44 +09001286 var = "call-graph.record-mode"; /* fall-through */
Jiri Olsaeb853e82014-02-03 12:44:42 +01001287
1288 return perf_default_config(var, value, cb);
1289}
1290
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001291struct clockid_map {
1292 const char *name;
1293 int clockid;
1294};
1295
1296#define CLOCKID_MAP(n, c) \
1297 { .name = n, .clockid = (c), }
1298
1299#define CLOCKID_END { .name = NULL, }
1300
1301
1302/*
1303 * Add the missing ones, we need to build on many distros...
1304 */
1305#ifndef CLOCK_MONOTONIC_RAW
1306#define CLOCK_MONOTONIC_RAW 4
1307#endif
1308#ifndef CLOCK_BOOTTIME
1309#define CLOCK_BOOTTIME 7
1310#endif
1311#ifndef CLOCK_TAI
1312#define CLOCK_TAI 11
1313#endif
1314
1315static const struct clockid_map clockids[] = {
1316 /* available for all events, NMI safe */
1317 CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
1318 CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
1319
1320 /* available for some events */
1321 CLOCKID_MAP("realtime", CLOCK_REALTIME),
1322 CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
1323 CLOCKID_MAP("tai", CLOCK_TAI),
1324
1325 /* available for the lazy */
1326 CLOCKID_MAP("mono", CLOCK_MONOTONIC),
1327 CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
1328 CLOCKID_MAP("real", CLOCK_REALTIME),
1329 CLOCKID_MAP("boot", CLOCK_BOOTTIME),
1330
1331 CLOCKID_END,
1332};
1333
1334static int parse_clockid(const struct option *opt, const char *str, int unset)
1335{
1336 struct record_opts *opts = (struct record_opts *)opt->value;
1337 const struct clockid_map *cm;
1338 const char *ostr = str;
1339
1340 if (unset) {
1341 opts->use_clockid = 0;
1342 return 0;
1343 }
1344
1345 /* no arg passed */
1346 if (!str)
1347 return 0;
1348
1349 /* no setting it twice */
1350 if (opts->use_clockid)
1351 return -1;
1352
1353 opts->use_clockid = true;
1354
1355 /* if its a number, we're done */
1356 if (sscanf(str, "%d", &opts->clockid) == 1)
1357 return 0;
1358
1359 /* allow a "CLOCK_" prefix to the name */
1360 if (!strncasecmp(str, "CLOCK_", 6))
1361 str += 6;
1362
1363 for (cm = clockids; cm->name; cm++) {
1364 if (!strcasecmp(str, cm->name)) {
1365 opts->clockid = cm->clockid;
1366 return 0;
1367 }
1368 }
1369
1370 opts->use_clockid = false;
1371 ui__warning("unknown clockid %s, check man page\n", ostr);
1372 return -1;
1373}
1374
Adrian Huntere9db1312015-04-09 18:53:46 +03001375static int record__parse_mmap_pages(const struct option *opt,
1376 const char *str,
1377 int unset __maybe_unused)
1378{
1379 struct record_opts *opts = opt->value;
1380 char *s, *p;
1381 unsigned int mmap_pages;
1382 int ret;
1383
1384 if (!str)
1385 return -EINVAL;
1386
1387 s = strdup(str);
1388 if (!s)
1389 return -ENOMEM;
1390
1391 p = strchr(s, ',');
1392 if (p)
1393 *p = '\0';
1394
1395 if (*s) {
1396 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
1397 if (ret)
1398 goto out_free;
1399 opts->mmap_pages = mmap_pages;
1400 }
1401
1402 if (!p) {
1403 ret = 0;
1404 goto out_free;
1405 }
1406
1407 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
1408 if (ret)
1409 goto out_free;
1410
1411 opts->auxtrace_mmap_pages = mmap_pages;
1412
1413out_free:
1414 free(s);
1415 return ret;
1416}
1417
Jiri Olsa0c582442017-01-09 10:51:59 +01001418static void switch_output_size_warn(struct record *rec)
1419{
1420 u64 wakeup_size = perf_evlist__mmap_size(rec->opts.mmap_pages);
1421 struct switch_output *s = &rec->switch_output;
1422
1423 wakeup_size /= 2;
1424
1425 if (s->size < wakeup_size) {
1426 char buf[100];
1427
1428 unit_number__scnprintf(buf, sizeof(buf), wakeup_size);
1429 pr_warning("WARNING: switch-output data size lower than "
1430 "wakeup kernel buffer size (%s) "
1431 "expect bigger perf.data sizes\n", buf);
1432 }
1433}
1434
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001435static int switch_output_setup(struct record *rec)
1436{
1437 struct switch_output *s = &rec->switch_output;
Jiri Olsadc0c6122017-01-09 10:51:58 +01001438 static struct parse_tag tags_size[] = {
1439 { .tag = 'B', .mult = 1 },
1440 { .tag = 'K', .mult = 1 << 10 },
1441 { .tag = 'M', .mult = 1 << 20 },
1442 { .tag = 'G', .mult = 1 << 30 },
1443 { .tag = 0 },
1444 };
Jiri Olsabfacbe32017-01-09 10:52:00 +01001445 static struct parse_tag tags_time[] = {
1446 { .tag = 's', .mult = 1 },
1447 { .tag = 'm', .mult = 60 },
1448 { .tag = 'h', .mult = 60*60 },
1449 { .tag = 'd', .mult = 60*60*24 },
1450 { .tag = 0 },
1451 };
Jiri Olsadc0c6122017-01-09 10:51:58 +01001452 unsigned long val;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001453
1454 if (!s->set)
1455 return 0;
1456
1457 if (!strcmp(s->str, "signal")) {
1458 s->signal = true;
1459 pr_debug("switch-output with SIGUSR2 signal\n");
Jiri Olsadc0c6122017-01-09 10:51:58 +01001460 goto enabled;
1461 }
1462
1463 val = parse_tag_value(s->str, tags_size);
1464 if (val != (unsigned long) -1) {
1465 s->size = val;
1466 pr_debug("switch-output with %s size threshold\n", s->str);
1467 goto enabled;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001468 }
1469
Jiri Olsabfacbe32017-01-09 10:52:00 +01001470 val = parse_tag_value(s->str, tags_time);
1471 if (val != (unsigned long) -1) {
1472 s->time = val;
1473 pr_debug("switch-output with %s time threshold (%lu seconds)\n",
1474 s->str, s->time);
1475 goto enabled;
1476 }
1477
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001478 return -1;
Jiri Olsadc0c6122017-01-09 10:51:58 +01001479
1480enabled:
1481 rec->timestamp_filename = true;
1482 s->enabled = true;
Jiri Olsa0c582442017-01-09 10:51:59 +01001483
1484 if (s->size && !rec->opts.no_buffering)
1485 switch_output_size_warn(rec);
1486
Jiri Olsadc0c6122017-01-09 10:51:58 +01001487 return 0;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001488}
1489
Namhyung Kime5b2c202014-10-23 00:15:46 +09001490static const char * const __record_usage[] = {
Mike Galbraith9e0967532009-05-28 16:25:34 +02001491 "perf record [<options>] [<command>]",
1492 "perf record [<options>] -- <command> [<options>]",
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001493 NULL
1494};
Namhyung Kime5b2c202014-10-23 00:15:46 +09001495const char * const *record_usage = __record_usage;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001496
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001497/*
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001498 * XXX Ideally would be local to cmd_record() and passed to a record__new
1499 * because we need to have access to it in record__exit, that is called
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001500 * after cmd_record() exits, but since record_options need to be accessible to
1501 * builtin-script, leave it here.
1502 *
1503 * At least we don't ouch it in all the other functions here directly.
1504 *
1505 * Just say no to tons of global variables, sigh.
1506 */
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001507static struct record record = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001508 .opts = {
Andi Kleen8affc2b2014-07-31 14:45:04 +08001509 .sample_time = true,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001510 .mmap_pages = UINT_MAX,
1511 .user_freq = UINT_MAX,
1512 .user_interval = ULLONG_MAX,
Arnaldo Carvalho de Melo447a6012012-05-22 13:14:18 -03001513 .freq = 4000,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001514 .target = {
1515 .uses_mmap = true,
Adrian Hunter3aa59392013-11-15 15:52:29 +02001516 .default_per_cpu = true,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001517 },
Kan Liang9d9cad72015-06-17 09:51:11 -04001518 .proc_map_timeout = 500,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001519 },
Namhyung Kime3d59112015-01-29 17:06:44 +09001520 .tool = {
1521 .sample = process_sample_event,
1522 .fork = perf_event__process_fork,
Adrian Huntercca84822015-08-19 17:29:21 +03001523 .exit = perf_event__process_exit,
Namhyung Kime3d59112015-01-29 17:06:44 +09001524 .comm = perf_event__process_comm,
Hari Bathinif3b36142017-03-08 02:11:43 +05301525 .namespaces = perf_event__process_namespaces,
Namhyung Kime3d59112015-01-29 17:06:44 +09001526 .mmap = perf_event__process_mmap,
1527 .mmap2 = perf_event__process_mmap2,
Adrian Huntercca84822015-08-19 17:29:21 +03001528 .ordered_events = true,
Namhyung Kime3d59112015-01-29 17:06:44 +09001529 },
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001530};
Frederic Weisbecker7865e812010-04-14 19:42:07 +02001531
Namhyung Kim76a26542015-10-22 23:28:32 +09001532const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1533 "\n\t\t\t\tDefault: fp";
Arnaldo Carvalho de Melo61eaa3b2012-10-01 15:20:58 -03001534
Wang Nan0aab2132016-06-16 08:02:41 +00001535static bool dry_run;
1536
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001537/*
1538 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
1539 * with it and switch to use the library functions in perf_evlist that came
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001540 * from builtin-record.c, i.e. use record_opts,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001541 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
1542 * using pipes, etc.
1543 */
Jiri Olsaefd21302017-01-03 09:19:55 +01001544static struct option __record_options[] = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001545 OPT_CALLBACK('e', "event", &record.evlist, "event",
Thomas Gleixner86847b62009-06-06 12:24:17 +02001546 "event selector. use 'perf list' to list available events",
Jiri Olsaf120f9d2011-07-14 11:25:32 +02001547 parse_events_option),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001548 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
Li Zefanc171b552009-10-15 11:22:07 +08001549 "event filter", parse_filter),
Wang Nan4ba1faa2015-07-10 07:36:10 +00001550 OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
1551 NULL, "don't record events from perf itself",
1552 exclude_perf),
Namhyung Kimbea03402012-04-26 14:15:15 +09001553 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001554 "record events on existing process id"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001555 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001556 "record events on existing thread id"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001557 OPT_INTEGER('r', "realtime", &record.realtime_prio,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001558 "collect data with this RT SCHED_FIFO priority"),
Arnaldo Carvalho de Melo509051e2014-01-14 17:52:14 -03001559 OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
Kirill Smelkovacac03f2011-01-12 17:59:36 +03001560 "collect data without buffering"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001561 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
Frederic Weisbeckerdaac07b2009-08-13 10:27:19 +02001562 "collect raw sample records from all opened counters"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001563 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001564 "system-wide collection from all CPUs"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001565 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
Stephane Eranianc45c6ea2010-05-28 12:00:01 +02001566 "list of cpus to monitor"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001567 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
Jiri Olsaf5fc14122013-10-15 16:27:32 +02001568 OPT_STRING('o', "output", &record.file.path, "file",
Ingo Molnarabaff322009-06-02 22:59:57 +02001569 "output file name"),
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001570 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1571 &record.opts.no_inherit_set,
1572 "child tasks do not inherit counters"),
Wang Nan4ea648a2016-07-14 08:34:47 +00001573 OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize,
1574 "synthesize non-sample events at the end of output"),
Wang Nan626a6b72016-07-14 08:34:45 +00001575 OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001576 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
Adrian Huntere9db1312015-04-09 18:53:46 +03001577 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
1578 "number of mmap data pages and AUX area tracing mmap pages",
1579 record__parse_mmap_pages),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001580 OPT_BOOLEAN(0, "group", &record.opts.group,
Lin Ming43bece72011-08-17 18:42:07 +08001581 "put the counters into a counter group"),
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001582 OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001583 NULL, "enables call-graph recording" ,
1584 &record_callchain_opt),
1585 OPT_CALLBACK(0, "call-graph", &record.opts,
Namhyung Kim76a26542015-10-22 23:28:32 +09001586 "record_mode[,record_size]", record_callchain_help,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001587 &record_parse_callchain_opt),
Ian Munsiec0555642010-04-13 18:37:33 +10001588 OPT_INCR('v', "verbose", &verbose,
Ingo Molnar3da297a2009-06-07 17:39:02 +02001589 "be more verbose (show counter open errors, etc)"),
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001590 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001591 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001592 "per thread counts"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001593 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
Jiri Olsab6f35ed2016-08-01 20:02:35 +02001594 OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"),
Adrian Hunter3abebc52015-07-06 14:51:01 +03001595 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
1596 &record.opts.sample_time_set,
1597 "Record the sample timestamps"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001598 OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001599 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001600 "don't sample"),
Wang Nand2db9a92016-01-25 09:56:19 +00001601 OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
1602 &record.no_buildid_cache_set,
1603 "do not update the buildid cache"),
1604 OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
1605 &record.no_buildid_set,
1606 "do not collect buildids in perf.data"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001607 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
Stephane Eranian023695d2011-02-14 11:20:01 +02001608 "monitor event in cgroup name only",
1609 parse_cgroups),
Arnaldo Carvalho de Meloa6205a32014-01-14 17:58:12 -03001610 OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
Andi Kleen6619a532014-01-11 13:38:27 -08001611 "ms to wait before starting measurement after program start"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001612 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
1613 "user to profile"),
Stephane Eraniana5aabda2012-03-08 23:47:45 +01001614
1615 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
1616 "branch any", "sample any taken branches",
1617 parse_branch_stack),
1618
1619 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
1620 "branch filter mask", "branch stack filter modes",
Roberto Agostino Vitillobdfebd82012-02-09 23:21:02 +01001621 parse_branch_stack),
Andi Kleen05484292013-01-24 16:10:29 +01001622 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
1623 "sample by weight (on special events only)"),
Andi Kleen475eeab2013-09-20 07:40:43 -07001624 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
1625 "sample transaction flags (special events only)"),
Adrian Hunter3aa59392013-11-15 15:52:29 +02001626 OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
1627 "use per-thread mmaps"),
Stephane Eranianbcc84ec2015-08-31 18:41:12 +02001628 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
1629 "sample selected machine registers on interrupt,"
1630 " use -I ? to list register names", parse_regs),
Andi Kleen85c273d2015-02-24 15:13:40 -08001631 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
1632 "Record running/enabled time of read (:S) events"),
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001633 OPT_CALLBACK('k', "clockid", &record.opts,
1634 "clockid", "clockid to use for events, see clock_gettime()",
1635 parse_clockid),
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001636 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
1637 "opts", "AUX area tracing Snapshot Mode", ""),
Kan Liang9d9cad72015-06-17 09:51:11 -04001638 OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
1639 "per thread proc mmap processing timeout in ms"),
Hari Bathinif3b36142017-03-08 02:11:43 +05301640 OPT_BOOLEAN(0, "namespaces", &record.opts.record_namespaces,
1641 "Record namespaces events"),
Adrian Hunterb757bb02015-07-21 12:44:04 +03001642 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1643 "Record context switch events"),
Jiri Olsa85723882016-02-15 09:34:31 +01001644 OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
1645 "Configure all used events to run in kernel space.",
1646 PARSE_OPT_EXCLUSIVE),
1647 OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
1648 "Configure all used events to run in user space.",
1649 PARSE_OPT_EXCLUSIVE),
Wang Nan71dc23262015-10-14 12:41:19 +00001650 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1651 "clang binary to use for compiling BPF scriptlets"),
1652 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1653 "options passed to clang when compiling BPF scriptlets"),
He Kuang7efe0e02015-12-14 10:39:23 +00001654 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1655 "file", "vmlinux pathname"),
Namhyung Kim61566812016-01-11 22:37:09 +09001656 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
1657 "Record build-id of all DSOs regardless of hits"),
Wang Nanecfd7a92016-04-13 08:21:07 +00001658 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1659 "append timestamp to output filename"),
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001660 OPT_STRING_OPTARG_SET(0, "switch-output", &record.switch_output.str,
Jiri Olsabfacbe32017-01-09 10:52:00 +01001661 &record.switch_output.set, "signal,size,time",
1662 "Switch output when receive SIGUSR2 or cross size,time threshold",
Jiri Olsadc0c6122017-01-09 10:51:58 +01001663 "signal"),
Wang Nan0aab2132016-06-16 08:02:41 +00001664 OPT_BOOLEAN(0, "dry-run", &dry_run,
1665 "Parse options then exit"),
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001666 OPT_END()
1667};
1668
Namhyung Kime5b2c202014-10-23 00:15:46 +09001669struct option *record_options = __record_options;
1670
Arnaldo Carvalho de Melob0ad8ea2017-03-27 11:47:20 -03001671int cmd_record(int argc, const char **argv)
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001672{
Adrian Hunteref149c22015-04-09 18:53:45 +03001673 int err;
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001674 struct record *rec = &record;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001675 char errbuf[BUFSIZ];
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001676
Wang Nan48e1cab2015-12-14 10:39:22 +00001677#ifndef HAVE_LIBBPF_SUPPORT
1678# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
1679 set_nobuild('\0', "clang-path", true);
1680 set_nobuild('\0', "clang-opt", true);
1681# undef set_nobuild
1682#endif
1683
He Kuang7efe0e02015-12-14 10:39:23 +00001684#ifndef HAVE_BPF_PROLOGUE
1685# if !defined (HAVE_DWARF_SUPPORT)
1686# define REASON "NO_DWARF=1"
1687# elif !defined (HAVE_LIBBPF_SUPPORT)
1688# define REASON "NO_LIBBPF=1"
1689# else
1690# define REASON "this architecture doesn't support BPF prologue"
1691# endif
1692# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
1693 set_nobuild('\0', "vmlinux", true);
1694# undef set_nobuild
1695# undef REASON
1696#endif
1697
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001698 rec->evlist = perf_evlist__new();
1699 if (rec->evlist == NULL)
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -02001700 return -ENOMEM;
1701
Arnaldo Carvalho de Meloecc4c562017-01-24 13:44:10 -03001702 err = perf_config(perf_record_config, rec);
1703 if (err)
1704 return err;
Jiri Olsaeb853e82014-02-03 12:44:42 +01001705
Tom Zanussibca647a2010-11-10 08:11:30 -06001706 argc = parse_options(argc, argv, record_options, record_usage,
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001707 PARSE_OPT_STOP_AT_NON_OPTION);
Namhyung Kim68ba3232017-02-17 17:17:42 +09001708 if (quiet)
1709 perf_quiet_option();
Jiri Olsa483635a2017-02-17 18:00:18 +01001710
1711 /* Make system wide (-a) the default target. */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001712 if (!argc && target__none(&rec->opts.target))
Jiri Olsa483635a2017-02-17 18:00:18 +01001713 rec->opts.target.system_wide = true;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001714
Namhyung Kimbea03402012-04-26 14:15:15 +09001715 if (nr_cgroups && !rec->opts.target.system_wide) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001716 usage_with_options_msg(record_usage, record_options,
1717 "cgroup monitoring only available in system-wide mode");
1718
Stephane Eranian023695d2011-02-14 11:20:01 +02001719 }
Adrian Hunterb757bb02015-07-21 12:44:04 +03001720 if (rec->opts.record_switch_events &&
1721 !perf_can_record_switch_events()) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001722 ui__error("kernel does not support recording context switch events\n");
1723 parse_options_usage(record_usage, record_options, "switch-events", 0);
1724 return -EINVAL;
Adrian Hunterb757bb02015-07-21 12:44:04 +03001725 }
Stephane Eranian023695d2011-02-14 11:20:01 +02001726
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01001727 if (switch_output_setup(rec)) {
1728 parse_options_usage(record_usage, record_options, "switch-output", 0);
1729 return -EINVAL;
1730 }
1731
Jiri Olsabfacbe32017-01-09 10:52:00 +01001732 if (rec->switch_output.time) {
1733 signal(SIGALRM, alarm_sig_handler);
1734 alarm(rec->switch_output.time);
1735 }
1736
Adrian Hunteref149c22015-04-09 18:53:45 +03001737 if (!rec->itr) {
1738 rec->itr = auxtrace_record__init(rec->evlist, &err);
1739 if (err)
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001740 goto out;
Adrian Hunteref149c22015-04-09 18:53:45 +03001741 }
1742
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001743 err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
1744 rec->opts.auxtrace_snapshot_opts);
1745 if (err)
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001746 goto out;
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001747
Adrian Hunter1b36c032016-09-23 17:38:39 +03001748 /*
1749 * Allow aliases to facilitate the lookup of symbols for address
1750 * filters. Refer to auxtrace_parse_filters().
1751 */
1752 symbol_conf.allow_aliases = true;
1753
1754 symbol__init(NULL);
1755
1756 err = auxtrace_parse_filters(rec->evlist);
1757 if (err)
1758 goto out;
1759
Wang Nan0aab2132016-06-16 08:02:41 +00001760 if (dry_run)
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001761 goto out;
Wang Nan0aab2132016-06-16 08:02:41 +00001762
Wang Nand7888572016-04-08 15:07:24 +00001763 err = bpf__setup_stdout(rec->evlist);
1764 if (err) {
1765 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
1766 pr_err("ERROR: Setup BPF stdout failed: %s\n",
1767 errbuf);
Adrian Hunter5c01ad602016-09-23 17:38:37 +03001768 goto out;
Wang Nand7888572016-04-08 15:07:24 +00001769 }
1770
Adrian Hunteref149c22015-04-09 18:53:45 +03001771 err = -ENOMEM;
1772
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001773 if (symbol_conf.kptr_restrict)
Arnaldo Carvalho de Melo646aaea2011-05-27 11:00:41 -03001774 pr_warning(
1775"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
1776"check /proc/sys/kernel/kptr_restrict.\n\n"
1777"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
1778"file is not found in the buildid cache or in the vmlinux path.\n\n"
1779"Samples in kernel modules won't be resolved at all.\n\n"
1780"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
1781"even with a suitable vmlinux or kallsyms file.\n\n");
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001782
Wang Nan0c1d46a2016-04-20 18:59:52 +00001783 if (rec->no_buildid_cache || rec->no_buildid) {
Stephane Eraniana1ac1d32010-06-17 11:39:01 +02001784 disable_buildid_cache();
Jiri Olsadc0c6122017-01-09 10:51:58 +01001785 } else if (rec->switch_output.enabled) {
Wang Nan0c1d46a2016-04-20 18:59:52 +00001786 /*
1787 * In 'perf record --switch-output', disable buildid
1788 * generation by default to reduce data file switching
1789 * overhead. Still generate buildid if they are required
1790 * explicitly using
1791 *
Jiri Olsa60437ac2017-01-03 09:19:56 +01001792 * perf record --switch-output --no-no-buildid \
Wang Nan0c1d46a2016-04-20 18:59:52 +00001793 * --no-no-buildid-cache
1794 *
1795 * Following code equals to:
1796 *
1797 * if ((rec->no_buildid || !rec->no_buildid_set) &&
1798 * (rec->no_buildid_cache || !rec->no_buildid_cache_set))
1799 * disable_buildid_cache();
1800 */
1801 bool disable = true;
1802
1803 if (rec->no_buildid_set && !rec->no_buildid)
1804 disable = false;
1805 if (rec->no_buildid_cache_set && !rec->no_buildid_cache)
1806 disable = false;
1807 if (disable) {
1808 rec->no_buildid = true;
1809 rec->no_buildid_cache = true;
1810 disable_buildid_cache();
1811 }
1812 }
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001813
Wang Nan4ea648a2016-07-14 08:34:47 +00001814 if (record.opts.overwrite)
1815 record.opts.tail_synthesize = true;
1816
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001817 if (rec->evlist->nr_entries == 0 &&
1818 perf_evlist__add_default(rec->evlist) < 0) {
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001819 pr_err("Not enough memory for event selector list\n");
Adrian Hunter394c01e2016-09-23 17:38:36 +03001820 goto out;
Peter Zijlstrabbd36e52009-06-11 23:11:50 +02001821 }
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001822
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001823 if (rec->opts.target.tid && !rec->opts.no_inherit_set)
1824 rec->opts.no_inherit = true;
1825
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001826 err = target__validate(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001827 if (err) {
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001828 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001829 ui__warning("%s", errbuf);
1830 }
Namhyung Kim4bd0f2d2012-04-26 14:15:18 +09001831
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001832 err = target__parse_uid(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001833 if (err) {
1834 int saved_errno = errno;
1835
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001836 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim3780f482012-05-29 13:22:57 +09001837 ui__error("%s", errbuf);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001838
1839 err = -saved_errno;
Adrian Hunter394c01e2016-09-23 17:38:36 +03001840 goto out;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001841 }
Arnaldo Carvalho de Melo0d37aa32012-01-19 14:08:15 -02001842
Jiri Olsa23dc4f12016-12-12 11:35:43 +01001843 /* Enable ignoring missing threads when -u option is defined. */
1844 rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX;
1845
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001846 err = -ENOMEM;
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001847 if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -02001848 usage_with_options(record_usage, record_options);
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001849
Adrian Hunteref149c22015-04-09 18:53:45 +03001850 err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
1851 if (err)
Adrian Hunter394c01e2016-09-23 17:38:36 +03001852 goto out;
Adrian Hunteref149c22015-04-09 18:53:45 +03001853
Namhyung Kim61566812016-01-11 22:37:09 +09001854 /*
1855 * We take all buildids when the file contains
1856 * AUX area tracing data because we do not decode the
1857 * trace because it would take too long.
1858 */
1859 if (rec->opts.full_auxtrace)
1860 rec->buildid_all = true;
1861
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001862 if (record_opts__config(&rec->opts)) {
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001863 err = -EINVAL;
Adrian Hunter394c01e2016-09-23 17:38:36 +03001864 goto out;
Mike Galbraith7e4ff9e2009-10-12 07:56:03 +02001865 }
1866
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001867 err = __cmd_record(&record, argc, argv);
Adrian Hunter394c01e2016-09-23 17:38:36 +03001868out:
Namhyung Kim45604712014-05-12 09:47:24 +09001869 perf_evlist__delete(rec->evlist);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03001870 symbol__exit();
Adrian Hunteref149c22015-04-09 18:53:45 +03001871 auxtrace_record__free(rec->itr);
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001872 return err;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001873}
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001874
1875static void snapshot_sig_handler(int sig __maybe_unused)
1876{
Jiri Olsadc0c6122017-01-09 10:51:58 +01001877 struct record *rec = &record;
1878
Wang Nan5f9cf592016-04-20 18:59:49 +00001879 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1880 trigger_hit(&auxtrace_snapshot_trigger);
1881 auxtrace_record__snapshot_started = 1;
1882 if (auxtrace_record__snapshot_start(record.itr))
1883 trigger_error(&auxtrace_snapshot_trigger);
1884 }
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001885
Jiri Olsadc0c6122017-01-09 10:51:58 +01001886 if (switch_output_signal(rec))
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001887 trigger_hit(&switch_output_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001888}
Jiri Olsabfacbe32017-01-09 10:52:00 +01001889
1890static void alarm_sig_handler(int sig __maybe_unused)
1891{
1892 struct record *rec = &record;
1893
1894 if (switch_output_time(rec))
1895 trigger_hit(&switch_output_trigger);
1896}