blob: 73ce651c84f678cbbf8c8aaf2236b651738c6390 [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 Olsaf5fc14122013-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 Olsaf5fc14122013-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;
Wang Nan09fa4f42016-05-23 07:13:40 +000091 u64 end = head, start = old;
Jiri Olsa918512b2013-09-12 18:39:35 +020092 unsigned char *data = md->base + page_size;
Peter Zijlstrade9ac072009-04-08 15:01:31 +020093 unsigned long size;
94 void *buf;
David Ahern8d3eca22012-08-26 12:24:47 -060095 int rc = 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +020096
Wang Nan09fa4f42016-05-23 07:13:40 +000097 if (start == end)
David Ahern8d3eca22012-08-26 12:24:47 -060098 return 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +020099
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200100 rec->samples++;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200101
Wang Nan09fa4f42016-05-23 07:13:40 +0000102 size = end - start;
Wang Nan2d11c652016-05-23 07:13:39 +0000103 if (size > (unsigned long)(md->mask) + 1) {
104 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
105
106 md->prev = head;
107 perf_evlist__mmap_consume(rec->evlist, idx);
108 return 0;
109 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200110
Wang Nan09fa4f42016-05-23 07:13:40 +0000111 if ((start & md->mask) + size != (end & md->mask)) {
112 buf = &data[start & md->mask];
113 size = md->mask + 1 - (start & md->mask);
114 start += 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
Wang Nan09fa4f42016-05-23 07:13:40 +0000122 buf = &data[start & md->mask];
123 size = end - start;
124 start += size;
Ingo Molnar021e9f42009-06-03 19:27:19 +0200125
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300126 if (record__write(rec, buf, size) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600127 rc = -1;
128 goto out;
129 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200130
Wang Nan09fa4f42016-05-23 07:13:40 +0000131 md->prev = head;
Arnaldo Carvalho de Meloe5685732014-09-17 16:42:58 -0300132 perf_evlist__mmap_consume(rec->evlist, idx);
David Ahern8d3eca22012-08-26 12:24:47 -0600133out:
134 return rc;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200135}
136
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300137static volatile int done;
138static volatile int signr = -1;
139static volatile int child_finished;
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000140
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300141static volatile int auxtrace_record__snapshot_started;
Wang Nan5f9cf592016-04-20 18:59:49 +0000142static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000143static DEFINE_TRIGGER(switch_output_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300144
145static void sig_handler(int sig)
146{
147 if (sig == SIGCHLD)
148 child_finished = 1;
149 else
150 signr = sig;
151
152 done = 1;
153}
154
155static void record__sig_exit(void)
156{
157 if (signr == -1)
158 return;
159
160 signal(signr, SIG_DFL);
161 raise(signr);
162}
163
Adrian Huntere31f0d02015-04-30 17:37:27 +0300164#ifdef HAVE_AUXTRACE_SUPPORT
165
Adrian Hunteref149c22015-04-09 18:53:45 +0300166static int record__process_auxtrace(struct perf_tool *tool,
167 union perf_event *event, void *data1,
168 size_t len1, void *data2, size_t len2)
169{
170 struct record *rec = container_of(tool, struct record, tool);
Adrian Hunter99fa2982015-04-30 17:37:25 +0300171 struct perf_data_file *file = &rec->file;
Adrian Hunteref149c22015-04-09 18:53:45 +0300172 size_t padding;
173 u8 pad[8] = {0};
174
Adrian Hunter99fa2982015-04-30 17:37:25 +0300175 if (!perf_data_file__is_pipe(file)) {
176 off_t file_offset;
177 int fd = perf_data_file__fd(file);
178 int err;
179
180 file_offset = lseek(fd, 0, SEEK_CUR);
181 if (file_offset == -1)
182 return -1;
183 err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index,
184 event, file_offset);
185 if (err)
186 return err;
187 }
188
Adrian Hunteref149c22015-04-09 18:53:45 +0300189 /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */
190 padding = (len1 + len2) & 7;
191 if (padding)
192 padding = 8 - padding;
193
194 record__write(rec, event, event->header.size);
195 record__write(rec, data1, len1);
196 if (len2)
197 record__write(rec, data2, len2);
198 record__write(rec, &pad, padding);
199
200 return 0;
201}
202
203static int record__auxtrace_mmap_read(struct record *rec,
204 struct auxtrace_mmap *mm)
205{
206 int ret;
207
208 ret = auxtrace_mmap__read(mm, rec->itr, &rec->tool,
209 record__process_auxtrace);
210 if (ret < 0)
211 return ret;
212
213 if (ret)
214 rec->samples++;
215
216 return 0;
217}
218
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300219static int record__auxtrace_mmap_read_snapshot(struct record *rec,
220 struct auxtrace_mmap *mm)
221{
222 int ret;
223
224 ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool,
225 record__process_auxtrace,
226 rec->opts.auxtrace_snapshot_size);
227 if (ret < 0)
228 return ret;
229
230 if (ret)
231 rec->samples++;
232
233 return 0;
234}
235
236static int record__auxtrace_read_snapshot_all(struct record *rec)
237{
238 int i;
239 int rc = 0;
240
241 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
242 struct auxtrace_mmap *mm =
243 &rec->evlist->mmap[i].auxtrace_mmap;
244
245 if (!mm->base)
246 continue;
247
248 if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) {
249 rc = -1;
250 goto out;
251 }
252 }
253out:
254 return rc;
255}
256
257static void record__read_auxtrace_snapshot(struct record *rec)
258{
259 pr_debug("Recording AUX area tracing snapshot\n");
260 if (record__auxtrace_read_snapshot_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000261 trigger_error(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300262 } else {
Wang Nan5f9cf592016-04-20 18:59:49 +0000263 if (auxtrace_record__snapshot_finish(rec->itr))
264 trigger_error(&auxtrace_snapshot_trigger);
265 else
266 trigger_ready(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300267 }
268}
269
Adrian Huntere31f0d02015-04-30 17:37:27 +0300270#else
271
272static inline
273int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
274 struct auxtrace_mmap *mm __maybe_unused)
275{
276 return 0;
277}
278
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300279static inline
280void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
281{
282}
283
284static inline
285int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
286{
287 return 0;
288}
289
Adrian Huntere31f0d02015-04-30 17:37:27 +0300290#endif
291
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300292static int record__open(struct record *rec)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200293{
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300294 char msg[512];
Jiri Olsa6a4bb042012-08-08 12:22:36 +0200295 struct perf_evsel *pos;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200296 struct perf_evlist *evlist = rec->evlist;
297 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300298 struct record_opts *opts = &rec->opts;
David Ahern8d3eca22012-08-26 12:24:47 -0600299 int rc = 0;
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200300
Arnaldo Carvalho de Meloe68ae9c2016-04-11 18:15:29 -0300301 perf_evlist__config(evlist, opts, &callchain_param);
Jiri Olsacac21422012-11-12 18:34:00 +0100302
Arnaldo Carvalho de Melo0050f7a2014-01-10 10:37:27 -0300303 evlist__for_each(evlist, pos) {
Ingo Molnar3da297a2009-06-07 17:39:02 +0200304try_again:
Kan Liangd988d5e2015-08-21 02:23:14 -0400305 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300306 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300307 if (verbose)
Arnaldo Carvalho de Meloc0a54342012-12-13 14:16:30 -0300308 ui__warning("%s\n", msg);
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300309 goto try_again;
310 }
David Ahernca6a4252011-03-25 13:11:11 -0600311
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300312 rc = -errno;
313 perf_evsel__open_strerror(pos, &opts->target,
314 errno, msg, sizeof(msg));
315 ui__error("%s\n", msg);
David Ahern8d3eca22012-08-26 12:24:47 -0600316 goto out;
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300317 }
Li Zefanc171b552009-10-15 11:22:07 +0800318 }
Arnaldo Carvalho de Meloa43d3f02010-12-25 12:12:25 -0200319
Arnaldo Carvalho de Melo23d4aad2015-03-24 19:23:47 -0300320 if (perf_evlist__apply_filters(evlist, &pos)) {
321 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
322 pos->filter, perf_evsel__name(pos), errno,
Masami Hiramatsu35550da2014-08-14 02:22:43 +0000323 strerror_r(errno, msg, sizeof(msg)));
David Ahern8d3eca22012-08-26 12:24:47 -0600324 rc = -1;
325 goto out;
Frederic Weisbecker0a102472011-02-26 04:51:54 +0100326 }
327
Adrian Hunteref149c22015-04-09 18:53:45 +0300328 if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300329 opts->auxtrace_mmap_pages,
330 opts->auxtrace_snapshot_mode) < 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600331 if (errno == EPERM) {
332 pr_err("Permission error mapping pages.\n"
333 "Consider increasing "
334 "/proc/sys/kernel/perf_event_mlock_kb,\n"
335 "or try again with a smaller value of -m/--mmap_pages.\n"
Adrian Hunteref149c22015-04-09 18:53:45 +0300336 "(current value: %u,%u)\n",
337 opts->mmap_pages, opts->auxtrace_mmap_pages);
David Ahern8d3eca22012-08-26 12:24:47 -0600338 rc = -errno;
David Ahern8d3eca22012-08-26 12:24:47 -0600339 } else {
Masami Hiramatsu35550da2014-08-14 02:22:43 +0000340 pr_err("failed to mmap with %d (%s)\n", errno,
341 strerror_r(errno, msg, sizeof(msg)));
Wang Nan95c36562016-02-26 09:32:17 +0000342 if (errno)
343 rc = -errno;
344 else
345 rc = -EINVAL;
David Ahern8d3eca22012-08-26 12:24:47 -0600346 }
347 goto out;
Nelson Elhage18e60932011-12-19 08:39:31 -0500348 }
Arnaldo Carvalho de Melo0a27d7f2011-01-14 15:50:51 -0200349
Jiri Olsa563aecb2013-06-05 13:35:06 +0200350 session->evlist = evlist;
Arnaldo Carvalho de Melo7b56cce2012-08-01 19:31:00 -0300351 perf_session__set_id_hdr_size(session);
David Ahern8d3eca22012-08-26 12:24:47 -0600352out:
353 return rc;
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200354}
355
Namhyung Kime3d59112015-01-29 17:06:44 +0900356static int process_sample_event(struct perf_tool *tool,
357 union perf_event *event,
358 struct perf_sample *sample,
359 struct perf_evsel *evsel,
360 struct machine *machine)
361{
362 struct record *rec = container_of(tool, struct record, tool);
363
364 rec->samples++;
365
366 return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
367}
368
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300369static int process_buildids(struct record *rec)
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200370{
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200371 struct perf_data_file *file = &rec->file;
372 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200373
He Kuang457ae942015-05-28 13:17:30 +0000374 if (file->size == 0)
Arnaldo Carvalho de Melo9f591fd2010-03-11 15:53:11 -0300375 return 0;
376
Namhyung Kim00dc8652014-11-04 10:14:32 +0900377 /*
378 * During this process, it'll load kernel map and replace the
379 * dso->long_name to a real pathname it found. In this case
380 * we prefer the vmlinux path like
381 * /lib/modules/3.16.4/build/vmlinux
382 *
383 * rather than build-id path (in debug directory).
384 * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551
385 */
386 symbol_conf.ignore_vmlinux_buildid = true;
387
Namhyung Kim61566812016-01-11 22:37:09 +0900388 /*
389 * If --buildid-all is given, it marks all DSO regardless of hits,
390 * so no need to process samples.
391 */
392 if (rec->buildid_all)
393 rec->tool.sample = NULL;
394
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300395 return perf_session__process_events(session);
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200396}
397
Arnaldo Carvalho de Melo8115d602011-01-29 14:01:45 -0200398static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800399{
400 int err;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200401 struct perf_tool *tool = data;
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800402 /*
403 *As for guest kernel when processing subcommand record&report,
404 *we arrange module mmap prior to guest kernel mmap and trigger
405 *a preload dso because default guest module symbols are loaded
406 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
407 *method is used to avoid symbol missing when the first addr is
408 *in module instead of in guest kernel.
409 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200410 err = perf_event__synthesize_modules(tool, process_synthesized_event,
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200411 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800412 if (err < 0)
413 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300414 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800415
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800416 /*
417 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
418 * have no _text sometimes.
419 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200420 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
Adrian Hunter0ae617b2014-01-29 16:14:40 +0200421 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800422 if (err < 0)
423 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300424 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800425}
426
Frederic Weisbecker98402802010-05-02 22:05:29 +0200427static struct perf_event_header finished_round_event = {
428 .size = sizeof(struct perf_event_header),
429 .type = PERF_RECORD_FINISHED_ROUND,
430};
431
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300432static int record__mmap_read_all(struct record *rec)
Frederic Weisbecker98402802010-05-02 22:05:29 +0200433{
Jiri Olsadcabb502014-07-25 16:56:16 +0200434 u64 bytes_written = rec->bytes_written;
Peter Zijlstra0e2e63d2010-05-20 14:45:26 +0200435 int i;
David Ahern8d3eca22012-08-26 12:24:47 -0600436 int rc = 0;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200437
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200438 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
Adrian Hunteref149c22015-04-09 18:53:45 +0300439 struct auxtrace_mmap *mm = &rec->evlist->mmap[i].auxtrace_mmap;
440
David Ahern8d3eca22012-08-26 12:24:47 -0600441 if (rec->evlist->mmap[i].base) {
Arnaldo Carvalho de Meloe5685732014-09-17 16:42:58 -0300442 if (record__mmap_read(rec, i) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600443 rc = -1;
444 goto out;
445 }
446 }
Adrian Hunteref149c22015-04-09 18:53:45 +0300447
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300448 if (mm->base && !rec->opts.auxtrace_snapshot_mode &&
Adrian Hunteref149c22015-04-09 18:53:45 +0300449 record__auxtrace_mmap_read(rec, mm) != 0) {
450 rc = -1;
451 goto out;
452 }
Frederic Weisbecker98402802010-05-02 22:05:29 +0200453 }
454
Jiri Olsadcabb502014-07-25 16:56:16 +0200455 /*
456 * Mark the round finished in case we wrote
457 * at least one event.
458 */
459 if (bytes_written != rec->bytes_written)
460 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
David Ahern8d3eca22012-08-26 12:24:47 -0600461
462out:
463 return rc;
Frederic Weisbecker98402802010-05-02 22:05:29 +0200464}
465
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300466static void record__init_features(struct record *rec)
David Ahern57706ab2013-11-06 11:41:34 -0700467{
David Ahern57706ab2013-11-06 11:41:34 -0700468 struct perf_session *session = rec->session;
469 int feat;
470
471 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
472 perf_header__set_feat(&session->header, feat);
473
474 if (rec->no_buildid)
475 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
476
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300477 if (!have_tracepoints(&rec->evlist->entries))
David Ahern57706ab2013-11-06 11:41:34 -0700478 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
479
480 if (!rec->opts.branch_stack)
481 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
Adrian Hunteref149c22015-04-09 18:53:45 +0300482
483 if (!rec->opts.full_auxtrace)
484 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
Jiri Olsaffa517a2015-10-25 15:51:43 +0100485
486 perf_header__clear_feat(&session->header, HEADER_STAT);
David Ahern57706ab2013-11-06 11:41:34 -0700487}
488
Wang Nane1ab48b2016-02-26 09:32:10 +0000489static void
490record__finish_output(struct record *rec)
491{
492 struct perf_data_file *file = &rec->file;
493 int fd = perf_data_file__fd(file);
494
495 if (file->is_pipe)
496 return;
497
498 rec->session->header.data_size += rec->bytes_written;
499 file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR);
500
501 if (!rec->no_buildid) {
502 process_buildids(rec);
503
504 if (rec->buildid_all)
505 dsos__hit_all(rec->session);
506 }
507 perf_session__write_header(rec->session, rec->evlist, fd, true);
508
509 return;
510}
511
Wang Nanbe7b0c92016-04-20 18:59:54 +0000512static int record__synthesize_workload(struct record *rec)
513{
514 struct {
515 struct thread_map map;
516 struct thread_map_data map_data;
517 } thread_map;
518
519 thread_map.map.nr = 1;
520 thread_map.map.map[0].pid = rec->evlist->workload.pid;
521 thread_map.map.map[0].comm = NULL;
522 return perf_event__synthesize_thread_map(&rec->tool, &thread_map.map,
523 process_synthesized_event,
524 &rec->session->machines.host,
525 rec->opts.sample_address,
526 rec->opts.proc_map_timeout);
527}
528
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000529static int record__synthesize(struct record *rec);
530
Wang Nanecfd7a92016-04-13 08:21:07 +0000531static int
532record__switch_output(struct record *rec, bool at_exit)
533{
534 struct perf_data_file *file = &rec->file;
535 int fd, err;
536
537 /* Same Size: "2015122520103046"*/
538 char timestamp[] = "InvalidTimestamp";
539
540 rec->samples = 0;
541 record__finish_output(rec);
542 err = fetch_current_timestamp(timestamp, sizeof(timestamp));
543 if (err) {
544 pr_err("Failed to get current timestamp\n");
545 return -EINVAL;
546 }
547
548 fd = perf_data_file__switch(file, timestamp,
549 rec->session->header.data_offset,
550 at_exit);
551 if (fd >= 0 && !at_exit) {
552 rec->bytes_written = 0;
553 rec->session->header.data_size = 0;
554 }
555
556 if (!quiet)
557 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
558 file->path, timestamp);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000559
560 /* Output tracking events */
Wang Nanbe7b0c92016-04-20 18:59:54 +0000561 if (!at_exit) {
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000562 record__synthesize(rec);
563
Wang Nanbe7b0c92016-04-20 18:59:54 +0000564 /*
565 * In 'perf record --switch-output' without -a,
566 * record__synthesize() in record__switch_output() won't
567 * generate tracking events because there's no thread_map
568 * in evlist. Which causes newly created perf.data doesn't
569 * contain map and comm information.
570 * Create a fake thread_map and directly call
571 * perf_event__synthesize_thread_map() for those events.
572 */
573 if (target__none(&rec->opts.target))
574 record__synthesize_workload(rec);
575 }
Wang Nanecfd7a92016-04-13 08:21:07 +0000576 return fd;
577}
578
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300579static volatile int workload_exec_errno;
580
581/*
582 * perf_evlist__prepare_workload will send a SIGUSR1
583 * if the fork fails, since we asked by setting its
584 * want_signal to true.
585 */
Namhyung Kim45604712014-05-12 09:47:24 +0900586static void workload_exec_failed_signal(int signo __maybe_unused,
587 siginfo_t *info,
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300588 void *ucontext __maybe_unused)
589{
590 workload_exec_errno = info->si_value.sival_int;
591 done = 1;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300592 child_finished = 1;
593}
594
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300595static void snapshot_sig_handler(int sig);
596
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200597int __weak
598perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
599 struct perf_tool *tool __maybe_unused,
600 perf_event__handler_t process __maybe_unused,
601 struct machine *machine __maybe_unused)
602{
603 return 0;
604}
605
Wang Nanc45c86e2016-02-26 09:32:07 +0000606static int record__synthesize(struct record *rec)
607{
608 struct perf_session *session = rec->session;
609 struct machine *machine = &session->machines.host;
610 struct perf_data_file *file = &rec->file;
611 struct record_opts *opts = &rec->opts;
612 struct perf_tool *tool = &rec->tool;
613 int fd = perf_data_file__fd(file);
614 int err = 0;
615
616 if (file->is_pipe) {
617 err = perf_event__synthesize_attrs(tool, session,
618 process_synthesized_event);
619 if (err < 0) {
620 pr_err("Couldn't synthesize attrs.\n");
621 goto out;
622 }
623
624 if (have_tracepoints(&rec->evlist->entries)) {
625 /*
626 * FIXME err <= 0 here actually means that
627 * there were no tracepoints so its not really
628 * an error, just that we don't need to
629 * synthesize anything. We really have to
630 * return this more properly and also
631 * propagate errors that now are calling die()
632 */
633 err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
634 process_synthesized_event);
635 if (err <= 0) {
636 pr_err("Couldn't record tracing data.\n");
637 goto out;
638 }
639 rec->bytes_written += err;
640 }
641 }
642
Adrian Hunter46bc29b2016-03-08 10:38:44 +0200643 err = perf_event__synth_time_conv(rec->evlist->mmap[0].base, tool,
644 process_synthesized_event, machine);
645 if (err)
646 goto out;
647
Wang Nanc45c86e2016-02-26 09:32:07 +0000648 if (rec->opts.full_auxtrace) {
649 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
650 session, process_synthesized_event);
651 if (err)
652 goto out;
653 }
654
655 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
656 machine);
657 WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
658 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
659 "Check /proc/kallsyms permission or run as root.\n");
660
661 err = perf_event__synthesize_modules(tool, process_synthesized_event,
662 machine);
663 WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
664 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
665 "Check /proc/modules permission or run as root.\n");
666
667 if (perf_guest) {
668 machines__process_guests(&session->machines,
669 perf_event__synthesize_guest_os, tool);
670 }
671
672 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
673 process_synthesized_event, opts->sample_address,
674 opts->proc_map_timeout);
675out:
676 return err;
677}
678
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300679static int __cmd_record(struct record *rec, int argc, const char **argv)
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200680{
David Ahern57706ab2013-11-06 11:41:34 -0700681 int err;
Namhyung Kim45604712014-05-12 09:47:24 +0900682 int status = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200683 unsigned long waking = 0;
Zhang, Yanmin46be6042010-03-18 11:36:04 -0300684 const bool forks = argc > 0;
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300685 struct machine *machine;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200686 struct perf_tool *tool = &rec->tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300687 struct record_opts *opts = &rec->opts;
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200688 struct perf_data_file *file = &rec->file;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200689 struct perf_session *session;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300690 bool disabled = false, draining = false;
Namhyung Kim42aa2762015-01-29 17:06:48 +0900691 int fd;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200692
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200693 rec->progname = argv[0];
Andi Kleen33e49ea2011-09-15 14:31:40 -0700694
Namhyung Kim45604712014-05-12 09:47:24 +0900695 atexit(record__sig_exit);
Peter Zijlstraf5970552009-06-18 23:22:55 +0200696 signal(SIGCHLD, sig_handler);
697 signal(SIGINT, sig_handler);
David Ahern804f7ac2013-05-06 12:24:23 -0600698 signal(SIGTERM, sig_handler);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000699
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000700 if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300701 signal(SIGUSR2, snapshot_sig_handler);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000702 if (rec->opts.auxtrace_snapshot_mode)
703 trigger_on(&auxtrace_snapshot_trigger);
704 if (rec->switch_output)
705 trigger_on(&switch_output_trigger);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000706 } else {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300707 signal(SIGUSR2, SIG_IGN);
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000708 }
Peter Zijlstraf5970552009-06-18 23:22:55 +0200709
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300710 session = perf_session__new(file, false, tool);
Arnaldo Carvalho de Melo94c744b2009-12-11 21:24:02 -0200711 if (session == NULL) {
Adrien BAKffa91882014-04-18 11:00:43 +0900712 pr_err("Perf session creation failed.\n");
Arnaldo Carvalho de Meloa9a70bb2009-11-17 01:18:11 -0200713 return -1;
714 }
715
Namhyung Kim42aa2762015-01-29 17:06:48 +0900716 fd = perf_data_file__fd(file);
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200717 rec->session = session;
718
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300719 record__init_features(rec);
Stephane Eranian330aa672012-03-08 23:47:46 +0100720
Arnaldo Carvalho de Melod4db3f12009-12-27 21:36:57 -0200721 if (forks) {
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300722 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200723 argv, file->is_pipe,
Arnaldo Carvalho de Melo735f7e02014-01-03 14:56:49 -0300724 workload_exec_failed_signal);
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200725 if (err < 0) {
726 pr_err("Couldn't run the workload!\n");
Namhyung Kim45604712014-05-12 09:47:24 +0900727 status = err;
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -0200728 goto out_delete_session;
Jens Axboe0a5ac842009-08-12 11:18:01 +0200729 }
Peter Zijlstra856e9662009-12-16 17:55:55 +0100730 }
731
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300732 if (record__open(rec) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -0600733 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900734 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600735 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200736
Wang Nan8690a2a2016-02-22 09:10:32 +0000737 err = bpf__apply_obj_config();
738 if (err) {
739 char errbuf[BUFSIZ];
740
741 bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
742 pr_err("ERROR: Apply config to BPF failed: %s\n",
743 errbuf);
744 goto out_child;
745 }
746
Adrian Huntercca84822015-08-19 17:29:21 +0300747 /*
748 * Normally perf_session__new would do this, but it doesn't have the
749 * evlist.
750 */
751 if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
752 pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
753 rec->tool.ordered_events = false;
754 }
755
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300756 if (!rec->evlist->nr_groups)
Namhyung Kima8bb5592013-01-22 18:09:31 +0900757 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
758
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200759 if (file->is_pipe) {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900760 err = perf_header__write_pipe(fd);
Tom Zanussi529870e2010-04-01 23:59:16 -0500761 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900762 goto out_child;
Jiri Olsa563aecb2013-06-05 13:35:06 +0200763 } else {
Namhyung Kim42aa2762015-01-29 17:06:48 +0900764 err = perf_session__write_header(session, rec->evlist, fd, false);
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200765 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900766 goto out_child;
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -0200767 }
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +0200768
David Ahernd3665492012-02-06 15:27:52 -0700769 if (!rec->no_buildid
Robert Richtere20960c2011-12-07 10:02:55 +0100770 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
David Ahernd3665492012-02-06 15:27:52 -0700771 pr_err("Couldn't generate buildids. "
Robert Richtere20960c2011-12-07 10:02:55 +0100772 "Use --no-buildid to profile anyway.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600773 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900774 goto out_child;
Robert Richtere20960c2011-12-07 10:02:55 +0100775 }
776
Arnaldo Carvalho de Melo34ba5122012-12-19 09:04:24 -0300777 machine = &session->machines.host;
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200778
Wang Nanc45c86e2016-02-26 09:32:07 +0000779 err = record__synthesize(rec);
780 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +0900781 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600782
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200783 if (rec->realtime_prio) {
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200784 struct sched_param param;
785
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200786 param.sched_priority = rec->realtime_prio;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200787 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
Arnaldo Carvalho de Melo6beba7a2009-10-21 17:34:06 -0200788 pr_err("Could not set realtime priority.\n");
David Ahern8d3eca22012-08-26 12:24:47 -0600789 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900790 goto out_child;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200791 }
792 }
793
Jiri Olsa774cb492012-11-12 18:34:01 +0100794 /*
795 * When perf is starting the traced process, all the events
796 * (apart from group members) have enable_on_exec=1 set,
797 * so don't spoil it by prematurely enabling them.
798 */
Andi Kleen6619a532014-01-11 13:38:27 -0800799 if (!target__none(&opts->target) && !opts->initial_delay)
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300800 perf_evlist__enable(rec->evlist);
David Ahern764e16a32011-08-25 10:17:55 -0600801
Peter Zijlstra856e9662009-12-16 17:55:55 +0100802 /*
803 * Let the child rip
804 */
Namhyung Kime803cf92015-09-22 09:24:55 +0900805 if (forks) {
Namhyung Kime5bed562015-09-30 10:45:24 +0900806 union perf_event *event;
807
808 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
809 if (event == NULL) {
810 err = -ENOMEM;
811 goto out_child;
812 }
813
Namhyung Kime803cf92015-09-22 09:24:55 +0900814 /*
815 * Some H/W events are generated before COMM event
816 * which is emitted during exec(), so perf script
817 * cannot see a correct process name for those events.
818 * Synthesize COMM event to prevent it.
819 */
Namhyung Kime5bed562015-09-30 10:45:24 +0900820 perf_event__synthesize_comm(tool, event,
Namhyung Kime803cf92015-09-22 09:24:55 +0900821 rec->evlist->workload.pid,
822 process_synthesized_event,
823 machine);
Namhyung Kime5bed562015-09-30 10:45:24 +0900824 free(event);
Namhyung Kime803cf92015-09-22 09:24:55 +0900825
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300826 perf_evlist__start_workload(rec->evlist);
Namhyung Kime803cf92015-09-22 09:24:55 +0900827 }
Peter Zijlstra856e9662009-12-16 17:55:55 +0100828
Andi Kleen6619a532014-01-11 13:38:27 -0800829 if (opts->initial_delay) {
830 usleep(opts->initial_delay * 1000);
831 perf_evlist__enable(rec->evlist);
832 }
833
Wang Nan5f9cf592016-04-20 18:59:49 +0000834 trigger_ready(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000835 trigger_ready(&switch_output_trigger);
Peter Zijlstra649c48a2009-06-24 21:12:48 +0200836 for (;;) {
Yang Shi9f065192015-09-29 14:49:43 -0700837 unsigned long long hits = rec->samples;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200838
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300839 if (record__mmap_read_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000840 trigger_error(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000841 trigger_error(&switch_output_trigger);
David Ahern8d3eca22012-08-26 12:24:47 -0600842 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900843 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -0600844 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200845
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300846 if (auxtrace_record__snapshot_started) {
847 auxtrace_record__snapshot_started = 0;
Wang Nan5f9cf592016-04-20 18:59:49 +0000848 if (!trigger_is_error(&auxtrace_snapshot_trigger))
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300849 record__read_auxtrace_snapshot(rec);
Wang Nan5f9cf592016-04-20 18:59:49 +0000850 if (trigger_is_error(&auxtrace_snapshot_trigger)) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300851 pr_err("AUX area tracing snapshot failed\n");
852 err = -1;
853 goto out_child;
854 }
855 }
856
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000857 if (trigger_is_hit(&switch_output_trigger)) {
858 trigger_ready(&switch_output_trigger);
859
860 if (!quiet)
861 fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
862 waking);
863 waking = 0;
864 fd = record__switch_output(rec, false);
865 if (fd < 0) {
866 pr_err("Failed to switch to new file\n");
867 trigger_error(&switch_output_trigger);
868 err = fd;
869 goto out_child;
870 }
871 }
872
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200873 if (hits == rec->samples) {
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300874 if (done || draining)
Peter Zijlstra649c48a2009-06-24 21:12:48 +0200875 break;
Arnaldo Carvalho de Melof66a8892014-08-18 17:25:59 -0300876 err = perf_evlist__poll(rec->evlist, -1);
Jiri Olsaa5151142014-06-02 13:44:23 -0400877 /*
878 * Propagate error, only if there's any. Ignore positive
879 * number of returned events and interrupt error.
880 */
881 if (err > 0 || (err < 0 && errno == EINTR))
Namhyung Kim45604712014-05-12 09:47:24 +0900882 err = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200883 waking++;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -0300884
885 if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
886 draining = true;
Peter Zijlstra8b412662009-09-17 19:59:05 +0200887 }
888
Jiri Olsa774cb492012-11-12 18:34:01 +0100889 /*
890 * When perf is starting the traced process, at the end events
891 * die with the process and we wait for that. Thus no need to
892 * disable events in this case.
893 */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -0300894 if (done && !disabled && !target__none(&opts->target)) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000895 trigger_off(&auxtrace_snapshot_trigger);
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -0300896 perf_evlist__disable(rec->evlist);
Jiri Olsa27119262012-11-12 18:34:02 +0100897 disabled = true;
898 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200899 }
Wang Nan5f9cf592016-04-20 18:59:49 +0000900 trigger_off(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +0000901 trigger_off(&switch_output_trigger);
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200902
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300903 if (forks && workload_exec_errno) {
Masami Hiramatsu35550da2014-08-14 02:22:43 +0000904 char msg[STRERR_BUFSIZE];
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300905 const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
906 pr_err("Workload failed: %s\n", emsg);
907 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +0900908 goto out_child;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -0300909 }
910
Namhyung Kime3d59112015-01-29 17:06:44 +0900911 if (!quiet)
Namhyung Kim45604712014-05-12 09:47:24 +0900912 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -0200913
Namhyung Kim45604712014-05-12 09:47:24 +0900914out_child:
915 if (forks) {
916 int exit_status;
Ingo Molnaraddc2782009-06-02 23:43:11 +0200917
Namhyung Kim45604712014-05-12 09:47:24 +0900918 if (!child_finished)
919 kill(rec->evlist->workload.pid, SIGTERM);
920
921 wait(&exit_status);
922
923 if (err < 0)
924 status = err;
925 else if (WIFEXITED(exit_status))
926 status = WEXITSTATUS(exit_status);
927 else if (WIFSIGNALED(exit_status))
928 signr = WTERMSIG(exit_status);
929 } else
930 status = err;
931
Namhyung Kime3d59112015-01-29 17:06:44 +0900932 /* this will be recalculated during process_buildids() */
933 rec->samples = 0;
934
Wang Nanecfd7a92016-04-13 08:21:07 +0000935 if (!err) {
936 if (!rec->timestamp_filename) {
937 record__finish_output(rec);
938 } else {
939 fd = record__switch_output(rec, true);
940 if (fd < 0) {
941 status = fd;
942 goto out_delete_session;
943 }
944 }
945 }
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -0300946
Namhyung Kime3d59112015-01-29 17:06:44 +0900947 if (!err && !quiet) {
948 char samples[128];
Wang Nanecfd7a92016-04-13 08:21:07 +0000949 const char *postfix = rec->timestamp_filename ?
950 ".<timestamp>" : "";
Namhyung Kime3d59112015-01-29 17:06:44 +0900951
Adrian Hunteref149c22015-04-09 18:53:45 +0300952 if (rec->samples && !rec->opts.full_auxtrace)
Namhyung Kime3d59112015-01-29 17:06:44 +0900953 scnprintf(samples, sizeof(samples),
954 " (%" PRIu64 " samples)", rec->samples);
955 else
956 samples[0] = '\0';
957
Wang Nanecfd7a92016-04-13 08:21:07 +0000958 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
Namhyung Kime3d59112015-01-29 17:06:44 +0900959 perf_data_file__size(file) / 1024.0 / 1024.0,
Wang Nanecfd7a92016-04-13 08:21:07 +0000960 file->path, postfix, samples);
Namhyung Kime3d59112015-01-29 17:06:44 +0900961 }
962
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -0300963out_delete_session:
964 perf_session__delete(session);
Namhyung Kim45604712014-05-12 09:47:24 +0900965 return status;
Peter Zijlstrade9ac072009-04-08 15:01:31 +0200966}
Ingo Molnar0e9b20b2009-05-26 09:17:18 +0200967
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300968static void callchain_debug(struct callchain_param *callchain)
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200969{
Kan Liangaad2b212015-01-05 13:23:04 -0500970 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
Jiri Olsaa601fdf2014-02-03 12:44:43 +0100971
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300972 pr_debug("callchain: type %s\n", str[callchain->record_mode]);
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200973
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300974 if (callchain->record_mode == CALLCHAIN_DWARF)
Jiri Olsa09b0fd42013-10-26 16:25:33 +0200975 pr_debug("callchain: stack dump size %d\n",
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300976 callchain->dump_size);
977}
978
979int record_opts__parse_callchain(struct record_opts *record,
980 struct callchain_param *callchain,
981 const char *arg, bool unset)
982{
983 int ret;
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -0300984 callchain->enabled = !unset;
985
986 /* --no-call-graph */
987 if (unset) {
988 callchain->record_mode = CALLCHAIN_NONE;
989 pr_debug("callchain: disabled\n");
990 return 0;
991 }
992
993 ret = parse_callchain_record_opt(arg, callchain);
994 if (!ret) {
995 /* Enable data address sampling for DWARF unwind. */
996 if (callchain->record_mode == CALLCHAIN_DWARF)
997 record->sample_address = true;
998 callchain_debug(callchain);
999 }
1000
1001 return ret;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001002}
1003
Kan Liangc421e802015-07-29 05:42:12 -04001004int record_parse_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001005 const char *arg,
1006 int unset)
1007{
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001008 return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
Jiri Olsa26d33022012-08-07 15:20:47 +02001009}
1010
Kan Liangc421e802015-07-29 05:42:12 -04001011int record_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001012 const char *arg __maybe_unused,
1013 int unset __maybe_unused)
1014{
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001015 struct callchain_param *callchain = opt->value;
Kan Liangc421e802015-07-29 05:42:12 -04001016
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001017 callchain->enabled = true;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001018
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001019 if (callchain->record_mode == CALLCHAIN_NONE)
1020 callchain->record_mode = CALLCHAIN_FP;
Jiri Olsaeb853e82014-02-03 12:44:42 +01001021
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001022 callchain_debug(callchain);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001023 return 0;
1024}
1025
Jiri Olsaeb853e82014-02-03 12:44:42 +01001026static int perf_record_config(const char *var, const char *value, void *cb)
1027{
Namhyung Kim7a29c082015-12-15 10:49:56 +09001028 struct record *rec = cb;
1029
1030 if (!strcmp(var, "record.build-id")) {
1031 if (!strcmp(value, "cache"))
1032 rec->no_buildid_cache = false;
1033 else if (!strcmp(value, "no-cache"))
1034 rec->no_buildid_cache = true;
1035 else if (!strcmp(value, "skip"))
1036 rec->no_buildid = true;
1037 else
1038 return -1;
1039 return 0;
1040 }
Jiri Olsaeb853e82014-02-03 12:44:42 +01001041 if (!strcmp(var, "record.call-graph"))
Namhyung Kim5a2e5e82014-09-23 10:01:44 +09001042 var = "call-graph.record-mode"; /* fall-through */
Jiri Olsaeb853e82014-02-03 12:44:42 +01001043
1044 return perf_default_config(var, value, cb);
1045}
1046
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001047struct clockid_map {
1048 const char *name;
1049 int clockid;
1050};
1051
1052#define CLOCKID_MAP(n, c) \
1053 { .name = n, .clockid = (c), }
1054
1055#define CLOCKID_END { .name = NULL, }
1056
1057
1058/*
1059 * Add the missing ones, we need to build on many distros...
1060 */
1061#ifndef CLOCK_MONOTONIC_RAW
1062#define CLOCK_MONOTONIC_RAW 4
1063#endif
1064#ifndef CLOCK_BOOTTIME
1065#define CLOCK_BOOTTIME 7
1066#endif
1067#ifndef CLOCK_TAI
1068#define CLOCK_TAI 11
1069#endif
1070
1071static const struct clockid_map clockids[] = {
1072 /* available for all events, NMI safe */
1073 CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
1074 CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
1075
1076 /* available for some events */
1077 CLOCKID_MAP("realtime", CLOCK_REALTIME),
1078 CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
1079 CLOCKID_MAP("tai", CLOCK_TAI),
1080
1081 /* available for the lazy */
1082 CLOCKID_MAP("mono", CLOCK_MONOTONIC),
1083 CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
1084 CLOCKID_MAP("real", CLOCK_REALTIME),
1085 CLOCKID_MAP("boot", CLOCK_BOOTTIME),
1086
1087 CLOCKID_END,
1088};
1089
1090static int parse_clockid(const struct option *opt, const char *str, int unset)
1091{
1092 struct record_opts *opts = (struct record_opts *)opt->value;
1093 const struct clockid_map *cm;
1094 const char *ostr = str;
1095
1096 if (unset) {
1097 opts->use_clockid = 0;
1098 return 0;
1099 }
1100
1101 /* no arg passed */
1102 if (!str)
1103 return 0;
1104
1105 /* no setting it twice */
1106 if (opts->use_clockid)
1107 return -1;
1108
1109 opts->use_clockid = true;
1110
1111 /* if its a number, we're done */
1112 if (sscanf(str, "%d", &opts->clockid) == 1)
1113 return 0;
1114
1115 /* allow a "CLOCK_" prefix to the name */
1116 if (!strncasecmp(str, "CLOCK_", 6))
1117 str += 6;
1118
1119 for (cm = clockids; cm->name; cm++) {
1120 if (!strcasecmp(str, cm->name)) {
1121 opts->clockid = cm->clockid;
1122 return 0;
1123 }
1124 }
1125
1126 opts->use_clockid = false;
1127 ui__warning("unknown clockid %s, check man page\n", ostr);
1128 return -1;
1129}
1130
Adrian Huntere9db1312015-04-09 18:53:46 +03001131static int record__parse_mmap_pages(const struct option *opt,
1132 const char *str,
1133 int unset __maybe_unused)
1134{
1135 struct record_opts *opts = opt->value;
1136 char *s, *p;
1137 unsigned int mmap_pages;
1138 int ret;
1139
1140 if (!str)
1141 return -EINVAL;
1142
1143 s = strdup(str);
1144 if (!s)
1145 return -ENOMEM;
1146
1147 p = strchr(s, ',');
1148 if (p)
1149 *p = '\0';
1150
1151 if (*s) {
1152 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
1153 if (ret)
1154 goto out_free;
1155 opts->mmap_pages = mmap_pages;
1156 }
1157
1158 if (!p) {
1159 ret = 0;
1160 goto out_free;
1161 }
1162
1163 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
1164 if (ret)
1165 goto out_free;
1166
1167 opts->auxtrace_mmap_pages = mmap_pages;
1168
1169out_free:
1170 free(s);
1171 return ret;
1172}
1173
Namhyung Kime5b2c202014-10-23 00:15:46 +09001174static const char * const __record_usage[] = {
Mike Galbraith9e0967532009-05-28 16:25:34 +02001175 "perf record [<options>] [<command>]",
1176 "perf record [<options>] -- <command> [<options>]",
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001177 NULL
1178};
Namhyung Kime5b2c202014-10-23 00:15:46 +09001179const char * const *record_usage = __record_usage;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001180
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001181/*
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001182 * XXX Ideally would be local to cmd_record() and passed to a record__new
1183 * because we need to have access to it in record__exit, that is called
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001184 * after cmd_record() exits, but since record_options need to be accessible to
1185 * builtin-script, leave it here.
1186 *
1187 * At least we don't ouch it in all the other functions here directly.
1188 *
1189 * Just say no to tons of global variables, sigh.
1190 */
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001191static struct record record = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001192 .opts = {
Andi Kleen8affc2b2014-07-31 14:45:04 +08001193 .sample_time = true,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001194 .mmap_pages = UINT_MAX,
1195 .user_freq = UINT_MAX,
1196 .user_interval = ULLONG_MAX,
Arnaldo Carvalho de Melo447a6012012-05-22 13:14:18 -03001197 .freq = 4000,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001198 .target = {
1199 .uses_mmap = true,
Adrian Hunter3aa59392013-11-15 15:52:29 +02001200 .default_per_cpu = true,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09001201 },
Kan Liang9d9cad72015-06-17 09:51:11 -04001202 .proc_map_timeout = 500,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001203 },
Namhyung Kime3d59112015-01-29 17:06:44 +09001204 .tool = {
1205 .sample = process_sample_event,
1206 .fork = perf_event__process_fork,
Adrian Huntercca84822015-08-19 17:29:21 +03001207 .exit = perf_event__process_exit,
Namhyung Kime3d59112015-01-29 17:06:44 +09001208 .comm = perf_event__process_comm,
1209 .mmap = perf_event__process_mmap,
1210 .mmap2 = perf_event__process_mmap2,
Adrian Huntercca84822015-08-19 17:29:21 +03001211 .ordered_events = true,
Namhyung Kime3d59112015-01-29 17:06:44 +09001212 },
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001213};
Frederic Weisbecker7865e812010-04-14 19:42:07 +02001214
Namhyung Kim76a26542015-10-22 23:28:32 +09001215const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1216 "\n\t\t\t\tDefault: fp";
Arnaldo Carvalho de Melo61eaa3b2012-10-01 15:20:58 -03001217
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001218/*
1219 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
1220 * with it and switch to use the library functions in perf_evlist that came
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001221 * from builtin-record.c, i.e. use record_opts,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001222 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
1223 * using pipes, etc.
1224 */
Namhyung Kime5b2c202014-10-23 00:15:46 +09001225struct option __record_options[] = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001226 OPT_CALLBACK('e', "event", &record.evlist, "event",
Thomas Gleixner86847b62009-06-06 12:24:17 +02001227 "event selector. use 'perf list' to list available events",
Jiri Olsaf120f9d2011-07-14 11:25:32 +02001228 parse_events_option),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001229 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
Li Zefanc171b552009-10-15 11:22:07 +08001230 "event filter", parse_filter),
Wang Nan4ba1faa2015-07-10 07:36:10 +00001231 OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
1232 NULL, "don't record events from perf itself",
1233 exclude_perf),
Namhyung Kimbea03402012-04-26 14:15:15 +09001234 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001235 "record events on existing process id"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001236 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03001237 "record events on existing thread id"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001238 OPT_INTEGER('r', "realtime", &record.realtime_prio,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001239 "collect data with this RT SCHED_FIFO priority"),
Arnaldo Carvalho de Melo509051e2014-01-14 17:52:14 -03001240 OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
Kirill Smelkovacac03f2011-01-12 17:59:36 +03001241 "collect data without buffering"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001242 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
Frederic Weisbeckerdaac07b2009-08-13 10:27:19 +02001243 "collect raw sample records from all opened counters"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001244 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001245 "system-wide collection from all CPUs"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001246 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
Stephane Eranianc45c6ea2010-05-28 12:00:01 +02001247 "list of cpus to monitor"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001248 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
Jiri Olsaf5fc14122013-10-15 16:27:32 +02001249 OPT_STRING('o', "output", &record.file.path, "file",
Ingo Molnarabaff322009-06-02 22:59:57 +02001250 "output file name"),
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001251 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1252 &record.opts.no_inherit_set,
1253 "child tasks do not inherit counters"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001254 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
Adrian Huntere9db1312015-04-09 18:53:46 +03001255 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
1256 "number of mmap data pages and AUX area tracing mmap pages",
1257 record__parse_mmap_pages),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001258 OPT_BOOLEAN(0, "group", &record.opts.group,
Lin Ming43bece72011-08-17 18:42:07 +08001259 "put the counters into a counter group"),
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03001260 OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001261 NULL, "enables call-graph recording" ,
1262 &record_callchain_opt),
1263 OPT_CALLBACK(0, "call-graph", &record.opts,
Namhyung Kim76a26542015-10-22 23:28:32 +09001264 "record_mode[,record_size]", record_callchain_help,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001265 &record_parse_callchain_opt),
Ian Munsiec0555642010-04-13 18:37:33 +10001266 OPT_INCR('v', "verbose", &verbose,
Ingo Molnar3da297a2009-06-07 17:39:02 +02001267 "be more verbose (show counter open errors, etc)"),
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001268 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001269 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001270 "per thread counts"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001271 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
Adrian Hunter3abebc52015-07-06 14:51:01 +03001272 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
1273 &record.opts.sample_time_set,
1274 "Record the sample timestamps"),
Peter Zijlstra56100322015-06-10 16:48:50 +02001275 OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001276 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001277 "don't sample"),
Wang Nand2db9a92016-01-25 09:56:19 +00001278 OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
1279 &record.no_buildid_cache_set,
1280 "do not update the buildid cache"),
1281 OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
1282 &record.no_buildid_set,
1283 "do not collect buildids in perf.data"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001284 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
Stephane Eranian023695d2011-02-14 11:20:01 +02001285 "monitor event in cgroup name only",
1286 parse_cgroups),
Arnaldo Carvalho de Meloa6205a32014-01-14 17:58:12 -03001287 OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
Andi Kleen6619a532014-01-11 13:38:27 -08001288 "ms to wait before starting measurement after program start"),
Namhyung Kimbea03402012-04-26 14:15:15 +09001289 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
1290 "user to profile"),
Stephane Eraniana5aabda2012-03-08 23:47:45 +01001291
1292 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
1293 "branch any", "sample any taken branches",
1294 parse_branch_stack),
1295
1296 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
1297 "branch filter mask", "branch stack filter modes",
Roberto Agostino Vitillobdfebd82012-02-09 23:21:02 +01001298 parse_branch_stack),
Andi Kleen05484292013-01-24 16:10:29 +01001299 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
1300 "sample by weight (on special events only)"),
Andi Kleen475eeab2013-09-20 07:40:43 -07001301 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
1302 "sample transaction flags (special events only)"),
Adrian Hunter3aa59392013-11-15 15:52:29 +02001303 OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
1304 "use per-thread mmaps"),
Stephane Eranianbcc84ec2015-08-31 18:41:12 +02001305 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
1306 "sample selected machine registers on interrupt,"
1307 " use -I ? to list register names", parse_regs),
Andi Kleen85c273d2015-02-24 15:13:40 -08001308 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
1309 "Record running/enabled time of read (:S) events"),
Peter Zijlstra814c8c32015-03-31 00:19:31 +02001310 OPT_CALLBACK('k', "clockid", &record.opts,
1311 "clockid", "clockid to use for events, see clock_gettime()",
1312 parse_clockid),
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001313 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
1314 "opts", "AUX area tracing Snapshot Mode", ""),
Kan Liang9d9cad72015-06-17 09:51:11 -04001315 OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
1316 "per thread proc mmap processing timeout in ms"),
Adrian Hunterb757bb02015-07-21 12:44:04 +03001317 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1318 "Record context switch events"),
Jiri Olsa85723882016-02-15 09:34:31 +01001319 OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
1320 "Configure all used events to run in kernel space.",
1321 PARSE_OPT_EXCLUSIVE),
1322 OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
1323 "Configure all used events to run in user space.",
1324 PARSE_OPT_EXCLUSIVE),
Wang Nan71dc23262015-10-14 12:41:19 +00001325 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1326 "clang binary to use for compiling BPF scriptlets"),
1327 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1328 "options passed to clang when compiling BPF scriptlets"),
He Kuang7efe0e02015-12-14 10:39:23 +00001329 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1330 "file", "vmlinux pathname"),
Namhyung Kim61566812016-01-11 22:37:09 +09001331 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
1332 "Record build-id of all DSOs regardless of hits"),
Wang Nanecfd7a92016-04-13 08:21:07 +00001333 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1334 "append timestamp to output filename"),
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001335 OPT_BOOLEAN(0, "switch-output", &record.switch_output,
1336 "Switch output when receive SIGUSR2"),
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001337 OPT_END()
1338};
1339
Namhyung Kime5b2c202014-10-23 00:15:46 +09001340struct option *record_options = __record_options;
1341
Irina Tirdea1d037ca2012-09-11 01:15:03 +03001342int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001343{
Adrian Hunteref149c22015-04-09 18:53:45 +03001344 int err;
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001345 struct record *rec = &record;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001346 char errbuf[BUFSIZ];
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001347
Wang Nan48e1cab2015-12-14 10:39:22 +00001348#ifndef HAVE_LIBBPF_SUPPORT
1349# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
1350 set_nobuild('\0', "clang-path", true);
1351 set_nobuild('\0', "clang-opt", true);
1352# undef set_nobuild
1353#endif
1354
He Kuang7efe0e02015-12-14 10:39:23 +00001355#ifndef HAVE_BPF_PROLOGUE
1356# if !defined (HAVE_DWARF_SUPPORT)
1357# define REASON "NO_DWARF=1"
1358# elif !defined (HAVE_LIBBPF_SUPPORT)
1359# define REASON "NO_LIBBPF=1"
1360# else
1361# define REASON "this architecture doesn't support BPF prologue"
1362# endif
1363# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
1364 set_nobuild('\0', "vmlinux", true);
1365# undef set_nobuild
1366# undef REASON
1367#endif
1368
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001369 rec->evlist = perf_evlist__new();
1370 if (rec->evlist == NULL)
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -02001371 return -ENOMEM;
1372
Jiri Olsaeb853e82014-02-03 12:44:42 +01001373 perf_config(perf_record_config, rec);
1374
Tom Zanussibca647a2010-11-10 08:11:30 -06001375 argc = parse_options(argc, argv, record_options, record_usage,
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001376 PARSE_OPT_STOP_AT_NON_OPTION);
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001377 if (!argc && target__none(&rec->opts.target))
Tom Zanussibca647a2010-11-10 08:11:30 -06001378 usage_with_options(record_usage, record_options);
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001379
Namhyung Kimbea03402012-04-26 14:15:15 +09001380 if (nr_cgroups && !rec->opts.target.system_wide) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001381 usage_with_options_msg(record_usage, record_options,
1382 "cgroup monitoring only available in system-wide mode");
1383
Stephane Eranian023695d2011-02-14 11:20:01 +02001384 }
Adrian Hunterb757bb02015-07-21 12:44:04 +03001385 if (rec->opts.record_switch_events &&
1386 !perf_can_record_switch_events()) {
Namhyung Kimc7118362015-10-25 00:49:27 +09001387 ui__error("kernel does not support recording context switch events\n");
1388 parse_options_usage(record_usage, record_options, "switch-events", 0);
1389 return -EINVAL;
Adrian Hunterb757bb02015-07-21 12:44:04 +03001390 }
Stephane Eranian023695d2011-02-14 11:20:01 +02001391
Wang Naneca857a2016-04-20 18:59:51 +00001392 if (rec->switch_output)
1393 rec->timestamp_filename = true;
1394
Adrian Hunteref149c22015-04-09 18:53:45 +03001395 if (!rec->itr) {
1396 rec->itr = auxtrace_record__init(rec->evlist, &err);
1397 if (err)
1398 return err;
1399 }
1400
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001401 err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
1402 rec->opts.auxtrace_snapshot_opts);
1403 if (err)
1404 return err;
1405
Wang Nand7888572016-04-08 15:07:24 +00001406 err = bpf__setup_stdout(rec->evlist);
1407 if (err) {
1408 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
1409 pr_err("ERROR: Setup BPF stdout failed: %s\n",
1410 errbuf);
1411 return err;
1412 }
1413
Adrian Hunteref149c22015-04-09 18:53:45 +03001414 err = -ENOMEM;
1415
Namhyung Kim0a7e6d12014-08-12 15:40:45 +09001416 symbol__init(NULL);
Arnaldo Carvalho de Melobaa2f6c2010-11-26 19:39:15 -02001417
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001418 if (symbol_conf.kptr_restrict)
Arnaldo Carvalho de Melo646aaea2011-05-27 11:00:41 -03001419 pr_warning(
1420"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
1421"check /proc/sys/kernel/kptr_restrict.\n\n"
1422"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
1423"file is not found in the buildid cache or in the vmlinux path.\n\n"
1424"Samples in kernel modules won't be resolved at all.\n\n"
1425"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
1426"even with a suitable vmlinux or kallsyms file.\n\n");
Arnaldo Carvalho de Meloec80fde2011-05-26 09:53:51 -03001427
Wang Nan0c1d46a2016-04-20 18:59:52 +00001428 if (rec->no_buildid_cache || rec->no_buildid) {
Stephane Eraniana1ac1d32010-06-17 11:39:01 +02001429 disable_buildid_cache();
Wang Nan0c1d46a2016-04-20 18:59:52 +00001430 } else if (rec->switch_output) {
1431 /*
1432 * In 'perf record --switch-output', disable buildid
1433 * generation by default to reduce data file switching
1434 * overhead. Still generate buildid if they are required
1435 * explicitly using
1436 *
1437 * perf record --signal-trigger --no-no-buildid \
1438 * --no-no-buildid-cache
1439 *
1440 * Following code equals to:
1441 *
1442 * if ((rec->no_buildid || !rec->no_buildid_set) &&
1443 * (rec->no_buildid_cache || !rec->no_buildid_cache_set))
1444 * disable_buildid_cache();
1445 */
1446 bool disable = true;
1447
1448 if (rec->no_buildid_set && !rec->no_buildid)
1449 disable = false;
1450 if (rec->no_buildid_cache_set && !rec->no_buildid_cache)
1451 disable = false;
1452 if (disable) {
1453 rec->no_buildid = true;
1454 rec->no_buildid_cache = true;
1455 disable_buildid_cache();
1456 }
1457 }
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02001458
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001459 if (rec->evlist->nr_entries == 0 &&
1460 perf_evlist__add_default(rec->evlist) < 0) {
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001461 pr_err("Not enough memory for event selector list\n");
1462 goto out_symbol_exit;
Peter Zijlstrabbd36e52009-06-11 23:11:50 +02001463 }
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001464
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02001465 if (rec->opts.target.tid && !rec->opts.no_inherit_set)
1466 rec->opts.no_inherit = true;
1467
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001468 err = target__validate(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001469 if (err) {
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001470 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001471 ui__warning("%s", errbuf);
1472 }
Namhyung Kim4bd0f2d2012-04-26 14:15:18 +09001473
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001474 err = target__parse_uid(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001475 if (err) {
1476 int saved_errno = errno;
1477
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001478 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim3780f482012-05-29 13:22:57 +09001479 ui__error("%s", errbuf);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001480
1481 err = -saved_errno;
Namhyung Kim8fa60e12013-03-15 14:48:51 +09001482 goto out_symbol_exit;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001483 }
Arnaldo Carvalho de Melo0d37aa32012-01-19 14:08:15 -02001484
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09001485 err = -ENOMEM;
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001486 if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -02001487 usage_with_options(record_usage, record_options);
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02001488
Adrian Hunteref149c22015-04-09 18:53:45 +03001489 err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
1490 if (err)
1491 goto out_symbol_exit;
1492
Namhyung Kim61566812016-01-11 22:37:09 +09001493 /*
1494 * We take all buildids when the file contains
1495 * AUX area tracing data because we do not decode the
1496 * trace because it would take too long.
1497 */
1498 if (rec->opts.full_auxtrace)
1499 rec->buildid_all = true;
1500
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001501 if (record_opts__config(&rec->opts)) {
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001502 err = -EINVAL;
Arnaldo Carvalho de Melo03ad9742014-01-03 15:56:06 -03001503 goto out_symbol_exit;
Mike Galbraith7e4ff9e2009-10-12 07:56:03 +02001504 }
1505
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001506 err = __cmd_record(&record, argc, argv);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03001507out_symbol_exit:
Namhyung Kim45604712014-05-12 09:47:24 +09001508 perf_evlist__delete(rec->evlist);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03001509 symbol__exit();
Adrian Hunteref149c22015-04-09 18:53:45 +03001510 auxtrace_record__free(rec->itr);
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001511 return err;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001512}
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001513
1514static void snapshot_sig_handler(int sig __maybe_unused)
1515{
Wang Nan5f9cf592016-04-20 18:59:49 +00001516 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1517 trigger_hit(&auxtrace_snapshot_trigger);
1518 auxtrace_record__snapshot_started = 1;
1519 if (auxtrace_record__snapshot_start(record.itr))
1520 trigger_error(&auxtrace_snapshot_trigger);
1521 }
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001522
1523 if (trigger_is_ready(&switch_output_trigger))
1524 trigger_hit(&switch_output_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001525}