blob: f4710c82980f66ce4e21d55e06ae0e5576e51f2c [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>
Peter Zijlstrade9ac072009-04-08 15:01:31 +020043
Bernhard Rosenkraenzer78da39f2012-10-08 09:43:26 +030044
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -030045struct record {
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020046 struct perf_tool tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -030047 struct record_opts opts;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020048 u64 bytes_written;
Jiri Olsaf5fc1412013-10-15 16:27:32 +020049 struct perf_data_file file;
Adrian Hunteref149c22015-04-09 18:53:45 +030050 struct auxtrace_record *itr;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020051 struct perf_evlist *evlist;
52 struct perf_session *session;
53 const char *progname;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020054 int realtime_prio;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020055 bool no_buildid;
Wang Nand2db9a92016-01-25 09:56:19 +000056 bool no_buildid_set;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020057 bool no_buildid_cache;
Wang Nand2db9a92016-01-25 09:56:19 +000058 bool no_buildid_cache_set;
Namhyung Kim61566812016-01-11 22:37:09 +090059 bool buildid_all;
Wang Nanecfd7a92016-04-13 08:21:07 +000060 bool timestamp_filename;
Yang Shi9f065192015-09-29 14:49:43 -070061 unsigned long long samples;
Arnaldo Carvalho de Melo0f82ebc2011-11-08 14:41:57 -020062};
Ingo Molnara21ca2c2009-06-06 09:58:57 +020063
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -030064static int record__write(struct record *rec, void *bf, size_t size)
Peter Zijlstraf5970552009-06-18 23:22:55 +020065{
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -030066 if (perf_data_file__write(rec->session->file, bf, size) < 0) {
Jiri Olsa50a9b862013-11-22 13:11:24 +010067 pr_err("failed to write perf data, error: %m\n");
68 return -1;
Peter Zijlstraf5970552009-06-18 23:22:55 +020069 }
David Ahern8d3eca22012-08-26 12:24:47 -060070
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -030071 rec->bytes_written += size;
David Ahern8d3eca22012-08-26 12:24:47 -060072 return 0;
Peter Zijlstraf5970552009-06-18 23:22:55 +020073}
74
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020075static int process_synthesized_event(struct perf_tool *tool,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020076 union perf_event *event,
Irina Tirdea1d037ca2012-09-11 01:15:03 +030077 struct perf_sample *sample __maybe_unused,
78 struct machine *machine __maybe_unused)
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -020079{
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -030080 struct record *rec = container_of(tool, struct record, tool);
81 return record__write(rec, event, event->header.size);
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -020082}
83
Arnaldo Carvalho de Meloe5685732014-09-17 16:42:58 -030084static int record__mmap_read(struct record *rec, int idx)
Peter Zijlstrade9ac072009-04-08 15:01:31 +020085{
Arnaldo Carvalho de Meloe5685732014-09-17 16:42:58 -030086 struct perf_mmap *md = &rec->evlist->mmap[idx];
David Ahern7b8283b52015-04-07 09:20:37 -060087 u64 head = perf_mmap__read_head(md);
88 u64 old = md->prev;
Jiri Olsa918512b2013-09-12 18:39:35 +020089 unsigned char *data = md->base + page_size;
Peter Zijlstrade9ac072009-04-08 15:01:31 +020090 unsigned long size;
91 void *buf;
David Ahern8d3eca22012-08-26 12:24:47 -060092 int rc = 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +020093
Arnaldo Carvalho de Melodc820092011-01-28 14:49:19 -020094 if (old == head)
David Ahern8d3eca22012-08-26 12:24:47 -060095 return 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +020096
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020097 rec->samples++;
Peter Zijlstrade9ac072009-04-08 15:01:31 +020098
99 size = head - old;
100
101 if ((old & md->mask) + size != (head & md->mask)) {
102 buf = &data[old & md->mask];
103 size = md->mask + 1 - (old & md->mask);
104 old += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200105
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300106 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600107 rc = -1;
108 goto out;
109 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200110 }
111
112 buf = &data[old & md->mask];
113 size = head - old;
114 old += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200115
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300116 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600117 rc = -1;
118 goto out;
119 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200120
121 md->prev = old;
Arnaldo Carvalho de Meloe5685732014-09-17 16:42:58 -0300122 perf_evlist__mmap_consume(rec->evlist, idx);
David Ahern8d3eca22012-08-26 12:24:47 -0600123out:
124 return rc;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200125}
126
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300127static volatile int done;
128static volatile int signr = -1;
129static volatile int child_finished;
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000130
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300131static volatile int auxtrace_record__snapshot_started;
Wang Nan5f9cf592016-04-20 18:59:49 +0000132static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300133
134static void sig_handler(int sig)
135{
136 if (sig == SIGCHLD)
137 child_finished = 1;
138 else
139 signr = sig;
140
141 done = 1;
142}
143
144static void record__sig_exit(void)
145{
146 if (signr == -1)
147 return;
148
149 signal(signr, SIG_DFL);
150 raise(signr);
151}
152
Adrian Huntere31f0d02015-04-30 17:37:27 +0300153#ifdef HAVE_AUXTRACE_SUPPORT
154
Adrian Hunteref149c22015-04-09 18:53:45 +0300155static int record__process_auxtrace(struct perf_tool *tool,
156 union perf_event *event, void *data1,
157 size_t len1, void *data2, size_t len2)
158{
159 struct record *rec = container_of(tool, struct record, tool);
Adrian Hunter99fa2982015-04-30 17:37:25 +0300160 struct perf_data_file *file = &rec->file;
Adrian Hunteref149c22015-04-09 18:53:45 +0300161 size_t padding;
162 u8 pad[8] = {0};
163
Adrian Hunter99fa2982015-04-30 17:37:25 +0300164 if (!perf_data_file__is_pipe(file)) {
165 off_t file_offset;
166 int fd = perf_data_file__fd(file);
167 int err;
168
169 file_offset = lseek(fd, 0, SEEK_CUR);
170 if (file_offset == -1)
171 return -1;
172 err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index,
173 event, file_offset);
174 if (err)
175 return err;
176 }
177
Adrian Hunteref149c22015-04-09 18:53:45 +0300178 /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */
179 padding = (len1 + len2) & 7;
180 if (padding)
181 padding = 8 - padding;
182
183 record__write(rec, event, event->header.size);
184 record__write(rec, data1, len1);
185 if (len2)
186 record__write(rec, data2, len2);
187 record__write(rec, &pad, padding);
188
189 return 0;
190}
191
192static int record__auxtrace_mmap_read(struct record *rec,
193 struct auxtrace_mmap *mm)
194{
195 int ret;
196
197 ret = auxtrace_mmap__read(mm, rec->itr, &rec->tool,
198 record__process_auxtrace);
199 if (ret < 0)
200 return ret;
201
202 if (ret)
203 rec->samples++;
204
205 return 0;
206}
207
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300208static int record__auxtrace_mmap_read_snapshot(struct record *rec,
209 struct auxtrace_mmap *mm)
210{
211 int ret;
212
213 ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool,
214 record__process_auxtrace,
215 rec->opts.auxtrace_snapshot_size);
216 if (ret < 0)
217 return ret;
218
219 if (ret)
220 rec->samples++;
221
222 return 0;
223}
224
225static int record__auxtrace_read_snapshot_all(struct record *rec)
226{
227 int i;
228 int rc = 0;
229
230 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
231 struct auxtrace_mmap *mm =
232 &rec->evlist->mmap[i].auxtrace_mmap;
233
234 if (!mm->base)
235 continue;
236
237 if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) {
238 rc = -1;
239 goto out;
240 }
241 }
242out:
243 return rc;
244}
245
246static void record__read_auxtrace_snapshot(struct record *rec)
247{
248 pr_debug("Recording AUX area tracing snapshot\n");
249 if (record__auxtrace_read_snapshot_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000250 trigger_error(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300251 } else {
Wang Nan5f9cf592016-04-20 18:59:49 +0000252 if (auxtrace_record__snapshot_finish(rec->itr))
253 trigger_error(&auxtrace_snapshot_trigger);
254 else
255 trigger_ready(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300256 }
257}
258
Adrian Huntere31f0d02015-04-30 17:37:27 +0300259#else
260
261static inline
262int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
263 struct auxtrace_mmap *mm __maybe_unused)
264{
265 return 0;
266}
267
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300268static inline
269void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
270{
271}
272
273static inline
274int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
275{
276 return 0;
277}
278
Adrian Huntere31f0d02015-04-30 17:37:27 +0300279#endif
280
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300281static int record__open(struct record *rec)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200282{
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300283 char msg[512];
Jiri Olsa6a4bb042012-08-08 12:22:36 +0200284 struct perf_evsel *pos;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200285 struct perf_evlist *evlist = rec->evlist;
286 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300287 struct record_opts *opts = &rec->opts;
David Ahern8d3eca22012-08-26 12:24:47 -0600288 int rc = 0;
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200289
Arnaldo Carvalho de Meloe68ae9c2016-04-11 18:15:29 -0300290 perf_evlist__config(evlist, opts, &callchain_param);
Jiri Olsacac21422012-11-12 18:34:00 +0100291
Arnaldo Carvalho de Melo0050f7a2014-01-10 10:37:27 -0300292 evlist__for_each(evlist, pos) {
Ingo Molnar3da297a2009-06-07 17:39:02 +0200293try_again:
Kan Liangd988d5e2015-08-21 02:23:14 -0400294 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300295 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300296 if (verbose)
Arnaldo Carvalho de Meloc0a54342012-12-13 14:16:30 -0300297 ui__warning("%s\n", msg);
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300298 goto try_again;
299 }
David Ahernca6a4252011-03-25 13:11:11 -0600300
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300301 rc = -errno;
302 perf_evsel__open_strerror(pos, &opts->target,
303 errno, msg, sizeof(msg));
304 ui__error("%s\n", msg);
David Ahern8d3eca22012-08-26 12:24:47 -0600305 goto out;
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300306 }
Li Zefanc171b552009-10-15 11:22:07 +0800307 }
Arnaldo Carvalho de Meloa43d3f02010-12-25 12:12:25 -0200308
Arnaldo Carvalho de Melo23d4aad2015-03-24 19:23:47 -0300309 if (perf_evlist__apply_filters(evlist, &pos)) {
310 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
311 pos->filter, perf_evsel__name(pos), errno,
Masami Hiramatsu35550da2014-08-14 02:22:43 +0000312 strerror_r(errno, msg, sizeof(msg)));
David Ahern8d3eca22012-08-26 12:24:47 -0600313 rc = -1;
314 goto out;
Frederic Weisbecker0a102472011-02-26 04:51:54 +0100315 }
316
Adrian Hunteref149c22015-04-09 18:53:45 +0300317 if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300318 opts->auxtrace_mmap_pages,
319 opts->auxtrace_snapshot_mode) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600320 if (errno == EPERM) {
321 pr_err("Permission error mapping pages.\n"
322 "Consider increasing "
323 "/proc/sys/kernel/perf_event_mlock_kb,\n"
324 "or try again with a smaller value of -m/--mmap_pages.\n"
Adrian Hunteref149c22015-04-09 18:53:45 +0300325 "(current value: %u,%u)\n",
326 opts->mmap_pages, opts->auxtrace_mmap_pages);
David Ahern8d3eca22012-08-26 12:24:47 -0600327 rc = -errno;
David Ahern8d3eca22012-08-26 12:24:47 -0600328 } else {
Masami Hiramatsu35550da2014-08-14 02:22:43 +0000329 pr_err("failed to mmap with %d (%s)\n", errno,
330 strerror_r(errno, msg, sizeof(msg)));
Wang Nan95c36562016-02-26 09:32:17 +0000331 if (errno)
332 rc = -errno;
333 else
334 rc = -EINVAL;
David Ahern8d3eca22012-08-26 12:24:47 -0600335 }
336 goto out;
Nelson Elhage18e60932011-12-19 08:39:31 -0500337 }
Arnaldo Carvalho de Melo0a27d7f2011-01-14 15:50:51 -0200338
Jiri Olsa563aecb2013-06-05 13:35:06 +0200339 session->evlist = evlist;
Arnaldo Carvalho de Melo7b56cce2012-08-01 19:31:00 -0300340 perf_session__set_id_hdr_size(session);
David Ahern8d3eca22012-08-26 12:24:47 -0600341out:
342 return rc;
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200343}
344
Namhyung Kime3d59112015-01-29 17:06:44 +0900345static int process_sample_event(struct perf_tool *tool,
346 union perf_event *event,
347 struct perf_sample *sample,
348 struct perf_evsel *evsel,
349 struct machine *machine)
350{
351 struct record *rec = container_of(tool, struct record, tool);
352
353 rec->samples++;
354
355 return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
356}
357
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300358static int process_buildids(struct record *rec)
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200359{
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200360 struct perf_data_file *file = &rec->file;
361 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200362
He Kuang457ae942015-05-28 13:17:30 +0000363 if (file->size == 0)
Arnaldo Carvalho de Melo9f591fd2010-03-11 15:53:11 -0300364 return 0;
365
Namhyung Kim00dc8652014-11-04 10:14:32 +0900366 /*
367 * During this process, it'll load kernel map and replace the
368 * dso->long_name to a real pathname it found. In this case
369 * we prefer the vmlinux path like
370 * /lib/modules/3.16.4/build/vmlinux
371 *
372 * rather than build-id path (in debug directory).
373 * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551
374 */
375 symbol_conf.ignore_vmlinux_buildid = true;
376
Namhyung Kim61566812016-01-11 22:37:09 +0900377 /*
378 * If --buildid-all is given, it marks all DSO regardless of hits,
379 * so no need to process samples.
380 */
381 if (rec->buildid_all)
382 rec->tool.sample = NULL;
383
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300384 return perf_session__process_events(session);
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200385}
386
Arnaldo Carvalho de Melo8115d602011-01-29 14:01:45 -0200387static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800388{
389 int err;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200390 struct perf_tool *tool = data;
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800391 /*
392 *As for guest kernel when processing subcommand record&report,
393 *we arrange module mmap prior to guest kernel mmap and trigger
394 *a preload dso because default guest module symbols are loaded
395 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
396 *method is used to avoid symbol missing when the first addr is
397 *in module instead of in guest kernel.
398 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200399 err = perf_event__synthesize_modules(tool, process_synthesized_event,
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200400 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800401 if (err < 0)
402 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300403 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800404
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800405 /*
406 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
407 * have no _text sometimes.
408 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200409 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
Adrian Hunter0ae617b2014-01-29 16:14:40 +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}
415
Frederic Weisbecker98402802010-05-02 22:05:29 +0200416static struct perf_event_header finished_round_event = {
417 .size = sizeof(struct perf_event_header),
418 .type = PERF_RECORD_FINISHED_ROUND,
419};
420
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300421static int record__mmap_read_all(struct record *rec)
Frederic Weisbecker98402802010-05-02 22:05:29 +0200422{
Jiri Olsadcabb502014-07-25 16:56:16 +0200423 u64 bytes_written = rec->bytes_written;
Peter Zijlstra0e2e63d2010-05-20 14:45:26 +0200424 int i;
David Ahern8d3eca22012-08-26 12:24:47 -0600425 int rc = 0;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200426
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200427 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
Adrian Hunteref149c22015-04-09 18:53:45 +0300428 struct auxtrace_mmap *mm = &rec->evlist->mmap[i].auxtrace_mmap;
429
David Ahern8d3eca22012-08-26 12:24:47 -0600430 if (rec->evlist->mmap[i].base) {
Arnaldo Carvalho de Meloe5685732014-09-17 16:42:58 -0300431 if (record__mmap_read(rec, i) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600432 rc = -1;
433 goto out;
434 }
435 }
Adrian Hunteref149c22015-04-09 18:53:45 +0300436
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300437 if (mm->base && !rec->opts.auxtrace_snapshot_mode &&
Adrian Hunteref149c22015-04-09 18:53:45 +0300438 record__auxtrace_mmap_read(rec, mm) != 0) {
439 rc = -1;
440 goto out;
441 }
Frederic Weisbecker98402802010-05-02 22:05:29 +0200442 }
443
Jiri Olsadcabb502014-07-25 16:56:16 +0200444 /*
445 * Mark the round finished in case we wrote
446 * at least one event.
447 */
448 if (bytes_written != rec->bytes_written)
449 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
David Ahern8d3eca22012-08-26 12:24:47 -0600450
451out:
452 return rc;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200453}
454
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300455static void record__init_features(struct record *rec)
David Ahern57706ab2013-11-06 11:41:34 -0700456{
David Ahern57706ab2013-11-06 11:41:34 -0700457 struct perf_session *session = rec->session;
458 int feat;
459
460 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
461 perf_header__set_feat(&session->header, feat);
462
463 if (rec->no_buildid)
464 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
465
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300466 if (!have_tracepoints(&rec->evlist->entries))
David Ahern57706ab2013-11-06 11:41:34 -0700467 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
468
469 if (!rec->opts.branch_stack)
470 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
Adrian Hunteref149c22015-04-09 18:53:45 +0300471
472 if (!rec->opts.full_auxtrace)
473 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
Jiri Olsaffa517a2015-10-25 15:51:43 +0100474
475 perf_header__clear_feat(&session->header, HEADER_STAT);
David Ahern57706ab2013-11-06 11:41:34 -0700476}
477
Wang Nane1ab48b2016-02-26 09:32:10 +0000478static void
479record__finish_output(struct record *rec)
480{
481 struct perf_data_file *file = &rec->file;
482 int fd = perf_data_file__fd(file);
483
484 if (file->is_pipe)
485 return;
486
487 rec->session->header.data_size += rec->bytes_written;
488 file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR);
489
490 if (!rec->no_buildid) {
491 process_buildids(rec);
492
493 if (rec->buildid_all)
494 dsos__hit_all(rec->session);
495 }
496 perf_session__write_header(rec->session, rec->evlist, fd, true);
497
498 return;
499}
500
Wang Nanecfd7a92016-04-13 08:21:07 +0000501static int
502record__switch_output(struct record *rec, bool at_exit)
503{
504 struct perf_data_file *file = &rec->file;
505 int fd, err;
506
507 /* Same Size: "2015122520103046"*/
508 char timestamp[] = "InvalidTimestamp";
509
510 rec->samples = 0;
511 record__finish_output(rec);
512 err = fetch_current_timestamp(timestamp, sizeof(timestamp));
513 if (err) {
514 pr_err("Failed to get current timestamp\n");
515 return -EINVAL;
516 }
517
518 fd = perf_data_file__switch(file, timestamp,
519 rec->session->header.data_offset,
520 at_exit);
521 if (fd >= 0 && !at_exit) {
522 rec->bytes_written = 0;
523 rec->session->header.data_size = 0;
524 }
525
526 if (!quiet)
527 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
528 file->path, timestamp);
529 return fd;
530}
531
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300532static volatile int workload_exec_errno;
533
534/*
535 * perf_evlist__prepare_workload will send a SIGUSR1
536 * if the fork fails, since we asked by setting its
537 * want_signal to true.
538 */
Namhyung Kim45604712014-05-12 09:47:24 +0900539static void workload_exec_failed_signal(int signo __maybe_unused,
540 siginfo_t *info,
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300541 void *ucontext __maybe_unused)
542{
543 workload_exec_errno = info->si_value.sival_int;
544 done = 1;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300545 child_finished = 1;
546}
547
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300548static void snapshot_sig_handler(int sig);
549
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200550int __weak
551perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
552 struct perf_tool *tool __maybe_unused,
553 perf_event__handler_t process __maybe_unused,
554 struct machine *machine __maybe_unused)
555{
556 return 0;
557}
558
Wang Nanc45c86e2016-02-26 09:32:07 +0000559static int record__synthesize(struct record *rec)
560{
561 struct perf_session *session = rec->session;
562 struct machine *machine = &session->machines.host;
563 struct perf_data_file *file = &rec->file;
564 struct record_opts *opts = &rec->opts;
565 struct perf_tool *tool = &rec->tool;
566 int fd = perf_data_file__fd(file);
567 int err = 0;
568
569 if (file->is_pipe) {
570 err = perf_event__synthesize_attrs(tool, session,
571 process_synthesized_event);
572 if (err < 0) {
573 pr_err("Couldn't synthesize attrs.\n");
574 goto out;
575 }
576
577 if (have_tracepoints(&rec->evlist->entries)) {
578 /*
579 * FIXME err <= 0 here actually means that
580 * there were no tracepoints so its not really
581 * an error, just that we don't need to
582 * synthesize anything. We really have to
583 * return this more properly and also
584 * propagate errors that now are calling die()
585 */
586 err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
587 process_synthesized_event);
588 if (err <= 0) {
589 pr_err("Couldn't record tracing data.\n");
590 goto out;
591 }
592 rec->bytes_written += err;
593 }
594 }
595
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200596 err = perf_event__synth_time_conv(rec->evlist->mmap[0].base, tool,
597 process_synthesized_event, machine);
598 if (err)
599 goto out;
600
Wang Nanc45c86e2016-02-26 09:32:07 +0000601 if (rec->opts.full_auxtrace) {
602 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
603 session, process_synthesized_event);
604 if (err)
605 goto out;
606 }
607
608 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
609 machine);
610 WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
611 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
612 "Check /proc/kallsyms permission or run as root.\n");
613
614 err = perf_event__synthesize_modules(tool, process_synthesized_event,
615 machine);
616 WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
617 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
618 "Check /proc/modules permission or run as root.\n");
619
620 if (perf_guest) {
621 machines__process_guests(&session->machines,
622 perf_event__synthesize_guest_os, tool);
623 }
624
625 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
626 process_synthesized_event, opts->sample_address,
627 opts->proc_map_timeout);
628out:
629 return err;
630}
631
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300632static int __cmd_record(struct record *rec, int argc, const char **argv)
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200633{
David Ahern57706ab2013-11-06 11:41:34 -0700634 int err;
Namhyung Kim45604712014-05-12 09:47:24 +0900635 int status = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200636 unsigned long waking = 0;
Zhang, Yanmin46be6042010-03-18 11:36:04 -0300637 const bool forks = argc > 0;
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300638 struct machine *machine;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200639 struct perf_tool *tool = &rec->tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300640 struct record_opts *opts = &rec->opts;
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200641 struct perf_data_file *file = &rec->file;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200642 struct perf_session *session;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300643 bool disabled = false, draining = false;
Namhyung Kim42aa2762015-01-29 17:06:48 +0900644 int fd;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200645
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200646 rec->progname = argv[0];
Andi Kleen33e49ea2011-09-15 14:31:40 -0700647
Namhyung Kim45604712014-05-12 09:47:24 +0900648 atexit(record__sig_exit);
Peter Zijlstraf5970552009-06-18 23:22:55 +0200649 signal(SIGCHLD, sig_handler);
650 signal(SIGINT, sig_handler);
David Ahern804f7ac2013-05-06 12:24:23 -0600651 signal(SIGTERM, sig_handler);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000652
653 if (rec->opts.auxtrace_snapshot_mode) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300654 signal(SIGUSR2, snapshot_sig_handler);
Wang Nan5f9cf592016-04-20 18:59:49 +0000655 trigger_on(&auxtrace_snapshot_trigger);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000656 } else {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300657 signal(SIGUSR2, SIG_IGN);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000658 }
Peter Zijlstraf5970552009-06-18 23:22:55 +0200659
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300660 session = perf_session__new(file, false, tool);
Arnaldo Carvalho de Melo94c744b2009-12-11 21:24:02 -0200661 if (session == NULL) {
Adrien BAKffa91882014-04-18 11:00:43 +0900662 pr_err("Perf session creation failed.\n");
Arnaldo Carvalho de Meloa9a70bb2009-11-17 01:18:11 -0200663 return -1;
664 }
665
Namhyung Kim42aa2762015-01-29 17:06:48 +0900666 fd = perf_data_file__fd(file);
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200667 rec->session = session;
668
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300669 record__init_features(rec);
Stephane Eranian330aa672012-03-08 23:47:46 +0100670
Arnaldo Carvalho de Melod4db3f12009-12-27 21:36:57 -0200671 if (forks) {
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300672 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200673 argv, file->is_pipe,
Arnaldo Carvalho de Melo735f7e02014-01-03 14:56:49 -0300674 workload_exec_failed_signal);
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200675 if (err < 0) {
676 pr_err("Couldn't run the workload!\n");
Namhyung Kim45604712014-05-12 09:47:24 +0900677 status = err;
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200678 goto out_delete_session;
Jens Axboe0a5ac842009-08-12 11:18:01 +0200679 }
Peter Zijlstra856e9662009-12-16 17:55:55 +0100680 }
681
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300682 if (record__open(rec) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600683 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900684 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600685 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200686
Wang Nan8690a2a2016-02-22 09:10:32 +0000687 err = bpf__apply_obj_config();
688 if (err) {
689 char errbuf[BUFSIZ];
690
691 bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
692 pr_err("ERROR: Apply config to BPF failed: %s\n",
693 errbuf);
694 goto out_child;
695 }
696
Adrian Huntercca84822015-08-19 17:29:21 +0300697 /*
698 * Normally perf_session__new would do this, but it doesn't have the
699 * evlist.
700 */
701 if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
702 pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
703 rec->tool.ordered_events = false;
704 }
705
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300706 if (!rec->evlist->nr_groups)
Namhyung Kima8bb5592013-01-22 18:09:31 +0900707 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
708
Jiri Olsaf5fc1412013-10-15 16:27:32 +0200709 if (file->is_pipe) {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900710 err = perf_header__write_pipe(fd);
Tom Zanussi529870e2010-04-01 23:59:16 -0500711 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900712 goto out_child;
Jiri Olsa563aecb2013-06-05 13:35:06 +0200713 } else {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900714 err = perf_session__write_header(session, rec->evlist, fd, false);
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200715 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900716 goto out_child;
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200717 }
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +0200718
David Ahernd3665492012-02-06 15:27:52 -0700719 if (!rec->no_buildid
Robert Richtere20960c2011-12-07 10:02:55 +0100720 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
David Ahernd3665492012-02-06 15:27:52 -0700721 pr_err("Couldn't generate buildids. "
Robert Richtere20960c2011-12-07 10:02:55 +0100722 "Use --no-buildid to profile anyway.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600723 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900724 goto out_child;
Robert Richtere20960c2011-12-07 10:02:55 +0100725 }
726
Arnaldo Carvalho de Melo34ba5122012-12-19 09:04:24 -0300727 machine = &session->machines.host;
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200728
Wang Nanc45c86e2016-02-26 09:32:07 +0000729 err = record__synthesize(rec);
730 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900731 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600732
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200733 if (rec->realtime_prio) {
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200734 struct sched_param param;
735
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200736 param.sched_priority = rec->realtime_prio;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200737 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
Arnaldo Carvalho de Melo6beba7a2009-10-21 17:34:06 -0200738 pr_err("Could not set realtime priority.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600739 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900740 goto out_child;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200741 }
742 }
743
Jiri Olsa774cb492012-11-12 18:34:01 +0100744 /*
745 * When perf is starting the traced process, all the events
746 * (apart from group members) have enable_on_exec=1 set,
747 * so don't spoil it by prematurely enabling them.
748 */
Andi Kleen6619a532014-01-11 13:38:27 -0800749 if (!target__none(&opts->target) && !opts->initial_delay)
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300750 perf_evlist__enable(rec->evlist);
David Ahern764e16a32011-08-25 10:17:55 -0600751
Peter Zijlstra856e9662009-12-16 17:55:55 +0100752 /*
753 * Let the child rip
754 */
Namhyung Kime803cf92015-09-22 09:24:55 +0900755 if (forks) {
Namhyung Kime5bed562015-09-30 10:45:24 +0900756 union perf_event *event;
757
758 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
759 if (event == NULL) {
760 err = -ENOMEM;
761 goto out_child;
762 }
763
Namhyung Kime803cf92015-09-22 09:24:55 +0900764 /*
765 * Some H/W events are generated before COMM event
766 * which is emitted during exec(), so perf script
767 * cannot see a correct process name for those events.
768 * Synthesize COMM event to prevent it.
769 */
Namhyung Kime5bed562015-09-30 10:45:24 +0900770 perf_event__synthesize_comm(tool, event,
Namhyung Kime803cf92015-09-22 09:24:55 +0900771 rec->evlist->workload.pid,
772 process_synthesized_event,
773 machine);
Namhyung Kime5bed562015-09-30 10:45:24 +0900774 free(event);
Namhyung Kime803cf92015-09-22 09:24:55 +0900775
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300776 perf_evlist__start_workload(rec->evlist);
Namhyung Kime803cf92015-09-22 09:24:55 +0900777 }
Peter Zijlstra856e9662009-12-16 17:55:55 +0100778
Andi Kleen6619a532014-01-11 13:38:27 -0800779 if (opts->initial_delay) {
780 usleep(opts->initial_delay * 1000);
781 perf_evlist__enable(rec->evlist);
782 }
783
Wang Nan5f9cf592016-04-20 18:59:49 +0000784 trigger_ready(&auxtrace_snapshot_trigger);
Peter Zijlstra649c48a2009-06-24 21:12:48 +0200785 for (;;) {
Yang Shi9f065192015-09-29 14:49:43 -0700786 unsigned long long hits = rec->samples;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200787
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300788 if (record__mmap_read_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000789 trigger_error(&auxtrace_snapshot_trigger);
David Ahern8d3eca22012-08-26 12:24:47 -0600790 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900791 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600792 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200793
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300794 if (auxtrace_record__snapshot_started) {
795 auxtrace_record__snapshot_started = 0;
Wang Nan5f9cf592016-04-20 18:59:49 +0000796 if (!trigger_is_error(&auxtrace_snapshot_trigger))
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300797 record__read_auxtrace_snapshot(rec);
Wang Nan5f9cf592016-04-20 18:59:49 +0000798 if (trigger_is_error(&auxtrace_snapshot_trigger)) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300799 pr_err("AUX area tracing snapshot failed\n");
800 err = -1;
801 goto out_child;
802 }
803 }
804
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200805 if (hits == rec->samples) {
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300806 if (done || draining)
Peter Zijlstra649c48a2009-06-24 21:12:48 +0200807 break;
Arnaldo Carvalho de Melof66a8892014-08-18 17:25:59 -0300808 err = perf_evlist__poll(rec->evlist, -1);
Jiri Olsaa5151142014-06-02 13:44:23 -0400809 /*
810 * Propagate error, only if there's any. Ignore positive
811 * number of returned events and interrupt error.
812 */
813 if (err > 0 || (err < 0 && errno == EINTR))
Namhyung Kim45604712014-05-12 09:47:24 +0900814 err = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200815 waking++;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300816
817 if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
818 draining = true;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200819 }
820
Jiri Olsa774cb492012-11-12 18:34:01 +0100821 /*
822 * When perf is starting the traced process, at the end events
823 * die with the process and we wait for that. Thus no need to
824 * disable events in this case.
825 */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -0300826 if (done && !disabled && !target__none(&opts->target)) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000827 trigger_off(&auxtrace_snapshot_trigger);
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300828 perf_evlist__disable(rec->evlist);
Jiri Olsa27119262012-11-12 18:34:02 +0100829 disabled = true;
830 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200831 }
Wang Nan5f9cf592016-04-20 18:59:49 +0000832 trigger_off(&auxtrace_snapshot_trigger);
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200833
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300834 if (forks && workload_exec_errno) {
Masami Hiramatsu35550da2014-08-14 02:22:43 +0000835 char msg[STRERR_BUFSIZE];
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300836 const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
837 pr_err("Workload failed: %s\n", emsg);
838 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900839 goto out_child;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300840 }
841
Namhyung Kime3d59112015-01-29 17:06:44 +0900842 if (!quiet)
Namhyung Kim45604712014-05-12 09:47:24 +0900843 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -0200844
Namhyung Kim45604712014-05-12 09:47:24 +0900845out_child:
846 if (forks) {
847 int exit_status;
Ingo Molnaraddc2782009-06-02 23:43:11 +0200848
Namhyung Kim45604712014-05-12 09:47:24 +0900849 if (!child_finished)
850 kill(rec->evlist->workload.pid, SIGTERM);
851
852 wait(&exit_status);
853
854 if (err < 0)
855 status = err;
856 else if (WIFEXITED(exit_status))
857 status = WEXITSTATUS(exit_status);
858 else if (WIFSIGNALED(exit_status))
859 signr = WTERMSIG(exit_status);
860 } else
861 status = err;
862
Namhyung Kime3d59112015-01-29 17:06:44 +0900863 /* this will be recalculated during process_buildids() */
864 rec->samples = 0;
865
Wang Nanecfd7a92016-04-13 08:21:07 +0000866 if (!err) {
867 if (!rec->timestamp_filename) {
868 record__finish_output(rec);
869 } else {
870 fd = record__switch_output(rec, true);
871 if (fd < 0) {
872 status = fd;
873 goto out_delete_session;
874 }
875 }
876 }
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -0300877
Namhyung Kime3d59112015-01-29 17:06:44 +0900878 if (!err && !quiet) {
879 char samples[128];
Wang Nanecfd7a92016-04-13 08:21:07 +0000880 const char *postfix = rec->timestamp_filename ?
881 ".<timestamp>" : "";
Namhyung Kime3d59112015-01-29 17:06:44 +0900882
Adrian Hunteref149c22015-04-09 18:53:45 +0300883 if (rec->samples && !rec->opts.full_auxtrace)
Namhyung Kime3d59112015-01-29 17:06:44 +0900884 scnprintf(samples, sizeof(samples),
885 " (%" PRIu64 " samples)", rec->samples);
886 else
887 samples[0] = '\0';
888
Wang Nanecfd7a92016-04-13 08:21:07 +0000889 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
Namhyung Kime3d59112015-01-29 17:06:44 +0900890 perf_data_file__size(file) / 1024.0 / 1024.0,
Wang Nanecfd7a92016-04-13 08:21:07 +0000891 file->path, postfix, samples);
Namhyung Kime3d59112015-01-29 17:06:44 +0900892 }
893
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -0300894out_delete_session:
895 perf_session__delete(session);
Namhyung Kim45604712014-05-12 09:47:24 +0900896 return status;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200897}
Ingo Molnar0e9b20b2009-05-26 09:17:18 +0200898
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300899static void callchain_debug(struct callchain_param *callchain)
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200900{
Kan Liangaad2b212015-01-05 13:23:04 -0500901 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
Jiri Olsaa601fdf2014-02-03 12:44:43 +0100902
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300903 pr_debug("callchain: type %s\n", str[callchain->record_mode]);
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200904
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300905 if (callchain->record_mode == CALLCHAIN_DWARF)
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200906 pr_debug("callchain: stack dump size %d\n",
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300907 callchain->dump_size);
908}
909
910int record_opts__parse_callchain(struct record_opts *record,
911 struct callchain_param *callchain,
912 const char *arg, bool unset)
913{
914 int ret;
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300915 callchain->enabled = !unset;
916
917 /* --no-call-graph */
918 if (unset) {
919 callchain->record_mode = CALLCHAIN_NONE;
920 pr_debug("callchain: disabled\n");
921 return 0;
922 }
923
924 ret = parse_callchain_record_opt(arg, callchain);
925 if (!ret) {
926 /* Enable data address sampling for DWARF unwind. */
927 if (callchain->record_mode == CALLCHAIN_DWARF)
928 record->sample_address = true;
929 callchain_debug(callchain);
930 }
931
932 return ret;
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200933}
934
Kan Liangc421e802015-07-29 05:42:12 -0400935int record_parse_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200936 const char *arg,
937 int unset)
938{
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300939 return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
Jiri Olsa26d33022012-08-07 15:20:47 +0200940}
941
Kan Liangc421e802015-07-29 05:42:12 -0400942int record_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200943 const char *arg __maybe_unused,
944 int unset __maybe_unused)
945{
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -0300946 struct callchain_param *callchain = opt->value;
Kan Liangc421e802015-07-29 05:42:12 -0400947
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -0300948 callchain->enabled = true;
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200949
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -0300950 if (callchain->record_mode == CALLCHAIN_NONE)
951 callchain->record_mode = CALLCHAIN_FP;
Jiri Olsaeb853e82014-02-03 12:44:42 +0100952
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -0300953 callchain_debug(callchain);
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200954 return 0;
955}
956
Jiri Olsaeb853e82014-02-03 12:44:42 +0100957static int perf_record_config(const char *var, const char *value, void *cb)
958{
Namhyung Kim7a29c082015-12-15 10:49:56 +0900959 struct record *rec = cb;
960
961 if (!strcmp(var, "record.build-id")) {
962 if (!strcmp(value, "cache"))
963 rec->no_buildid_cache = false;
964 else if (!strcmp(value, "no-cache"))
965 rec->no_buildid_cache = true;
966 else if (!strcmp(value, "skip"))
967 rec->no_buildid = true;
968 else
969 return -1;
970 return 0;
971 }
Jiri Olsaeb853e82014-02-03 12:44:42 +0100972 if (!strcmp(var, "record.call-graph"))
Namhyung Kim5a2e5e82014-09-23 10:01:44 +0900973 var = "call-graph.record-mode"; /* fall-through */
Jiri Olsaeb853e82014-02-03 12:44:42 +0100974
975 return perf_default_config(var, value, cb);
976}
977
Peter Zijlstra814c8c32015-03-31 00:19:31 +0200978struct clockid_map {
979 const char *name;
980 int clockid;
981};
982
983#define CLOCKID_MAP(n, c) \
984 { .name = n, .clockid = (c), }
985
986#define CLOCKID_END { .name = NULL, }
987
988
989/*
990 * Add the missing ones, we need to build on many distros...
991 */
992#ifndef CLOCK_MONOTONIC_RAW
993#define CLOCK_MONOTONIC_RAW 4
994#endif
995#ifndef CLOCK_BOOTTIME
996#define CLOCK_BOOTTIME 7
997#endif
998#ifndef CLOCK_TAI
999#define CLOCK_TAI 11
1000#endif
1001
1002static const struct clockid_map clockids[] = {
1003 /* available for all events, NMI safe */
1004 CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
1005 CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
1006
1007 /* available for some events */
1008 CLOCKID_MAP("realtime", CLOCK_REALTIME),
1009 CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
1010 CLOCKID_MAP("tai", CLOCK_TAI),
1011
1012 /* available for the lazy */
1013 CLOCKID_MAP("mono", CLOCK_MONOTONIC),
1014 CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
1015 CLOCKID_MAP("real", CLOCK_REALTIME),
1016 CLOCKID_MAP("boot", CLOCK_BOOTTIME),
1017
1018 CLOCKID_END,
1019};
1020
1021static int parse_clockid(const struct option *opt, const char *str, int unset)
1022{
1023 struct record_opts *opts = (struct record_opts *)opt->value;
1024 const struct clockid_map *cm;
1025 const char *ostr = str;
1026
1027 if (unset) {
1028 opts->use_clockid = 0;
1029 return 0;
1030 }
1031
1032 /* no arg passed */
1033 if (!str)
1034 return 0;
1035
1036 /* no setting it twice */
1037 if (opts->use_clockid)
1038 return -1;
1039
1040 opts->use_clockid = true;
1041
1042 /* if its a number, we're done */
1043 if (sscanf(str, "%d", &opts->clockid) == 1)
1044 return 0;
1045
1046 /* allow a "CLOCK_" prefix to the name */
1047 if (!strncasecmp(str, "CLOCK_", 6))
1048 str += 6;
1049
1050 for (cm = clockids; cm->name; cm++) {
1051 if (!strcasecmp(str, cm->name)) {
1052 opts->clockid = cm->clockid;
1053 return 0;
1054 }
1055 }
1056
1057 opts->use_clockid = false;
1058 ui__warning("unknown clockid %s, check man page\n", ostr);
1059 return -1;
1060}
1061
Adrian Huntere9db1312015-04-09 18:53:46 +03001062static int record__parse_mmap_pages(const struct option *opt,
1063 const char *str,
1064 int unset __maybe_unused)
1065{
1066 struct record_opts *opts = opt->value;
1067 char *s, *p;
1068 unsigned int mmap_pages;
1069 int ret;
1070
1071 if (!str)
1072 return -EINVAL;
1073
1074 s = strdup(str);
1075 if (!s)
1076 return -ENOMEM;
1077
1078 p = strchr(s, ',');
1079 if (p)
1080 *p = '\0';
1081
1082 if (*s) {
1083 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
1084 if (ret)
1085 goto out_free;
1086 opts->mmap_pages = mmap_pages;
1087 }
1088
1089 if (!p) {
1090 ret = 0;
1091 goto out_free;
1092 }
1093
1094 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
1095 if (ret)
1096 goto out_free;
1097
1098 opts->auxtrace_mmap_pages = mmap_pages;
1099
1100out_free:
1101 free(s);
1102 return ret;
1103}
1104
Namhyung Kime5b2c202014-10-23 00:15:46 +09001105static const char * const __record_usage[] = {
Mike Galbraith9e0967532009-05-28 16:25:34 +02001106 "perf record [<options>] [<command>]",
1107 "perf record [<options>] -- <command> [<options>]",
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001108 NULL
1109};
Namhyung Kime5b2c202014-10-23 00:15:46 +09001110const char * const *record_usage = __record_usage;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001111
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001112/*
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001113 * XXX Ideally would be local to cmd_record() and passed to a record__new
1114 * because we need to have access to it in record__exit, that is called
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001115 * after cmd_record() exits, but since record_options need to be accessible to
1116 * builtin-script, leave it here.
1117 *
1118 * At least we don't ouch it in all the other functions here directly.
1119 *
1120 * Just say no to tons of global variables, sigh.
1121 */
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001122static struct record record = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001123 .opts = {
Andi Kleen8affc2b2014-07-31 14:45:04 +08001124 .sample_time = true,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001125 .mmap_pages = UINT_MAX,
1126 .user_freq = UINT_MAX,
1127 .user_interval = ULLONG_MAX,
Arnaldo Carvalho de Melo447a6012012-05-22 13:14:18 -03001128 .freq = 4000,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001129 .target = {
1130 .uses_mmap = true,
Adrian Hunter3aa59392013-11-15 15:52:29 +02001131 .default_per_cpu = true,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001132 },
Kan Liang9d9cad72015-06-17 09:51:11 -04001133 .proc_map_timeout = 500,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001134 },
Namhyung Kime3d59112015-01-29 17:06:44 +09001135 .tool = {
1136 .sample = process_sample_event,
1137 .fork = perf_event__process_fork,
Adrian Huntercca84822015-08-19 17:29:21 +03001138 .exit = perf_event__process_exit,
Namhyung Kime3d59112015-01-29 17:06:44 +09001139 .comm = perf_event__process_comm,
1140 .mmap = perf_event__process_mmap,
1141 .mmap2 = perf_event__process_mmap2,
Adrian Huntercca84822015-08-19 17:29:21 +03001142 .ordered_events = true,
Namhyung Kime3d59112015-01-29 17:06:44 +09001143 },
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001144};
Frederic Weisbecker7865e812010-04-14 19:42:07 +02001145
Namhyung Kim76a26542015-10-22 23:28:32 +09001146const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1147 "\n\t\t\t\tDefault: fp";
Arnaldo Carvalho de Melo61eaa3b2012-10-01 15:20:58 -03001148
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001149/*
1150 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
1151 * with it and switch to use the library functions in perf_evlist that came
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001152 * from builtin-record.c, i.e. use record_opts,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001153 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
1154 * using pipes, etc.
1155 */
Namhyung Kime5b2c202014-10-23 00:15:46 +09001156struct option __record_options[] = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001157 OPT_CALLBACK('e', "event", &record.evlist, "event",
Thomas Gleixner86847b62009-06-06 12:24:17 +02001158 "event selector. use 'perf list' to list available events",
Jiri Olsaf120f9d2011-07-14 11:25:32 +02001159 parse_events_option),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001160 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
Li Zefanc171b552009-10-15 11:22:07 +08001161 "event filter", parse_filter),
Wang Nan4ba1faa2015-07-10 07:36:10 +00001162 OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
1163 NULL, "don't record events from perf itself",
1164 exclude_perf),
Namhyung Kimbea03402012-04-26 14:15:15 +09001165 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001166 "record events on existing process id"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001167 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001168 "record events on existing thread id"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001169 OPT_INTEGER('r', "realtime", &record.realtime_prio,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001170 "collect data with this RT SCHED_FIFO priority"),
Arnaldo Carvalho de Melo509051e2014-01-14 17:52:14 -03001171 OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
Kirill Smelkovacac03f2011-01-12 17:59:36 +03001172 "collect data without buffering"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001173 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
Frederic Weisbeckerdaac07b2009-08-13 10:27:19 +02001174 "collect raw sample records from all opened counters"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001175 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001176 "system-wide collection from all CPUs"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001177 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
Stephane Eranianc45c6ea2010-05-28 12:00:01 +02001178 "list of cpus to monitor"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001179 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
Jiri Olsaf5fc1412013-10-15 16:27:32 +02001180 OPT_STRING('o', "output", &record.file.path, "file",
Ingo Molnarabaff322009-06-02 22:59:57 +02001181 "output file name"),
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001182 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1183 &record.opts.no_inherit_set,
1184 "child tasks do not inherit counters"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001185 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
Adrian Huntere9db1312015-04-09 18:53:46 +03001186 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
1187 "number of mmap data pages and AUX area tracing mmap pages",
1188 record__parse_mmap_pages),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001189 OPT_BOOLEAN(0, "group", &record.opts.group,
Lin Ming43bece72011-08-17 18:42:07 +08001190 "put the counters into a counter group"),
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001191 OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001192 NULL, "enables call-graph recording" ,
1193 &record_callchain_opt),
1194 OPT_CALLBACK(0, "call-graph", &record.opts,
Namhyung Kim76a26542015-10-22 23:28:32 +09001195 "record_mode[,record_size]", record_callchain_help,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001196 &record_parse_callchain_opt),
Ian Munsiec0555642010-04-13 18:37:33 +10001197 OPT_INCR('v', "verbose", &verbose,
Ingo Molnar3da297a2009-06-07 17:39:02 +02001198 "be more verbose (show counter open errors, etc)"),
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001199 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001200 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001201 "per thread counts"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001202 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
Adrian Hunter3abebc52015-07-06 14:51:01 +03001203 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
1204 &record.opts.sample_time_set,
1205 "Record the sample timestamps"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001206 OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001207 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001208 "don't sample"),
Wang Nand2db9a92016-01-25 09:56:19 +00001209 OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
1210 &record.no_buildid_cache_set,
1211 "do not update the buildid cache"),
1212 OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
1213 &record.no_buildid_set,
1214 "do not collect buildids in perf.data"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001215 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
Stephane Eranian023695d2011-02-14 11:20:01 +02001216 "monitor event in cgroup name only",
1217 parse_cgroups),
Arnaldo Carvalho de Meloa6205a32014-01-14 17:58:12 -03001218 OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
Andi Kleen6619a532014-01-11 13:38:27 -08001219 "ms to wait before starting measurement after program start"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001220 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
1221 "user to profile"),
Stephane Eraniana5aabda2012-03-08 23:47:45 +01001222
1223 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
1224 "branch any", "sample any taken branches",
1225 parse_branch_stack),
1226
1227 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
1228 "branch filter mask", "branch stack filter modes",
Roberto Agostino Vitillobdfebd82012-02-09 23:21:02 +01001229 parse_branch_stack),
Andi Kleen05484292013-01-24 16:10:29 +01001230 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
1231 "sample by weight (on special events only)"),
Andi Kleen475eeab2013-09-20 07:40:43 -07001232 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
1233 "sample transaction flags (special events only)"),
Adrian Hunter3aa59392013-11-15 15:52:29 +02001234 OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
1235 "use per-thread mmaps"),
Stephane Eranianbcc84ec2015-08-31 18:41:12 +02001236 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
1237 "sample selected machine registers on interrupt,"
1238 " use -I ? to list register names", parse_regs),
Andi Kleen85c273d2015-02-24 15:13:40 -08001239 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
1240 "Record running/enabled time of read (:S) events"),
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001241 OPT_CALLBACK('k', "clockid", &record.opts,
1242 "clockid", "clockid to use for events, see clock_gettime()",
1243 parse_clockid),
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001244 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
1245 "opts", "AUX area tracing Snapshot Mode", ""),
Kan Liang9d9cad72015-06-17 09:51:11 -04001246 OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
1247 "per thread proc mmap processing timeout in ms"),
Adrian Hunterb757bb02015-07-21 12:44:04 +03001248 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1249 "Record context switch events"),
Jiri Olsa85723882016-02-15 09:34:31 +01001250 OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
1251 "Configure all used events to run in kernel space.",
1252 PARSE_OPT_EXCLUSIVE),
1253 OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
1254 "Configure all used events to run in user space.",
1255 PARSE_OPT_EXCLUSIVE),
Wang Nan71dc23262015-10-14 12:41:19 +00001256 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1257 "clang binary to use for compiling BPF scriptlets"),
1258 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1259 "options passed to clang when compiling BPF scriptlets"),
He Kuang7efe0e02015-12-14 10:39:23 +00001260 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1261 "file", "vmlinux pathname"),
Namhyung Kim61566812016-01-11 22:37:09 +09001262 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
1263 "Record build-id of all DSOs regardless of hits"),
Wang Nanecfd7a92016-04-13 08:21:07 +00001264 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1265 "append timestamp to output filename"),
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001266 OPT_END()
1267};
1268
Namhyung Kime5b2c202014-10-23 00:15:46 +09001269struct option *record_options = __record_options;
1270
Irina Tirdea1d037ca2012-09-11 01:15:03 +03001271int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001272{
Adrian Hunteref149c22015-04-09 18:53:45 +03001273 int err;
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001274 struct record *rec = &record;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001275 char errbuf[BUFSIZ];
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001276
Wang Nan48e1cab2015-12-14 10:39:22 +00001277#ifndef HAVE_LIBBPF_SUPPORT
1278# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
1279 set_nobuild('\0', "clang-path", true);
1280 set_nobuild('\0', "clang-opt", true);
1281# undef set_nobuild
1282#endif
1283
He Kuang7efe0e02015-12-14 10:39:23 +00001284#ifndef HAVE_BPF_PROLOGUE
1285# if !defined (HAVE_DWARF_SUPPORT)
1286# define REASON "NO_DWARF=1"
1287# elif !defined (HAVE_LIBBPF_SUPPORT)
1288# define REASON "NO_LIBBPF=1"
1289# else
1290# define REASON "this architecture doesn't support BPF prologue"
1291# endif
1292# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
1293 set_nobuild('\0', "vmlinux", true);
1294# undef set_nobuild
1295# undef REASON
1296#endif
1297
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001298 rec->evlist = perf_evlist__new();
1299 if (rec->evlist == NULL)
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -02001300 return -ENOMEM;
1301
Jiri Olsaeb853e82014-02-03 12:44:42 +01001302 perf_config(perf_record_config, rec);
1303
Tom Zanussibca647a2010-11-10 08:11:30 -06001304 argc = parse_options(argc, argv, record_options, record_usage,
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001305 PARSE_OPT_STOP_AT_NON_OPTION);
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001306 if (!argc && target__none(&rec->opts.target))
Tom Zanussibca647a2010-11-10 08:11:30 -06001307 usage_with_options(record_usage, record_options);
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001308
Namhyung Kimbea03402012-04-26 14:15:15 +09001309 if (nr_cgroups && !rec->opts.target.system_wide) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001310 usage_with_options_msg(record_usage, record_options,
1311 "cgroup monitoring only available in system-wide mode");
1312
Stephane Eranian023695d2011-02-14 11:20:01 +02001313 }
Adrian Hunterb757bb02015-07-21 12:44:04 +03001314 if (rec->opts.record_switch_events &&
1315 !perf_can_record_switch_events()) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001316 ui__error("kernel does not support recording context switch events\n");
1317 parse_options_usage(record_usage, record_options, "switch-events", 0);
1318 return -EINVAL;
Adrian Hunterb757bb02015-07-21 12:44:04 +03001319 }
Stephane Eranian023695d2011-02-14 11:20:01 +02001320
Adrian Hunteref149c22015-04-09 18:53:45 +03001321 if (!rec->itr) {
1322 rec->itr = auxtrace_record__init(rec->evlist, &err);
1323 if (err)
1324 return err;
1325 }
1326
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001327 err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
1328 rec->opts.auxtrace_snapshot_opts);
1329 if (err)
1330 return err;
1331
Wang Nand7888572016-04-08 15:07:24 +00001332 err = bpf__setup_stdout(rec->evlist);
1333 if (err) {
1334 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
1335 pr_err("ERROR: Setup BPF stdout failed: %s\n",
1336 errbuf);
1337 return err;
1338 }
1339
Adrian Hunteref149c22015-04-09 18:53:45 +03001340 err = -ENOMEM;
1341
Namhyung Kim0a7e6d12014-08-12 15:40:45 +09001342 symbol__init(NULL);
Arnaldo Carvalho de Melobaa2f6c2010-11-26 19:39:15 -02001343
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001344 if (symbol_conf.kptr_restrict)
Arnaldo Carvalho de Melo646aaea62011-05-27 11:00:41 -03001345 pr_warning(
1346"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
1347"check /proc/sys/kernel/kptr_restrict.\n\n"
1348"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
1349"file is not found in the buildid cache or in the vmlinux path.\n\n"
1350"Samples in kernel modules won't be resolved at all.\n\n"
1351"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
1352"even with a suitable vmlinux or kallsyms file.\n\n");
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001353
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001354 if (rec->no_buildid_cache || rec->no_buildid)
Stephane Eraniana1ac1d32010-06-17 11:39:01 +02001355 disable_buildid_cache();
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001356
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001357 if (rec->evlist->nr_entries == 0 &&
1358 perf_evlist__add_default(rec->evlist) < 0) {
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001359 pr_err("Not enough memory for event selector list\n");
1360 goto out_symbol_exit;
Peter Zijlstrabbd36e52009-06-11 23:11:50 +02001361 }
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001362
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001363 if (rec->opts.target.tid && !rec->opts.no_inherit_set)
1364 rec->opts.no_inherit = true;
1365
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001366 err = target__validate(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001367 if (err) {
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001368 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001369 ui__warning("%s", errbuf);
1370 }
Namhyung Kim4bd0f2d2012-04-26 14:15:18 +09001371
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001372 err = target__parse_uid(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001373 if (err) {
1374 int saved_errno = errno;
1375
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001376 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim3780f482012-05-29 13:22:57 +09001377 ui__error("%s", errbuf);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001378
1379 err = -saved_errno;
Namhyung Kim8fa60e12013-03-15 14:48:51 +09001380 goto out_symbol_exit;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001381 }
Arnaldo Carvalho de Melo0d37aa32012-01-19 14:08:15 -02001382
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001383 err = -ENOMEM;
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001384 if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -02001385 usage_with_options(record_usage, record_options);
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001386
Adrian Hunteref149c22015-04-09 18:53:45 +03001387 err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
1388 if (err)
1389 goto out_symbol_exit;
1390
Namhyung Kim61566812016-01-11 22:37:09 +09001391 /*
1392 * We take all buildids when the file contains
1393 * AUX area tracing data because we do not decode the
1394 * trace because it would take too long.
1395 */
1396 if (rec->opts.full_auxtrace)
1397 rec->buildid_all = true;
1398
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001399 if (record_opts__config(&rec->opts)) {
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001400 err = -EINVAL;
Arnaldo Carvalho de Melo03ad9742014-01-03 15:56:06 -03001401 goto out_symbol_exit;
Mike Galbraith7e4ff9e2009-10-12 07:56:03 +02001402 }
1403
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001404 err = __cmd_record(&record, argc, argv);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03001405out_symbol_exit:
Namhyung Kim45604712014-05-12 09:47:24 +09001406 perf_evlist__delete(rec->evlist);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03001407 symbol__exit();
Adrian Hunteref149c22015-04-09 18:53:45 +03001408 auxtrace_record__free(rec->itr);
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001409 return err;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001410}
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001411
1412static void snapshot_sig_handler(int sig __maybe_unused)
1413{
Wang Nan5f9cf592016-04-20 18:59:49 +00001414 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1415 trigger_hit(&auxtrace_snapshot_trigger);
1416 auxtrace_record__snapshot_started = 1;
1417 if (auxtrace_record__snapshot_start(record.itr))
1418 trigger_error(&auxtrace_snapshot_trigger);
1419 }
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001420}