blob: f302cc937ca5bdd71af98e9747749eebe939723f [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"
Thomas Gleixner6eda5832009-05-01 18:29:57 +020016
Arnaldo Carvalho de Melo8f651ea2014-10-09 16:12:24 -030017#include "util/callchain.h"
Arnaldo Carvalho de Melof14d5702014-10-17 12:17:40 -030018#include "util/cgroup.h"
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +020019#include "util/header.h"
Frederic Weisbecker66e274f2009-08-12 11:07:25 +020020#include "util/event.h"
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -020021#include "util/evlist.h"
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -020022#include "util/evsel.h"
Frederic Weisbecker8f288272009-08-16 22:05:48 +020023#include "util/debug.h"
Arnaldo Carvalho de Melo94c744b2009-12-11 21:24:02 -020024#include "util/session.h"
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020025#include "util/tool.h"
Arnaldo Carvalho de Melo8d063672009-11-04 18:50:43 -020026#include "util/symbol.h"
Paul Mackerrasa12b51c2010-03-10 20:36:09 +110027#include "util/cpumap.h"
Arnaldo Carvalho de Melofd782602011-01-18 15:15:24 -020028#include "util/thread_map.h"
Jiri Olsaf5fc1412013-10-15 16:27:32 +020029#include "util/data.h"
Stephane Eranianbcc84ec2015-08-31 18:41:12 +020030#include "util/perf_regs.h"
Adrian Hunteref149c22015-04-09 18:53:45 +030031#include "util/auxtrace.h"
Adrian Hunter46bc29b2016-03-08 10:38:44 +020032#include "util/tsc.h"
Andi Kleenf00898f2015-05-27 10:51:51 -070033#include "util/parse-branch-options.h"
Stephane Eranianbcc84ec2015-08-31 18:41:12 +020034#include "util/parse-regs-options.h"
Wang Nan71dc23262015-10-14 12:41:19 +000035#include "util/llvm-utils.h"
Wang Nan8690a2a2016-02-22 09:10:32 +000036#include "util/bpf-loader.h"
Wang Nan5f9cf592016-04-20 18:59:49 +000037#include "util/trigger.h"
Wang Nand8871ea2016-02-26 09:32:06 +000038#include "asm/bug.h"
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +020039
Peter Zijlstra97124d52009-06-02 15:52:24 +020040#include <unistd.h>
Peter Zijlstrade9ac072009-04-08 15:01:31 +020041#include <sched.h>
Arnaldo Carvalho de Meloa41794c2010-05-18 18:29:23 -030042#include <sys/mman.h>
Wang Nan2d11c652016-05-23 07:13:39 +000043#include <asm/bug.h>
Peter Zijlstrade9ac072009-04-08 15:01:31 +020044
Bernhard Rosenkraenzer78da39f2012-10-08 09:43:26 +030045
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -030046struct record {
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020047 struct perf_tool tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -030048 struct record_opts opts;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020049 u64 bytes_written;
Jiri Olsaf5fc1412013-10-15 16:27:32 +020050 struct perf_data_file file;
Adrian Hunteref149c22015-04-09 18:53:45 +030051 struct auxtrace_record *itr;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020052 struct perf_evlist *evlist;
53 struct perf_session *session;
54 const char *progname;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020055 int realtime_prio;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020056 bool no_buildid;
Wang Nand2db9a92016-01-25 09:56:19 +000057 bool no_buildid_set;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020058 bool no_buildid_cache;
Wang Nand2db9a92016-01-25 09:56:19 +000059 bool no_buildid_cache_set;
Namhyung Kim61566812016-01-11 22:37:09 +090060 bool buildid_all;
Wang Nanecfd7a92016-04-13 08:21:07 +000061 bool timestamp_filename;
Wang Nan3c1cb7e2016-04-20 18:59:50 +000062 bool switch_output;
Yang Shi9f065192015-09-29 14:49:43 -070063 unsigned long long samples;
Arnaldo Carvalho de Melo0f82ebc2011-11-08 14:41:57 -020064};
Ingo Molnara21ca2c2009-06-06 09:58:57 +020065
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -030066static int record__write(struct record *rec, void *bf, size_t size)
Peter Zijlstraf5970552009-06-18 23:22:55 +020067{
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -030068 if (perf_data_file__write(rec->session->file, bf, size) < 0) {
Jiri Olsa50a9b862013-11-22 13:11:24 +010069 pr_err("failed to write perf data, error: %m\n");
70 return -1;
Peter Zijlstraf5970552009-06-18 23:22:55 +020071 }
David Ahern8d3eca22012-08-26 12:24:47 -060072
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -030073 rec->bytes_written += size;
David Ahern8d3eca22012-08-26 12:24:47 -060074 return 0;
Peter Zijlstraf5970552009-06-18 23:22:55 +020075}
76
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020077static int process_synthesized_event(struct perf_tool *tool,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020078 union perf_event *event,
Irina Tirdea1d037ca2012-09-11 01:15:03 +030079 struct perf_sample *sample __maybe_unused,
80 struct machine *machine __maybe_unused)
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -020081{
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -030082 struct record *rec = container_of(tool, struct record, tool);
83 return record__write(rec, event, event->header.size);
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -020084}
85
Arnaldo Carvalho de Meloe5685732014-09-17 16:42:58 -030086static int record__mmap_read(struct record *rec, int idx)
Peter Zijlstrade9ac072009-04-08 15:01:31 +020087{
Arnaldo Carvalho de Meloe5685732014-09-17 16:42:58 -030088 struct perf_mmap *md = &rec->evlist->mmap[idx];
David Ahern7b8283b52015-04-07 09:20:37 -060089 u64 head = perf_mmap__read_head(md);
90 u64 old = md->prev;
Jiri Olsa918512b2013-09-12 18:39:35 +020091 unsigned char *data = md->base + page_size;
Peter Zijlstrade9ac072009-04-08 15:01:31 +020092 unsigned long size;
93 void *buf;
David Ahern8d3eca22012-08-26 12:24:47 -060094 int rc = 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +020095
Arnaldo Carvalho de Melodc820092011-01-28 14:49:19 -020096 if (old == head)
David Ahern8d3eca22012-08-26 12:24:47 -060097 return 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +020098
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020099 rec->samples++;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200100
101 size = head - old;
Wang Nan2d11c652016-05-23 07:13:39 +0000102 if (size > (unsigned long)(md->mask) + 1) {
103 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
104
105 md->prev = head;
106 perf_evlist__mmap_consume(rec->evlist, idx);
107 return 0;
108 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200109
110 if ((old & md->mask) + size != (head & md->mask)) {
111 buf = &data[old & md->mask];
112 size = md->mask + 1 - (old & md->mask);
113 old += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200114
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300115 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600116 rc = -1;
117 goto out;
118 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200119 }
120
121 buf = &data[old & md->mask];
122 size = head - old;
123 old += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200124
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300125 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600126 rc = -1;
127 goto out;
128 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200129
130 md->prev = old;
Arnaldo Carvalho de Meloe5685732014-09-17 16:42:58 -0300131 perf_evlist__mmap_consume(rec->evlist, idx);
David Ahern8d3eca22012-08-26 12:24:47 -0600132out:
133 return rc;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200134}
135
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300136static volatile int done;
137static volatile int signr = -1;
138static volatile int child_finished;
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000139
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300140static volatile int auxtrace_record__snapshot_started;
Wang Nan5f9cf592016-04-20 18:59:49 +0000141static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000142static DEFINE_TRIGGER(switch_output_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300143
144static void sig_handler(int sig)
145{
146 if (sig == SIGCHLD)
147 child_finished = 1;
148 else
149 signr = sig;
150
151 done = 1;
152}
153
154static void record__sig_exit(void)
155{
156 if (signr == -1)
157 return;
158
159 signal(signr, SIG_DFL);
160 raise(signr);
161}
162
Adrian Huntere31f0d02015-04-30 17:37:27 +0300163#ifdef HAVE_AUXTRACE_SUPPORT
164
Adrian Hunteref149c22015-04-09 18:53:45 +0300165static int record__process_auxtrace(struct perf_tool *tool,
166 union perf_event *event, void *data1,
167 size_t len1, void *data2, size_t len2)
168{
169 struct record *rec = container_of(tool, struct record, tool);
Adrian Hunter99fa2982015-04-30 17:37:25 +0300170 struct perf_data_file *file = &rec->file;
Adrian Hunteref149c22015-04-09 18:53:45 +0300171 size_t padding;
172 u8 pad[8] = {0};
173
Adrian Hunter99fa2982015-04-30 17:37:25 +0300174 if (!perf_data_file__is_pipe(file)) {
175 off_t file_offset;
176 int fd = perf_data_file__fd(file);
177 int err;
178
179 file_offset = lseek(fd, 0, SEEK_CUR);
180 if (file_offset == -1)
181 return -1;
182 err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index,
183 event, file_offset);
184 if (err)
185 return err;
186 }
187
Adrian Hunteref149c22015-04-09 18:53:45 +0300188 /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */
189 padding = (len1 + len2) & 7;
190 if (padding)
191 padding = 8 - padding;
192
193 record__write(rec, event, event->header.size);
194 record__write(rec, data1, len1);
195 if (len2)
196 record__write(rec, data2, len2);
197 record__write(rec, &pad, padding);
198
199 return 0;
200}
201
202static int record__auxtrace_mmap_read(struct record *rec,
203 struct auxtrace_mmap *mm)
204{
205 int ret;
206
207 ret = auxtrace_mmap__read(mm, rec->itr, &rec->tool,
208 record__process_auxtrace);
209 if (ret < 0)
210 return ret;
211
212 if (ret)
213 rec->samples++;
214
215 return 0;
216}
217
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300218static int record__auxtrace_mmap_read_snapshot(struct record *rec,
219 struct auxtrace_mmap *mm)
220{
221 int ret;
222
223 ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool,
224 record__process_auxtrace,
225 rec->opts.auxtrace_snapshot_size);
226 if (ret < 0)
227 return ret;
228
229 if (ret)
230 rec->samples++;
231
232 return 0;
233}
234
235static int record__auxtrace_read_snapshot_all(struct record *rec)
236{
237 int i;
238 int rc = 0;
239
240 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
241 struct auxtrace_mmap *mm =
242 &rec->evlist->mmap[i].auxtrace_mmap;
243
244 if (!mm->base)
245 continue;
246
247 if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) {
248 rc = -1;
249 goto out;
250 }
251 }
252out:
253 return rc;
254}
255
256static void record__read_auxtrace_snapshot(struct record *rec)
257{
258 pr_debug("Recording AUX area tracing snapshot\n");
259 if (record__auxtrace_read_snapshot_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000260 trigger_error(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300261 } else {
Wang Nan5f9cf592016-04-20 18:59:49 +0000262 if (auxtrace_record__snapshot_finish(rec->itr))
263 trigger_error(&auxtrace_snapshot_trigger);
264 else
265 trigger_ready(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300266 }
267}
268
Adrian Huntere31f0d02015-04-30 17:37:27 +0300269#else
270
271static inline
272int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
273 struct auxtrace_mmap *mm __maybe_unused)
274{
275 return 0;
276}
277
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300278static inline
279void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
280{
281}
282
283static inline
284int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
285{
286 return 0;
287}
288
Adrian Huntere31f0d02015-04-30 17:37:27 +0300289#endif
290
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300291static int record__open(struct record *rec)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200292{
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300293 char msg[512];
Jiri Olsa6a4bb042012-08-08 12:22:36 +0200294 struct perf_evsel *pos;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200295 struct perf_evlist *evlist = rec->evlist;
296 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300297 struct record_opts *opts = &rec->opts;
David Ahern8d3eca22012-08-26 12:24:47 -0600298 int rc = 0;
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200299
Arnaldo Carvalho de Meloe68ae9c2016-04-11 18:15:29 -0300300 perf_evlist__config(evlist, opts, &callchain_param);
Jiri Olsacac21422012-11-12 18:34:00 +0100301
Arnaldo Carvalho de Melo0050f7a2014-01-10 10:37:27 -0300302 evlist__for_each(evlist, pos) {
Ingo Molnar3da297a2009-06-07 17:39:02 +0200303try_again:
Kan Liangd988d5e2015-08-21 02:23:14 -0400304 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300305 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300306 if (verbose)
Arnaldo Carvalho de Meloc0a54342012-12-13 14:16:30 -0300307 ui__warning("%s\n", msg);
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300308 goto try_again;
309 }
David Ahernca6a4252011-03-25 13:11:11 -0600310
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300311 rc = -errno;
312 perf_evsel__open_strerror(pos, &opts->target,
313 errno, msg, sizeof(msg));
314 ui__error("%s\n", msg);
David Ahern8d3eca22012-08-26 12:24:47 -0600315 goto out;
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300316 }
Li Zefanc171b552009-10-15 11:22:07 +0800317 }
Arnaldo Carvalho de Meloa43d3f02010-12-25 12:12:25 -0200318
Arnaldo Carvalho de Melo23d4aad2015-03-24 19:23:47 -0300319 if (perf_evlist__apply_filters(evlist, &pos)) {
320 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
321 pos->filter, perf_evsel__name(pos), errno,
Masami Hiramatsu35550da2014-08-14 02:22:43 +0000322 strerror_r(errno, msg, sizeof(msg)));
David Ahern8d3eca22012-08-26 12:24:47 -0600323 rc = -1;
324 goto out;
Frederic Weisbecker0a102472011-02-26 04:51:54 +0100325 }
326
Adrian Hunteref149c22015-04-09 18:53:45 +0300327 if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300328 opts->auxtrace_mmap_pages,
329 opts->auxtrace_snapshot_mode) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600330 if (errno == EPERM) {
331 pr_err("Permission error mapping pages.\n"
332 "Consider increasing "
333 "/proc/sys/kernel/perf_event_mlock_kb,\n"
334 "or try again with a smaller value of -m/--mmap_pages.\n"
Adrian Hunteref149c22015-04-09 18:53:45 +0300335 "(current value: %u,%u)\n",
336 opts->mmap_pages, opts->auxtrace_mmap_pages);
David Ahern8d3eca22012-08-26 12:24:47 -0600337 rc = -errno;
David Ahern8d3eca22012-08-26 12:24:47 -0600338 } else {
Masami Hiramatsu35550da2014-08-14 02:22:43 +0000339 pr_err("failed to mmap with %d (%s)\n", errno,
340 strerror_r(errno, msg, sizeof(msg)));
Wang Nan95c36562016-02-26 09:32:17 +0000341 if (errno)
342 rc = -errno;
343 else
344 rc = -EINVAL;
David Ahern8d3eca22012-08-26 12:24:47 -0600345 }
346 goto out;
Nelson Elhage18e60932011-12-19 08:39:31 -0500347 }
Arnaldo Carvalho de Melo0a27d7f2011-01-14 15:50:51 -0200348
Jiri Olsa563aecb2013-06-05 13:35:06 +0200349 session->evlist = evlist;
Arnaldo Carvalho de Melo7b56cce2012-08-01 19:31:00 -0300350 perf_session__set_id_hdr_size(session);
David Ahern8d3eca22012-08-26 12:24:47 -0600351out:
352 return rc;
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200353}
354
Namhyung Kime3d59112015-01-29 17:06:44 +0900355static int process_sample_event(struct perf_tool *tool,
356 union perf_event *event,
357 struct perf_sample *sample,
358 struct perf_evsel *evsel,
359 struct machine *machine)
360{
361 struct record *rec = container_of(tool, struct record, tool);
362
363 rec->samples++;
364
365 return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
366}
367
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300368static int process_buildids(struct record *rec)
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200369{
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200370 struct perf_data_file *file = &rec->file;
371 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200372
He Kuang457ae942015-05-28 13:17:30 +0000373 if (file->size == 0)
Arnaldo Carvalho de Melo9f591fd2010-03-11 15:53:11 -0300374 return 0;
375
Namhyung Kim00dc8652014-11-04 10:14:32 +0900376 /*
377 * During this process, it'll load kernel map and replace the
378 * dso->long_name to a real pathname it found. In this case
379 * we prefer the vmlinux path like
380 * /lib/modules/3.16.4/build/vmlinux
381 *
382 * rather than build-id path (in debug directory).
383 * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551
384 */
385 symbol_conf.ignore_vmlinux_buildid = true;
386
Namhyung Kim61566812016-01-11 22:37:09 +0900387 /*
388 * If --buildid-all is given, it marks all DSO regardless of hits,
389 * so no need to process samples.
390 */
391 if (rec->buildid_all)
392 rec->tool.sample = NULL;
393
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300394 return perf_session__process_events(session);
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200395}
396
Arnaldo Carvalho de Melo8115d602011-01-29 14:01:45 -0200397static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800398{
399 int err;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200400 struct perf_tool *tool = data;
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800401 /*
402 *As for guest kernel when processing subcommand record&report,
403 *we arrange module mmap prior to guest kernel mmap and trigger
404 *a preload dso because default guest module symbols are loaded
405 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
406 *method is used to avoid symbol missing when the first addr is
407 *in module instead of in guest kernel.
408 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200409 err = perf_event__synthesize_modules(tool, process_synthesized_event,
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200410 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800411 if (err < 0)
412 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300413 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800414
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800415 /*
416 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
417 * have no _text sometimes.
418 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200419 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
Adrian Hunter0ae617b2014-01-29 16:14:40 +0200420 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800421 if (err < 0)
422 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300423 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800424}
425
Frederic Weisbecker98402802010-05-02 22:05:29 +0200426static struct perf_event_header finished_round_event = {
427 .size = sizeof(struct perf_event_header),
428 .type = PERF_RECORD_FINISHED_ROUND,
429};
430
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300431static int record__mmap_read_all(struct record *rec)
Frederic Weisbecker98402802010-05-02 22:05:29 +0200432{
Jiri Olsadcabb502014-07-25 16:56:16 +0200433 u64 bytes_written = rec->bytes_written;
Peter Zijlstra0e2e63d2010-05-20 14:45:26 +0200434 int i;
David Ahern8d3eca22012-08-26 12:24:47 -0600435 int rc = 0;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200436
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200437 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
Adrian Hunteref149c22015-04-09 18:53:45 +0300438 struct auxtrace_mmap *mm = &rec->evlist->mmap[i].auxtrace_mmap;
439
David Ahern8d3eca22012-08-26 12:24:47 -0600440 if (rec->evlist->mmap[i].base) {
Arnaldo Carvalho de Meloe5685732014-09-17 16:42:58 -0300441 if (record__mmap_read(rec, i) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600442 rc = -1;
443 goto out;
444 }
445 }
Adrian Hunteref149c22015-04-09 18:53:45 +0300446
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300447 if (mm->base && !rec->opts.auxtrace_snapshot_mode &&
Adrian Hunteref149c22015-04-09 18:53:45 +0300448 record__auxtrace_mmap_read(rec, mm) != 0) {
449 rc = -1;
450 goto out;
451 }
Frederic Weisbecker98402802010-05-02 22:05:29 +0200452 }
453
Jiri Olsadcabb502014-07-25 16:56:16 +0200454 /*
455 * Mark the round finished in case we wrote
456 * at least one event.
457 */
458 if (bytes_written != rec->bytes_written)
459 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
David Ahern8d3eca22012-08-26 12:24:47 -0600460
461out:
462 return rc;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200463}
464
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300465static void record__init_features(struct record *rec)
David Ahern57706ab2013-11-06 11:41:34 -0700466{
David Ahern57706ab2013-11-06 11:41:34 -0700467 struct perf_session *session = rec->session;
468 int feat;
469
470 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
471 perf_header__set_feat(&session->header, feat);
472
473 if (rec->no_buildid)
474 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
475
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300476 if (!have_tracepoints(&rec->evlist->entries))
David Ahern57706ab2013-11-06 11:41:34 -0700477 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
478
479 if (!rec->opts.branch_stack)
480 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
Adrian Hunteref149c22015-04-09 18:53:45 +0300481
482 if (!rec->opts.full_auxtrace)
483 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
Jiri Olsaffa517a2015-10-25 15:51:43 +0100484
485 perf_header__clear_feat(&session->header, HEADER_STAT);
David Ahern57706ab2013-11-06 11:41:34 -0700486}
487
Wang Nane1ab48b2016-02-26 09:32:10 +0000488static void
489record__finish_output(struct record *rec)
490{
491 struct perf_data_file *file = &rec->file;
492 int fd = perf_data_file__fd(file);
493
494 if (file->is_pipe)
495 return;
496
497 rec->session->header.data_size += rec->bytes_written;
498 file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR);
499
500 if (!rec->no_buildid) {
501 process_buildids(rec);
502
503 if (rec->buildid_all)
504 dsos__hit_all(rec->session);
505 }
506 perf_session__write_header(rec->session, rec->evlist, fd, true);
507
508 return;
509}
510
Wang Nanbe7b0c92016-04-20 18:59:54 +0000511static int record__synthesize_workload(struct record *rec)
512{
513 struct {
514 struct thread_map map;
515 struct thread_map_data map_data;
516 } thread_map;
517
518 thread_map.map.nr = 1;
519 thread_map.map.map[0].pid = rec->evlist->workload.pid;
520 thread_map.map.map[0].comm = NULL;
521 return perf_event__synthesize_thread_map(&rec->tool, &thread_map.map,
522 process_synthesized_event,
523 &rec->session->machines.host,
524 rec->opts.sample_address,
525 rec->opts.proc_map_timeout);
526}
527
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000528static int record__synthesize(struct record *rec);
529
Wang Nanecfd7a92016-04-13 08:21:07 +0000530static int
531record__switch_output(struct record *rec, bool at_exit)
532{
533 struct perf_data_file *file = &rec->file;
534 int fd, err;
535
536 /* Same Size: "2015122520103046"*/
537 char timestamp[] = "InvalidTimestamp";
538
539 rec->samples = 0;
540 record__finish_output(rec);
541 err = fetch_current_timestamp(timestamp, sizeof(timestamp));
542 if (err) {
543 pr_err("Failed to get current timestamp\n");
544 return -EINVAL;
545 }
546
547 fd = perf_data_file__switch(file, timestamp,
548 rec->session->header.data_offset,
549 at_exit);
550 if (fd >= 0 && !at_exit) {
551 rec->bytes_written = 0;
552 rec->session->header.data_size = 0;
553 }
554
555 if (!quiet)
556 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
557 file->path, timestamp);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000558
559 /* Output tracking events */
Wang Nanbe7b0c92016-04-20 18:59:54 +0000560 if (!at_exit) {
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000561 record__synthesize(rec);
562
Wang Nanbe7b0c92016-04-20 18:59:54 +0000563 /*
564 * In 'perf record --switch-output' without -a,
565 * record__synthesize() in record__switch_output() won't
566 * generate tracking events because there's no thread_map
567 * in evlist. Which causes newly created perf.data doesn't
568 * contain map and comm information.
569 * Create a fake thread_map and directly call
570 * perf_event__synthesize_thread_map() for those events.
571 */
572 if (target__none(&rec->opts.target))
573 record__synthesize_workload(rec);
574 }
Wang Nanecfd7a92016-04-13 08:21:07 +0000575 return fd;
576}
577
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300578static volatile int workload_exec_errno;
579
580/*
581 * perf_evlist__prepare_workload will send a SIGUSR1
582 * if the fork fails, since we asked by setting its
583 * want_signal to true.
584 */
Namhyung Kim45604712014-05-12 09:47:24 +0900585static void workload_exec_failed_signal(int signo __maybe_unused,
586 siginfo_t *info,
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300587 void *ucontext __maybe_unused)
588{
589 workload_exec_errno = info->si_value.sival_int;
590 done = 1;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300591 child_finished = 1;
592}
593
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300594static void snapshot_sig_handler(int sig);
595
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200596int __weak
597perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
598 struct perf_tool *tool __maybe_unused,
599 perf_event__handler_t process __maybe_unused,
600 struct machine *machine __maybe_unused)
601{
602 return 0;
603}
604
Wang Nanc45c86e2016-02-26 09:32:07 +0000605static int record__synthesize(struct record *rec)
606{
607 struct perf_session *session = rec->session;
608 struct machine *machine = &session->machines.host;
609 struct perf_data_file *file = &rec->file;
610 struct record_opts *opts = &rec->opts;
611 struct perf_tool *tool = &rec->tool;
612 int fd = perf_data_file__fd(file);
613 int err = 0;
614
615 if (file->is_pipe) {
616 err = perf_event__synthesize_attrs(tool, session,
617 process_synthesized_event);
618 if (err < 0) {
619 pr_err("Couldn't synthesize attrs.\n");
620 goto out;
621 }
622
623 if (have_tracepoints(&rec->evlist->entries)) {
624 /*
625 * FIXME err <= 0 here actually means that
626 * there were no tracepoints so its not really
627 * an error, just that we don't need to
628 * synthesize anything. We really have to
629 * return this more properly and also
630 * propagate errors that now are calling die()
631 */
632 err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
633 process_synthesized_event);
634 if (err <= 0) {
635 pr_err("Couldn't record tracing data.\n");
636 goto out;
637 }
638 rec->bytes_written += err;
639 }
640 }
641
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200642 err = perf_event__synth_time_conv(rec->evlist->mmap[0].base, tool,
643 process_synthesized_event, machine);
644 if (err)
645 goto out;
646
Wang Nanc45c86e2016-02-26 09:32:07 +0000647 if (rec->opts.full_auxtrace) {
648 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
649 session, process_synthesized_event);
650 if (err)
651 goto out;
652 }
653
654 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
655 machine);
656 WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
657 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
658 "Check /proc/kallsyms permission or run as root.\n");
659
660 err = perf_event__synthesize_modules(tool, process_synthesized_event,
661 machine);
662 WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
663 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
664 "Check /proc/modules permission or run as root.\n");
665
666 if (perf_guest) {
667 machines__process_guests(&session->machines,
668 perf_event__synthesize_guest_os, tool);
669 }
670
671 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
672 process_synthesized_event, opts->sample_address,
673 opts->proc_map_timeout);
674out:
675 return err;
676}
677
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300678static int __cmd_record(struct record *rec, int argc, const char **argv)
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200679{
David Ahern57706ab2013-11-06 11:41:34 -0700680 int err;
Namhyung Kim45604712014-05-12 09:47:24 +0900681 int status = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200682 unsigned long waking = 0;
Zhang, Yanmin46be6042010-03-18 11:36:04 -0300683 const bool forks = argc > 0;
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300684 struct machine *machine;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200685 struct perf_tool *tool = &rec->tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300686 struct record_opts *opts = &rec->opts;
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200687 struct perf_data_file *file = &rec->file;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200688 struct perf_session *session;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300689 bool disabled = false, draining = false;
Namhyung Kim42aa2762015-01-29 17:06:48 +0900690 int fd;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200691
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200692 rec->progname = argv[0];
Andi Kleen33e49ea2011-09-15 14:31:40 -0700693
Namhyung Kim45604712014-05-12 09:47:24 +0900694 atexit(record__sig_exit);
Peter Zijlstraf5970552009-06-18 23:22:55 +0200695 signal(SIGCHLD, sig_handler);
696 signal(SIGINT, sig_handler);
David Ahern804f7ac2013-05-06 12:24:23 -0600697 signal(SIGTERM, sig_handler);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000698
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000699 if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300700 signal(SIGUSR2, snapshot_sig_handler);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000701 if (rec->opts.auxtrace_snapshot_mode)
702 trigger_on(&auxtrace_snapshot_trigger);
703 if (rec->switch_output)
704 trigger_on(&switch_output_trigger);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000705 } else {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300706 signal(SIGUSR2, SIG_IGN);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000707 }
Peter Zijlstraf5970552009-06-18 23:22:55 +0200708
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300709 session = perf_session__new(file, false, tool);
Arnaldo Carvalho de Melo94c744b2009-12-11 21:24:02 -0200710 if (session == NULL) {
Adrien BAKffa91882014-04-18 11:00:43 +0900711 pr_err("Perf session creation failed.\n");
Arnaldo Carvalho de Meloa9a70bb2009-11-17 01:18:11 -0200712 return -1;
713 }
714
Namhyung Kim42aa2762015-01-29 17:06:48 +0900715 fd = perf_data_file__fd(file);
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200716 rec->session = session;
717
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300718 record__init_features(rec);
Stephane Eranian330aa672012-03-08 23:47:46 +0100719
Arnaldo Carvalho de Melod4db3f12009-12-27 21:36:57 -0200720 if (forks) {
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300721 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200722 argv, file->is_pipe,
Arnaldo Carvalho de Melo735f7e02014-01-03 14:56:49 -0300723 workload_exec_failed_signal);
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200724 if (err < 0) {
725 pr_err("Couldn't run the workload!\n");
Namhyung Kim45604712014-05-12 09:47:24 +0900726 status = err;
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200727 goto out_delete_session;
Jens Axboe0a5ac842009-08-12 11:18:01 +0200728 }
Peter Zijlstra856e9662009-12-16 17:55:55 +0100729 }
730
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300731 if (record__open(rec) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600732 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900733 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600734 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200735
Wang Nan8690a2a2016-02-22 09:10:32 +0000736 err = bpf__apply_obj_config();
737 if (err) {
738 char errbuf[BUFSIZ];
739
740 bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
741 pr_err("ERROR: Apply config to BPF failed: %s\n",
742 errbuf);
743 goto out_child;
744 }
745
Adrian Huntercca84822015-08-19 17:29:21 +0300746 /*
747 * Normally perf_session__new would do this, but it doesn't have the
748 * evlist.
749 */
750 if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
751 pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
752 rec->tool.ordered_events = false;
753 }
754
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300755 if (!rec->evlist->nr_groups)
Namhyung Kima8bb5592013-01-22 18:09:31 +0900756 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
757
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200758 if (file->is_pipe) {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900759 err = perf_header__write_pipe(fd);
Tom Zanussi529870e2010-04-01 23:59:16 -0500760 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900761 goto out_child;
Jiri Olsa563aecb2013-06-05 13:35:06 +0200762 } else {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900763 err = perf_session__write_header(session, rec->evlist, fd, false);
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200764 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900765 goto out_child;
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200766 }
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +0200767
David Ahernd3665492012-02-06 15:27:52 -0700768 if (!rec->no_buildid
Robert Richtere20960c2011-12-07 10:02:55 +0100769 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
David Ahernd3665492012-02-06 15:27:52 -0700770 pr_err("Couldn't generate buildids. "
Robert Richtere20960c2011-12-07 10:02:55 +0100771 "Use --no-buildid to profile anyway.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600772 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900773 goto out_child;
Robert Richtere20960c2011-12-07 10:02:55 +0100774 }
775
Arnaldo Carvalho de Melo34ba5122012-12-19 09:04:24 -0300776 machine = &session->machines.host;
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200777
Wang Nanc45c86e2016-02-26 09:32:07 +0000778 err = record__synthesize(rec);
779 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900780 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600781
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200782 if (rec->realtime_prio) {
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200783 struct sched_param param;
784
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200785 param.sched_priority = rec->realtime_prio;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200786 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
Arnaldo Carvalho de Melo6beba7a2009-10-21 17:34:06 -0200787 pr_err("Could not set realtime priority.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600788 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900789 goto out_child;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200790 }
791 }
792
Jiri Olsa774cb492012-11-12 18:34:01 +0100793 /*
794 * When perf is starting the traced process, all the events
795 * (apart from group members) have enable_on_exec=1 set,
796 * so don't spoil it by prematurely enabling them.
797 */
Andi Kleen6619a532014-01-11 13:38:27 -0800798 if (!target__none(&opts->target) && !opts->initial_delay)
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300799 perf_evlist__enable(rec->evlist);
David Ahern764e16a32011-08-25 10:17:55 -0600800
Peter Zijlstra856e9662009-12-16 17:55:55 +0100801 /*
802 * Let the child rip
803 */
Namhyung Kime803cf92015-09-22 09:24:55 +0900804 if (forks) {
Namhyung Kime5bed562015-09-30 10:45:24 +0900805 union perf_event *event;
806
807 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
808 if (event == NULL) {
809 err = -ENOMEM;
810 goto out_child;
811 }
812
Namhyung Kime803cf92015-09-22 09:24:55 +0900813 /*
814 * Some H/W events are generated before COMM event
815 * which is emitted during exec(), so perf script
816 * cannot see a correct process name for those events.
817 * Synthesize COMM event to prevent it.
818 */
Namhyung Kime5bed562015-09-30 10:45:24 +0900819 perf_event__synthesize_comm(tool, event,
Namhyung Kime803cf92015-09-22 09:24:55 +0900820 rec->evlist->workload.pid,
821 process_synthesized_event,
822 machine);
Namhyung Kime5bed562015-09-30 10:45:24 +0900823 free(event);
Namhyung Kime803cf92015-09-22 09:24:55 +0900824
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300825 perf_evlist__start_workload(rec->evlist);
Namhyung Kime803cf92015-09-22 09:24:55 +0900826 }
Peter Zijlstra856e9662009-12-16 17:55:55 +0100827
Andi Kleen6619a532014-01-11 13:38:27 -0800828 if (opts->initial_delay) {
829 usleep(opts->initial_delay * 1000);
830 perf_evlist__enable(rec->evlist);
831 }
832
Wang Nan5f9cf592016-04-20 18:59:49 +0000833 trigger_ready(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000834 trigger_ready(&switch_output_trigger);
Peter Zijlstra649c48a2009-06-24 21:12:48 +0200835 for (;;) {
Yang Shi9f065192015-09-29 14:49:43 -0700836 unsigned long long hits = rec->samples;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200837
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300838 if (record__mmap_read_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000839 trigger_error(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000840 trigger_error(&switch_output_trigger);
David Ahern8d3eca22012-08-26 12:24:47 -0600841 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900842 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600843 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200844
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300845 if (auxtrace_record__snapshot_started) {
846 auxtrace_record__snapshot_started = 0;
Wang Nan5f9cf592016-04-20 18:59:49 +0000847 if (!trigger_is_error(&auxtrace_snapshot_trigger))
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300848 record__read_auxtrace_snapshot(rec);
Wang Nan5f9cf592016-04-20 18:59:49 +0000849 if (trigger_is_error(&auxtrace_snapshot_trigger)) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300850 pr_err("AUX area tracing snapshot failed\n");
851 err = -1;
852 goto out_child;
853 }
854 }
855
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000856 if (trigger_is_hit(&switch_output_trigger)) {
857 trigger_ready(&switch_output_trigger);
858
859 if (!quiet)
860 fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
861 waking);
862 waking = 0;
863 fd = record__switch_output(rec, false);
864 if (fd < 0) {
865 pr_err("Failed to switch to new file\n");
866 trigger_error(&switch_output_trigger);
867 err = fd;
868 goto out_child;
869 }
870 }
871
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200872 if (hits == rec->samples) {
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300873 if (done || draining)
Peter Zijlstra649c48a2009-06-24 21:12:48 +0200874 break;
Arnaldo Carvalho de Melof66a8892014-08-18 17:25:59 -0300875 err = perf_evlist__poll(rec->evlist, -1);
Jiri Olsaa5151142014-06-02 13:44:23 -0400876 /*
877 * Propagate error, only if there's any. Ignore positive
878 * number of returned events and interrupt error.
879 */
880 if (err > 0 || (err < 0 && errno == EINTR))
Namhyung Kim45604712014-05-12 09:47:24 +0900881 err = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200882 waking++;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300883
884 if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
885 draining = true;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200886 }
887
Jiri Olsa774cb492012-11-12 18:34:01 +0100888 /*
889 * When perf is starting the traced process, at the end events
890 * die with the process and we wait for that. Thus no need to
891 * disable events in this case.
892 */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -0300893 if (done && !disabled && !target__none(&opts->target)) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000894 trigger_off(&auxtrace_snapshot_trigger);
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300895 perf_evlist__disable(rec->evlist);
Jiri Olsa27119262012-11-12 18:34:02 +0100896 disabled = true;
897 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200898 }
Wang Nan5f9cf592016-04-20 18:59:49 +0000899 trigger_off(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000900 trigger_off(&switch_output_trigger);
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200901
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300902 if (forks && workload_exec_errno) {
Masami Hiramatsu35550da2014-08-14 02:22:43 +0000903 char msg[STRERR_BUFSIZE];
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300904 const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
905 pr_err("Workload failed: %s\n", emsg);
906 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900907 goto out_child;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300908 }
909
Namhyung Kime3d59112015-01-29 17:06:44 +0900910 if (!quiet)
Namhyung Kim45604712014-05-12 09:47:24 +0900911 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -0200912
Namhyung Kim45604712014-05-12 09:47:24 +0900913out_child:
914 if (forks) {
915 int exit_status;
Ingo Molnaraddc2782009-06-02 23:43:11 +0200916
Namhyung Kim45604712014-05-12 09:47:24 +0900917 if (!child_finished)
918 kill(rec->evlist->workload.pid, SIGTERM);
919
920 wait(&exit_status);
921
922 if (err < 0)
923 status = err;
924 else if (WIFEXITED(exit_status))
925 status = WEXITSTATUS(exit_status);
926 else if (WIFSIGNALED(exit_status))
927 signr = WTERMSIG(exit_status);
928 } else
929 status = err;
930
Namhyung Kime3d59112015-01-29 17:06:44 +0900931 /* this will be recalculated during process_buildids() */
932 rec->samples = 0;
933
Wang Nanecfd7a92016-04-13 08:21:07 +0000934 if (!err) {
935 if (!rec->timestamp_filename) {
936 record__finish_output(rec);
937 } else {
938 fd = record__switch_output(rec, true);
939 if (fd < 0) {
940 status = fd;
941 goto out_delete_session;
942 }
943 }
944 }
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -0300945
Namhyung Kime3d59112015-01-29 17:06:44 +0900946 if (!err && !quiet) {
947 char samples[128];
Wang Nanecfd7a92016-04-13 08:21:07 +0000948 const char *postfix = rec->timestamp_filename ?
949 ".<timestamp>" : "";
Namhyung Kime3d59112015-01-29 17:06:44 +0900950
Adrian Hunteref149c22015-04-09 18:53:45 +0300951 if (rec->samples && !rec->opts.full_auxtrace)
Namhyung Kime3d59112015-01-29 17:06:44 +0900952 scnprintf(samples, sizeof(samples),
953 " (%" PRIu64 " samples)", rec->samples);
954 else
955 samples[0] = '\0';
956
Wang Nanecfd7a92016-04-13 08:21:07 +0000957 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
Namhyung Kime3d59112015-01-29 17:06:44 +0900958 perf_data_file__size(file) / 1024.0 / 1024.0,
Wang Nanecfd7a92016-04-13 08:21:07 +0000959 file->path, postfix, samples);
Namhyung Kime3d59112015-01-29 17:06:44 +0900960 }
961
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -0300962out_delete_session:
963 perf_session__delete(session);
Namhyung Kim45604712014-05-12 09:47:24 +0900964 return status;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200965}
Ingo Molnar0e9b20b2009-05-26 09:17:18 +0200966
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300967static void callchain_debug(struct callchain_param *callchain)
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200968{
Kan Liangaad2b212015-01-05 13:23:04 -0500969 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
Jiri Olsaa601fdf2014-02-03 12:44:43 +0100970
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300971 pr_debug("callchain: type %s\n", str[callchain->record_mode]);
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200972
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300973 if (callchain->record_mode == CALLCHAIN_DWARF)
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200974 pr_debug("callchain: stack dump size %d\n",
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300975 callchain->dump_size);
976}
977
978int record_opts__parse_callchain(struct record_opts *record,
979 struct callchain_param *callchain,
980 const char *arg, bool unset)
981{
982 int ret;
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300983 callchain->enabled = !unset;
984
985 /* --no-call-graph */
986 if (unset) {
987 callchain->record_mode = CALLCHAIN_NONE;
988 pr_debug("callchain: disabled\n");
989 return 0;
990 }
991
992 ret = parse_callchain_record_opt(arg, callchain);
993 if (!ret) {
994 /* Enable data address sampling for DWARF unwind. */
995 if (callchain->record_mode == CALLCHAIN_DWARF)
996 record->sample_address = true;
997 callchain_debug(callchain);
998 }
999
1000 return ret;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001001}
1002
Kan Liangc421e802015-07-29 05:42:12 -04001003int record_parse_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001004 const char *arg,
1005 int unset)
1006{
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001007 return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
Jiri Olsa26d33022012-08-07 15:20:47 +02001008}
1009
Kan Liangc421e802015-07-29 05:42:12 -04001010int record_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001011 const char *arg __maybe_unused,
1012 int unset __maybe_unused)
1013{
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001014 struct callchain_param *callchain = opt->value;
Kan Liangc421e802015-07-29 05:42:12 -04001015
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001016 callchain->enabled = true;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001017
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001018 if (callchain->record_mode == CALLCHAIN_NONE)
1019 callchain->record_mode = CALLCHAIN_FP;
Jiri Olsaeb853e82014-02-03 12:44:42 +01001020
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001021 callchain_debug(callchain);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001022 return 0;
1023}
1024
Jiri Olsaeb853e82014-02-03 12:44:42 +01001025static int perf_record_config(const char *var, const char *value, void *cb)
1026{
Namhyung Kim7a29c082015-12-15 10:49:56 +09001027 struct record *rec = cb;
1028
1029 if (!strcmp(var, "record.build-id")) {
1030 if (!strcmp(value, "cache"))
1031 rec->no_buildid_cache = false;
1032 else if (!strcmp(value, "no-cache"))
1033 rec->no_buildid_cache = true;
1034 else if (!strcmp(value, "skip"))
1035 rec->no_buildid = true;
1036 else
1037 return -1;
1038 return 0;
1039 }
Jiri Olsaeb853e82014-02-03 12:44:42 +01001040 if (!strcmp(var, "record.call-graph"))
Namhyung Kim5a2e5e82014-09-23 10:01:44 +09001041 var = "call-graph.record-mode"; /* fall-through */
Jiri Olsaeb853e82014-02-03 12:44:42 +01001042
1043 return perf_default_config(var, value, cb);
1044}
1045
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001046struct clockid_map {
1047 const char *name;
1048 int clockid;
1049};
1050
1051#define CLOCKID_MAP(n, c) \
1052 { .name = n, .clockid = (c), }
1053
1054#define CLOCKID_END { .name = NULL, }
1055
1056
1057/*
1058 * Add the missing ones, we need to build on many distros...
1059 */
1060#ifndef CLOCK_MONOTONIC_RAW
1061#define CLOCK_MONOTONIC_RAW 4
1062#endif
1063#ifndef CLOCK_BOOTTIME
1064#define CLOCK_BOOTTIME 7
1065#endif
1066#ifndef CLOCK_TAI
1067#define CLOCK_TAI 11
1068#endif
1069
1070static const struct clockid_map clockids[] = {
1071 /* available for all events, NMI safe */
1072 CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
1073 CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
1074
1075 /* available for some events */
1076 CLOCKID_MAP("realtime", CLOCK_REALTIME),
1077 CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
1078 CLOCKID_MAP("tai", CLOCK_TAI),
1079
1080 /* available for the lazy */
1081 CLOCKID_MAP("mono", CLOCK_MONOTONIC),
1082 CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
1083 CLOCKID_MAP("real", CLOCK_REALTIME),
1084 CLOCKID_MAP("boot", CLOCK_BOOTTIME),
1085
1086 CLOCKID_END,
1087};
1088
1089static int parse_clockid(const struct option *opt, const char *str, int unset)
1090{
1091 struct record_opts *opts = (struct record_opts *)opt->value;
1092 const struct clockid_map *cm;
1093 const char *ostr = str;
1094
1095 if (unset) {
1096 opts->use_clockid = 0;
1097 return 0;
1098 }
1099
1100 /* no arg passed */
1101 if (!str)
1102 return 0;
1103
1104 /* no setting it twice */
1105 if (opts->use_clockid)
1106 return -1;
1107
1108 opts->use_clockid = true;
1109
1110 /* if its a number, we're done */
1111 if (sscanf(str, "%d", &opts->clockid) == 1)
1112 return 0;
1113
1114 /* allow a "CLOCK_" prefix to the name */
1115 if (!strncasecmp(str, "CLOCK_", 6))
1116 str += 6;
1117
1118 for (cm = clockids; cm->name; cm++) {
1119 if (!strcasecmp(str, cm->name)) {
1120 opts->clockid = cm->clockid;
1121 return 0;
1122 }
1123 }
1124
1125 opts->use_clockid = false;
1126 ui__warning("unknown clockid %s, check man page\n", ostr);
1127 return -1;
1128}
1129
Adrian Huntere9db1312015-04-09 18:53:46 +03001130static int record__parse_mmap_pages(const struct option *opt,
1131 const char *str,
1132 int unset __maybe_unused)
1133{
1134 struct record_opts *opts = opt->value;
1135 char *s, *p;
1136 unsigned int mmap_pages;
1137 int ret;
1138
1139 if (!str)
1140 return -EINVAL;
1141
1142 s = strdup(str);
1143 if (!s)
1144 return -ENOMEM;
1145
1146 p = strchr(s, ',');
1147 if (p)
1148 *p = '\0';
1149
1150 if (*s) {
1151 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
1152 if (ret)
1153 goto out_free;
1154 opts->mmap_pages = mmap_pages;
1155 }
1156
1157 if (!p) {
1158 ret = 0;
1159 goto out_free;
1160 }
1161
1162 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
1163 if (ret)
1164 goto out_free;
1165
1166 opts->auxtrace_mmap_pages = mmap_pages;
1167
1168out_free:
1169 free(s);
1170 return ret;
1171}
1172
Namhyung Kime5b2c202014-10-23 00:15:46 +09001173static const char * const __record_usage[] = {
Mike Galbraith9e0967532009-05-28 16:25:34 +02001174 "perf record [<options>] [<command>]",
1175 "perf record [<options>] -- <command> [<options>]",
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001176 NULL
1177};
Namhyung Kime5b2c202014-10-23 00:15:46 +09001178const char * const *record_usage = __record_usage;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001179
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001180/*
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001181 * XXX Ideally would be local to cmd_record() and passed to a record__new
1182 * because we need to have access to it in record__exit, that is called
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001183 * after cmd_record() exits, but since record_options need to be accessible to
1184 * builtin-script, leave it here.
1185 *
1186 * At least we don't ouch it in all the other functions here directly.
1187 *
1188 * Just say no to tons of global variables, sigh.
1189 */
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001190static struct record record = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001191 .opts = {
Andi Kleen8affc2b2014-07-31 14:45:04 +08001192 .sample_time = true,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001193 .mmap_pages = UINT_MAX,
1194 .user_freq = UINT_MAX,
1195 .user_interval = ULLONG_MAX,
Arnaldo Carvalho de Melo447a6012012-05-22 13:14:18 -03001196 .freq = 4000,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001197 .target = {
1198 .uses_mmap = true,
Adrian Hunter3aa59392013-11-15 15:52:29 +02001199 .default_per_cpu = true,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001200 },
Kan Liang9d9cad72015-06-17 09:51:11 -04001201 .proc_map_timeout = 500,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001202 },
Namhyung Kime3d59112015-01-29 17:06:44 +09001203 .tool = {
1204 .sample = process_sample_event,
1205 .fork = perf_event__process_fork,
Adrian Huntercca84822015-08-19 17:29:21 +03001206 .exit = perf_event__process_exit,
Namhyung Kime3d59112015-01-29 17:06:44 +09001207 .comm = perf_event__process_comm,
1208 .mmap = perf_event__process_mmap,
1209 .mmap2 = perf_event__process_mmap2,
Adrian Huntercca84822015-08-19 17:29:21 +03001210 .ordered_events = true,
Namhyung Kime3d59112015-01-29 17:06:44 +09001211 },
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001212};
Frederic Weisbecker7865e812010-04-14 19:42:07 +02001213
Namhyung Kim76a26542015-10-22 23:28:32 +09001214const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1215 "\n\t\t\t\tDefault: fp";
Arnaldo Carvalho de Melo61eaa3b2012-10-01 15:20:58 -03001216
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001217/*
1218 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
1219 * with it and switch to use the library functions in perf_evlist that came
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001220 * from builtin-record.c, i.e. use record_opts,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001221 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
1222 * using pipes, etc.
1223 */
Namhyung Kime5b2c202014-10-23 00:15:46 +09001224struct option __record_options[] = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001225 OPT_CALLBACK('e', "event", &record.evlist, "event",
Thomas Gleixner86847b62009-06-06 12:24:17 +02001226 "event selector. use 'perf list' to list available events",
Jiri Olsaf120f9d2011-07-14 11:25:32 +02001227 parse_events_option),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001228 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
Li Zefanc171b552009-10-15 11:22:07 +08001229 "event filter", parse_filter),
Wang Nan4ba1faa2015-07-10 07:36:10 +00001230 OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
1231 NULL, "don't record events from perf itself",
1232 exclude_perf),
Namhyung Kimbea03402012-04-26 14:15:15 +09001233 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001234 "record events on existing process id"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001235 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001236 "record events on existing thread id"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001237 OPT_INTEGER('r', "realtime", &record.realtime_prio,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001238 "collect data with this RT SCHED_FIFO priority"),
Arnaldo Carvalho de Melo509051e2014-01-14 17:52:14 -03001239 OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
Kirill Smelkovacac03f2011-01-12 17:59:36 +03001240 "collect data without buffering"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001241 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
Frederic Weisbeckerdaac07b2009-08-13 10:27:19 +02001242 "collect raw sample records from all opened counters"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001243 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001244 "system-wide collection from all CPUs"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001245 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
Stephane Eranianc45c6ea2010-05-28 12:00:01 +02001246 "list of cpus to monitor"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001247 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
Jiri Olsaf5fc1412013-10-15 16:27:32 +02001248 OPT_STRING('o', "output", &record.file.path, "file",
Ingo Molnarabaff322009-06-02 22:59:57 +02001249 "output file name"),
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001250 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1251 &record.opts.no_inherit_set,
1252 "child tasks do not inherit counters"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001253 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
Adrian Huntere9db1312015-04-09 18:53:46 +03001254 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
1255 "number of mmap data pages and AUX area tracing mmap pages",
1256 record__parse_mmap_pages),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001257 OPT_BOOLEAN(0, "group", &record.opts.group,
Lin Ming43bece72011-08-17 18:42:07 +08001258 "put the counters into a counter group"),
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001259 OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001260 NULL, "enables call-graph recording" ,
1261 &record_callchain_opt),
1262 OPT_CALLBACK(0, "call-graph", &record.opts,
Namhyung Kim76a26542015-10-22 23:28:32 +09001263 "record_mode[,record_size]", record_callchain_help,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001264 &record_parse_callchain_opt),
Ian Munsiec0555642010-04-13 18:37:33 +10001265 OPT_INCR('v', "verbose", &verbose,
Ingo Molnar3da297a2009-06-07 17:39:02 +02001266 "be more verbose (show counter open errors, etc)"),
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001267 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001268 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001269 "per thread counts"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001270 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
Adrian Hunter3abebc52015-07-06 14:51:01 +03001271 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
1272 &record.opts.sample_time_set,
1273 "Record the sample timestamps"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001274 OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001275 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001276 "don't sample"),
Wang Nand2db9a92016-01-25 09:56:19 +00001277 OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
1278 &record.no_buildid_cache_set,
1279 "do not update the buildid cache"),
1280 OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
1281 &record.no_buildid_set,
1282 "do not collect buildids in perf.data"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001283 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
Stephane Eranian023695d2011-02-14 11:20:01 +02001284 "monitor event in cgroup name only",
1285 parse_cgroups),
Arnaldo Carvalho de Meloa6205a32014-01-14 17:58:12 -03001286 OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
Andi Kleen6619a532014-01-11 13:38:27 -08001287 "ms to wait before starting measurement after program start"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001288 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
1289 "user to profile"),
Stephane Eraniana5aabda2012-03-08 23:47:45 +01001290
1291 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
1292 "branch any", "sample any taken branches",
1293 parse_branch_stack),
1294
1295 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
1296 "branch filter mask", "branch stack filter modes",
Roberto Agostino Vitillobdfebd82012-02-09 23:21:02 +01001297 parse_branch_stack),
Andi Kleen05484292013-01-24 16:10:29 +01001298 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
1299 "sample by weight (on special events only)"),
Andi Kleen475eeab2013-09-20 07:40:43 -07001300 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
1301 "sample transaction flags (special events only)"),
Adrian Hunter3aa59392013-11-15 15:52:29 +02001302 OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
1303 "use per-thread mmaps"),
Stephane Eranianbcc84ec2015-08-31 18:41:12 +02001304 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
1305 "sample selected machine registers on interrupt,"
1306 " use -I ? to list register names", parse_regs),
Andi Kleen85c273d2015-02-24 15:13:40 -08001307 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
1308 "Record running/enabled time of read (:S) events"),
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001309 OPT_CALLBACK('k', "clockid", &record.opts,
1310 "clockid", "clockid to use for events, see clock_gettime()",
1311 parse_clockid),
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001312 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
1313 "opts", "AUX area tracing Snapshot Mode", ""),
Kan Liang9d9cad72015-06-17 09:51:11 -04001314 OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
1315 "per thread proc mmap processing timeout in ms"),
Adrian Hunterb757bb02015-07-21 12:44:04 +03001316 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1317 "Record context switch events"),
Jiri Olsa85723882016-02-15 09:34:31 +01001318 OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
1319 "Configure all used events to run in kernel space.",
1320 PARSE_OPT_EXCLUSIVE),
1321 OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
1322 "Configure all used events to run in user space.",
1323 PARSE_OPT_EXCLUSIVE),
Wang Nan71dc23262015-10-14 12:41:19 +00001324 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1325 "clang binary to use for compiling BPF scriptlets"),
1326 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1327 "options passed to clang when compiling BPF scriptlets"),
He Kuang7efe0e02015-12-14 10:39:23 +00001328 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1329 "file", "vmlinux pathname"),
Namhyung Kim61566812016-01-11 22:37:09 +09001330 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
1331 "Record build-id of all DSOs regardless of hits"),
Wang Nanecfd7a92016-04-13 08:21:07 +00001332 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1333 "append timestamp to output filename"),
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001334 OPT_BOOLEAN(0, "switch-output", &record.switch_output,
1335 "Switch output when receive SIGUSR2"),
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001336 OPT_END()
1337};
1338
Namhyung Kime5b2c202014-10-23 00:15:46 +09001339struct option *record_options = __record_options;
1340
Irina Tirdea1d037ca2012-09-11 01:15:03 +03001341int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001342{
Adrian Hunteref149c22015-04-09 18:53:45 +03001343 int err;
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001344 struct record *rec = &record;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001345 char errbuf[BUFSIZ];
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001346
Wang Nan48e1cab2015-12-14 10:39:22 +00001347#ifndef HAVE_LIBBPF_SUPPORT
1348# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
1349 set_nobuild('\0', "clang-path", true);
1350 set_nobuild('\0', "clang-opt", true);
1351# undef set_nobuild
1352#endif
1353
He Kuang7efe0e02015-12-14 10:39:23 +00001354#ifndef HAVE_BPF_PROLOGUE
1355# if !defined (HAVE_DWARF_SUPPORT)
1356# define REASON "NO_DWARF=1"
1357# elif !defined (HAVE_LIBBPF_SUPPORT)
1358# define REASON "NO_LIBBPF=1"
1359# else
1360# define REASON "this architecture doesn't support BPF prologue"
1361# endif
1362# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
1363 set_nobuild('\0', "vmlinux", true);
1364# undef set_nobuild
1365# undef REASON
1366#endif
1367
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001368 rec->evlist = perf_evlist__new();
1369 if (rec->evlist == NULL)
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -02001370 return -ENOMEM;
1371
Jiri Olsaeb853e82014-02-03 12:44:42 +01001372 perf_config(perf_record_config, rec);
1373
Tom Zanussibca647a2010-11-10 08:11:30 -06001374 argc = parse_options(argc, argv, record_options, record_usage,
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001375 PARSE_OPT_STOP_AT_NON_OPTION);
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001376 if (!argc && target__none(&rec->opts.target))
Tom Zanussibca647a2010-11-10 08:11:30 -06001377 usage_with_options(record_usage, record_options);
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001378
Namhyung Kimbea03402012-04-26 14:15:15 +09001379 if (nr_cgroups && !rec->opts.target.system_wide) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001380 usage_with_options_msg(record_usage, record_options,
1381 "cgroup monitoring only available in system-wide mode");
1382
Stephane Eranian023695d2011-02-14 11:20:01 +02001383 }
Adrian Hunterb757bb02015-07-21 12:44:04 +03001384 if (rec->opts.record_switch_events &&
1385 !perf_can_record_switch_events()) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001386 ui__error("kernel does not support recording context switch events\n");
1387 parse_options_usage(record_usage, record_options, "switch-events", 0);
1388 return -EINVAL;
Adrian Hunterb757bb02015-07-21 12:44:04 +03001389 }
Stephane Eranian023695d2011-02-14 11:20:01 +02001390
Wang Naneca857a2016-04-20 18:59:51 +00001391 if (rec->switch_output)
1392 rec->timestamp_filename = true;
1393
Adrian Hunteref149c22015-04-09 18:53:45 +03001394 if (!rec->itr) {
1395 rec->itr = auxtrace_record__init(rec->evlist, &err);
1396 if (err)
1397 return err;
1398 }
1399
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001400 err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
1401 rec->opts.auxtrace_snapshot_opts);
1402 if (err)
1403 return err;
1404
Wang Nand7888572016-04-08 15:07:24 +00001405 err = bpf__setup_stdout(rec->evlist);
1406 if (err) {
1407 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
1408 pr_err("ERROR: Setup BPF stdout failed: %s\n",
1409 errbuf);
1410 return err;
1411 }
1412
Adrian Hunteref149c22015-04-09 18:53:45 +03001413 err = -ENOMEM;
1414
Namhyung Kim0a7e6d12014-08-12 15:40:45 +09001415 symbol__init(NULL);
Arnaldo Carvalho de Melobaa2f6c2010-11-26 19:39:15 -02001416
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001417 if (symbol_conf.kptr_restrict)
Arnaldo Carvalho de Melo646aaea62011-05-27 11:00:41 -03001418 pr_warning(
1419"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
1420"check /proc/sys/kernel/kptr_restrict.\n\n"
1421"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
1422"file is not found in the buildid cache or in the vmlinux path.\n\n"
1423"Samples in kernel modules won't be resolved at all.\n\n"
1424"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
1425"even with a suitable vmlinux or kallsyms file.\n\n");
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001426
Wang Nan0c1d46a2016-04-20 18:59:52 +00001427 if (rec->no_buildid_cache || rec->no_buildid) {
Stephane Eraniana1ac1d32010-06-17 11:39:01 +02001428 disable_buildid_cache();
Wang Nan0c1d46a2016-04-20 18:59:52 +00001429 } else if (rec->switch_output) {
1430 /*
1431 * In 'perf record --switch-output', disable buildid
1432 * generation by default to reduce data file switching
1433 * overhead. Still generate buildid if they are required
1434 * explicitly using
1435 *
1436 * perf record --signal-trigger --no-no-buildid \
1437 * --no-no-buildid-cache
1438 *
1439 * Following code equals to:
1440 *
1441 * if ((rec->no_buildid || !rec->no_buildid_set) &&
1442 * (rec->no_buildid_cache || !rec->no_buildid_cache_set))
1443 * disable_buildid_cache();
1444 */
1445 bool disable = true;
1446
1447 if (rec->no_buildid_set && !rec->no_buildid)
1448 disable = false;
1449 if (rec->no_buildid_cache_set && !rec->no_buildid_cache)
1450 disable = false;
1451 if (disable) {
1452 rec->no_buildid = true;
1453 rec->no_buildid_cache = true;
1454 disable_buildid_cache();
1455 }
1456 }
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001457
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001458 if (rec->evlist->nr_entries == 0 &&
1459 perf_evlist__add_default(rec->evlist) < 0) {
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001460 pr_err("Not enough memory for event selector list\n");
1461 goto out_symbol_exit;
Peter Zijlstrabbd36e52009-06-11 23:11:50 +02001462 }
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001463
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001464 if (rec->opts.target.tid && !rec->opts.no_inherit_set)
1465 rec->opts.no_inherit = true;
1466
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001467 err = target__validate(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001468 if (err) {
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001469 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001470 ui__warning("%s", errbuf);
1471 }
Namhyung Kim4bd0f2d2012-04-26 14:15:18 +09001472
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001473 err = target__parse_uid(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001474 if (err) {
1475 int saved_errno = errno;
1476
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001477 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim3780f482012-05-29 13:22:57 +09001478 ui__error("%s", errbuf);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001479
1480 err = -saved_errno;
Namhyung Kim8fa60e12013-03-15 14:48:51 +09001481 goto out_symbol_exit;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001482 }
Arnaldo Carvalho de Melo0d37aa32012-01-19 14:08:15 -02001483
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001484 err = -ENOMEM;
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001485 if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -02001486 usage_with_options(record_usage, record_options);
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001487
Adrian Hunteref149c22015-04-09 18:53:45 +03001488 err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
1489 if (err)
1490 goto out_symbol_exit;
1491
Namhyung Kim61566812016-01-11 22:37:09 +09001492 /*
1493 * We take all buildids when the file contains
1494 * AUX area tracing data because we do not decode the
1495 * trace because it would take too long.
1496 */
1497 if (rec->opts.full_auxtrace)
1498 rec->buildid_all = true;
1499
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001500 if (record_opts__config(&rec->opts)) {
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001501 err = -EINVAL;
Arnaldo Carvalho de Melo03ad9742014-01-03 15:56:06 -03001502 goto out_symbol_exit;
Mike Galbraith7e4ff9e2009-10-12 07:56:03 +02001503 }
1504
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001505 err = __cmd_record(&record, argc, argv);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03001506out_symbol_exit:
Namhyung Kim45604712014-05-12 09:47:24 +09001507 perf_evlist__delete(rec->evlist);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03001508 symbol__exit();
Adrian Hunteref149c22015-04-09 18:53:45 +03001509 auxtrace_record__free(rec->itr);
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001510 return err;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001511}
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001512
1513static void snapshot_sig_handler(int sig __maybe_unused)
1514{
Wang Nan5f9cf592016-04-20 18:59:49 +00001515 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1516 trigger_hit(&auxtrace_snapshot_trigger);
1517 auxtrace_record__snapshot_started = 1;
1518 if (auxtrace_record__snapshot_start(record.itr))
1519 trigger_error(&auxtrace_snapshot_trigger);
1520 }
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001521
1522 if (trigger_is_ready(&switch_output_trigger))
1523 trigger_hit(&switch_output_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001524}