blob: ecd478a22c644d2bd3d20398c6b329cdde5a23e3 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Ingo Molnarabaff322009-06-02 22:59:57 +02002/*
Ingo Molnarbf9e1872009-06-02 23:37:05 +02003 * builtin-record.c
4 *
5 * Builtin record command: Record the profile of a workload
6 * (or a CPU, or a PID) into the perf.data output file - for
7 * later analysis via perf report.
Ingo Molnarabaff322009-06-02 22:59:57 +02008 */
Ingo Molnar16f762a2009-05-27 09:10:38 +02009#include "builtin.h"
Ingo Molnarbf9e1872009-06-02 23:37:05 +020010
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -020011#include "util/build-id.h"
Josh Poimboeuf4b6ab942015-12-15 09:39:39 -060012#include <subcmd/parse-options.h>
Ingo Molnar8ad8db32009-05-26 11:10:09 +020013#include "util/parse-events.h"
Taeung Song41840d22016-06-23 17:55:17 +090014#include "util/config.h"
Thomas Gleixner6eda5832009-05-01 18:29:57 +020015
Arnaldo Carvalho de Melo8f651ea2014-10-09 16:12:24 -030016#include "util/callchain.h"
Arnaldo Carvalho de Melof14d5702014-10-17 12:17:40 -030017#include "util/cgroup.h"
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +020018#include "util/header.h"
Frederic Weisbecker66e274f2009-08-12 11:07:25 +020019#include "util/event.h"
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -020020#include "util/evlist.h"
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -020021#include "util/evsel.h"
Frederic Weisbecker8f288272009-08-16 22:05:48 +020022#include "util/debug.h"
Arnaldo Carvalho de Meloe0fcfb02019-09-23 12:20:38 -030023#include "util/mmap.h"
Arnaldo Carvalho de Meloaeb00b12019-08-22 15:40:29 -030024#include "util/target.h"
Arnaldo Carvalho de Melo94c744b2009-12-11 21:24:02 -020025#include "util/session.h"
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020026#include "util/tool.h"
Arnaldo Carvalho de Melo8d063672009-11-04 18:50:43 -020027#include "util/symbol.h"
Arnaldo Carvalho de Meloaeb00b12019-08-22 15:40:29 -030028#include "util/record.h"
Paul Mackerrasa12b51c2010-03-10 20:36:09 +110029#include "util/cpumap.h"
Arnaldo Carvalho de Melofd782602011-01-18 15:15:24 -020030#include "util/thread_map.h"
Jiri Olsaf5fc14122013-10-15 16:27:32 +020031#include "util/data.h"
Stephane Eranianbcc84ec2015-08-31 18:41:12 +020032#include "util/perf_regs.h"
Adrian Hunteref149c22015-04-09 18:53:45 +030033#include "util/auxtrace.h"
Adrian Hunter46bc29b2016-03-08 10:38:44 +020034#include "util/tsc.h"
Andi Kleenf00898f2015-05-27 10:51:51 -070035#include "util/parse-branch-options.h"
Stephane Eranianbcc84ec2015-08-31 18:41:12 +020036#include "util/parse-regs-options.h"
Arnaldo Carvalho de Melo40c7d242020-05-05 11:49:08 -030037#include "util/perf_api_probe.h"
Wang Nan71dc23262015-10-14 12:41:19 +000038#include "util/llvm-utils.h"
Wang Nan8690a2a2016-02-22 09:10:32 +000039#include "util/bpf-loader.h"
Wang Nan5f9cf592016-04-20 18:59:49 +000040#include "util/trigger.h"
Wang Nana0748652016-11-26 07:03:28 +000041#include "util/perf-hooks.h"
Alexey Budankovf13de662019-01-22 20:50:57 +030042#include "util/cpu-set-sched.h"
Arnaldo Carvalho de Meloea49e012019-09-18 11:36:13 -030043#include "util/synthetic-events.h"
Arnaldo Carvalho de Meloc5e40272017-04-19 16:12:39 -030044#include "util/time-utils.h"
Arnaldo Carvalho de Melo58db1d62017-04-19 16:05:56 -030045#include "util/units.h"
Song Liu7b612e22019-01-17 08:15:19 -080046#include "util/bpf-event.h"
Stephane Eraniand99c22e2020-04-22 08:50:38 -070047#include "util/util.h"
Wang Nand8871ea2016-02-26 09:32:06 +000048#include "asm/bug.h"
Arnaldo Carvalho de Meloc1a604d2019-08-29 15:20:59 -030049#include "perf.h"
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +020050
Arnaldo Carvalho de Meloa43783a2017-04-18 10:46:11 -030051#include <errno.h>
Arnaldo Carvalho de Melofd20e812017-04-17 15:23:08 -030052#include <inttypes.h>
Arnaldo Carvalho de Melo67230472018-03-01 13:46:23 -030053#include <locale.h>
Arnaldo Carvalho de Melo42087352017-04-19 19:06:30 -030054#include <poll.h>
Stephane Eraniand99c22e2020-04-22 08:50:38 -070055#include <pthread.h>
Peter Zijlstra97124d5e2009-06-02 15:52:24 +020056#include <unistd.h>
Peter Zijlstrade9ac072009-04-08 15:01:31 +020057#include <sched.h>
Arnaldo Carvalho de Melo9607ad32017-04-19 15:49:18 -030058#include <signal.h>
Anand K Mistryda231332020-05-13 12:20:23 +100059#ifdef HAVE_EVENTFD_SUPPORT
60#include <sys/eventfd.h>
61#endif
Arnaldo Carvalho de Meloa41794c2010-05-18 18:29:23 -030062#include <sys/mman.h>
Arnaldo Carvalho de Melo42087352017-04-19 19:06:30 -030063#include <sys/wait.h>
Adrian Huntereeb399b2019-10-04 11:31:21 +030064#include <sys/types.h>
65#include <sys/stat.h>
66#include <fcntl.h>
Mamatha Inamdar6ef81c52019-08-22 12:50:49 +053067#include <linux/err.h>
Arnaldo Carvalho de Melo8520a982019-08-29 16:18:59 -030068#include <linux/string.h>
Arnaldo Carvalho de Melo0693e682016-08-08 15:05:46 -030069#include <linux/time64.h>
Arnaldo Carvalho de Melod8f9da22019-07-04 12:06:20 -030070#include <linux/zalloc.h>
Alexey Budankov8384a262019-12-03 14:45:27 +030071#include <linux/bitmap.h>
Bernhard Rosenkraenzer78da39f2012-10-08 09:43:26 +030072
Jiri Olsa1b43b702017-01-09 10:51:56 +010073struct switch_output {
Jiri Olsadc0c6122017-01-09 10:51:58 +010074 bool enabled;
Jiri Olsa1b43b702017-01-09 10:51:56 +010075 bool signal;
Jiri Olsadc0c6122017-01-09 10:51:58 +010076 unsigned long size;
Jiri Olsabfacbe32017-01-09 10:52:00 +010077 unsigned long time;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +010078 const char *str;
79 bool set;
Andi Kleen03724b22019-03-14 15:49:55 -070080 char **filenames;
81 int num_files;
82 int cur_file;
Jiri Olsa1b43b702017-01-09 10:51:56 +010083};
84
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -030085struct record {
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -020086 struct perf_tool tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -030087 struct record_opts opts;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020088 u64 bytes_written;
Jiri Olsa8ceb41d2017-01-23 22:07:59 +010089 struct perf_data data;
Adrian Hunteref149c22015-04-09 18:53:45 +030090 struct auxtrace_record *itr;
Jiri Olsa63503db2019-07-21 13:23:52 +020091 struct evlist *evlist;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020092 struct perf_session *session;
Arnaldo Carvalho de Melobc477d792020-04-24 10:24:04 -030093 struct evlist *sb_evlist;
Arnaldo Carvalho de Melo899e5ff2020-04-27 17:56:37 -030094 pthread_t thread_id;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020095 int realtime_prio;
Arnaldo Carvalho de Melo899e5ff2020-04-27 17:56:37 -030096 bool switch_output_event_set;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020097 bool no_buildid;
Wang Nand2db9a92016-01-25 09:56:19 +000098 bool no_buildid_set;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -020099 bool no_buildid_cache;
Wang Nand2db9a92016-01-25 09:56:19 +0000100 bool no_buildid_cache_set;
Namhyung Kim61566812016-01-11 22:37:09 +0900101 bool buildid_all;
Wang Nanecfd7a92016-04-13 08:21:07 +0000102 bool timestamp_filename;
Jin Yao68588ba2017-12-08 21:13:42 +0800103 bool timestamp_boundary;
Jiri Olsa1b43b702017-01-09 10:51:56 +0100104 struct switch_output switch_output;
Yang Shi9f065192015-09-29 14:49:43 -0700105 unsigned long long samples;
Alexey Budankov8384a262019-12-03 14:45:27 +0300106 struct mmap_cpu_mask affinity_mask;
Jiwei Sun6d575812019-10-22 16:09:01 +0800107 unsigned long output_max_size; /* = 0: unlimited */
Arnaldo Carvalho de Melo0f82ebc2011-11-08 14:41:57 -0200108};
Ingo Molnara21ca2c2009-06-06 09:58:57 +0200109
Jiwei Sun6d575812019-10-22 16:09:01 +0800110static volatile int done;
111
Jiri Olsadc0c6122017-01-09 10:51:58 +0100112static volatile int auxtrace_record__snapshot_started;
113static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
114static DEFINE_TRIGGER(switch_output_trigger);
115
Alexey Budankov9d2ed642019-01-22 20:47:43 +0300116static const char *affinity_tags[PERF_AFFINITY_MAX] = {
117 "SYS", "NODE", "CPU"
118};
119
Jiri Olsadc0c6122017-01-09 10:51:58 +0100120static bool switch_output_signal(struct record *rec)
121{
122 return rec->switch_output.signal &&
123 trigger_is_ready(&switch_output_trigger);
124}
125
126static bool switch_output_size(struct record *rec)
127{
128 return rec->switch_output.size &&
129 trigger_is_ready(&switch_output_trigger) &&
130 (rec->bytes_written >= rec->switch_output.size);
131}
132
Jiri Olsabfacbe32017-01-09 10:52:00 +0100133static bool switch_output_time(struct record *rec)
134{
135 return rec->switch_output.time &&
136 trigger_is_ready(&switch_output_trigger);
137}
138
Jiwei Sun6d575812019-10-22 16:09:01 +0800139static bool record__output_max_size_exceeded(struct record *rec)
140{
141 return rec->output_max_size &&
142 (rec->bytes_written >= rec->output_max_size);
143}
144
Jiri Olsaa5830532019-07-27 20:30:53 +0200145static int record__write(struct record *rec, struct mmap *map __maybe_unused,
Jiri Olsaded2b8f2018-09-13 14:54:06 +0200146 void *bf, size_t size)
Peter Zijlstraf5970552009-06-18 23:22:55 +0200147{
Jiri Olsaded2b8f2018-09-13 14:54:06 +0200148 struct perf_data_file *file = &rec->session->data->file;
149
150 if (perf_data_file__write(file, bf, size) < 0) {
Jiri Olsa50a9b862013-11-22 13:11:24 +0100151 pr_err("failed to write perf data, error: %m\n");
152 return -1;
Peter Zijlstraf5970552009-06-18 23:22:55 +0200153 }
David Ahern8d3eca22012-08-26 12:24:47 -0600154
Arnaldo Carvalho de Melocf8b2e62013-12-19 14:26:26 -0300155 rec->bytes_written += size;
Jiri Olsadc0c6122017-01-09 10:51:58 +0100156
Jiwei Sun6d575812019-10-22 16:09:01 +0800157 if (record__output_max_size_exceeded(rec) && !done) {
158 fprintf(stderr, "[ perf record: perf size limit reached (%" PRIu64 " KB),"
159 " stopping session ]\n",
160 rec->bytes_written >> 10);
161 done = 1;
162 }
163
Jiri Olsadc0c6122017-01-09 10:51:58 +0100164 if (switch_output_size(rec))
165 trigger_hit(&switch_output_trigger);
166
David Ahern8d3eca22012-08-26 12:24:47 -0600167 return 0;
Peter Zijlstraf5970552009-06-18 23:22:55 +0200168}
169
Alexey Budankovef781122019-03-18 20:44:12 +0300170static int record__aio_enabled(struct record *rec);
171static int record__comp_enabled(struct record *rec);
Alexey Budankov5d7f4112019-03-18 20:43:35 +0300172static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_size,
173 void *src, size_t src_size);
174
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300175#ifdef HAVE_AIO_SUPPORT
176static int record__aio_write(struct aiocb *cblock, int trace_fd,
177 void *buf, size_t size, off_t off)
178{
179 int rc;
180
181 cblock->aio_fildes = trace_fd;
182 cblock->aio_buf = buf;
183 cblock->aio_nbytes = size;
184 cblock->aio_offset = off;
185 cblock->aio_sigevent.sigev_notify = SIGEV_NONE;
186
187 do {
188 rc = aio_write(cblock);
189 if (rc == 0) {
190 break;
191 } else if (errno != EAGAIN) {
192 cblock->aio_fildes = -1;
193 pr_err("failed to queue perf data, error: %m\n");
194 break;
195 }
196 } while (1);
197
198 return rc;
199}
200
Jiri Olsaa5830532019-07-27 20:30:53 +0200201static int record__aio_complete(struct mmap *md, struct aiocb *cblock)
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300202{
203 void *rem_buf;
204 off_t rem_off;
205 size_t rem_size;
206 int rc, aio_errno;
207 ssize_t aio_ret, written;
208
209 aio_errno = aio_error(cblock);
210 if (aio_errno == EINPROGRESS)
211 return 0;
212
213 written = aio_ret = aio_return(cblock);
214 if (aio_ret < 0) {
215 if (aio_errno != EINTR)
216 pr_err("failed to write perf data, error: %m\n");
217 written = 0;
218 }
219
220 rem_size = cblock->aio_nbytes - written;
221
222 if (rem_size == 0) {
223 cblock->aio_fildes = -1;
224 /*
Alexey Budankovef781122019-03-18 20:44:12 +0300225 * md->refcount is incremented in record__aio_pushfn() for
226 * every aio write request started in record__aio_push() so
227 * decrement it because the request is now complete.
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300228 */
Jiri Olsa80e53d12019-10-07 14:53:15 +0200229 perf_mmap__put(&md->core);
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300230 rc = 1;
231 } else {
232 /*
233 * aio write request may require restart with the
234 * reminder if the kernel didn't write whole
235 * chunk at once.
236 */
237 rem_off = cblock->aio_offset + written;
238 rem_buf = (void *)(cblock->aio_buf + written);
239 record__aio_write(cblock, cblock->aio_fildes,
240 rem_buf, rem_size, rem_off);
241 rc = 0;
242 }
243
244 return rc;
245}
246
Jiri Olsaa5830532019-07-27 20:30:53 +0200247static int record__aio_sync(struct mmap *md, bool sync_all)
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300248{
Alexey Budankov93f20c02018-11-06 12:07:19 +0300249 struct aiocb **aiocb = md->aio.aiocb;
250 struct aiocb *cblocks = md->aio.cblocks;
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300251 struct timespec timeout = { 0, 1000 * 1000 * 1 }; /* 1ms */
Alexey Budankov93f20c02018-11-06 12:07:19 +0300252 int i, do_suspend;
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300253
254 do {
Alexey Budankov93f20c02018-11-06 12:07:19 +0300255 do_suspend = 0;
256 for (i = 0; i < md->aio.nr_cblocks; ++i) {
257 if (cblocks[i].aio_fildes == -1 || record__aio_complete(md, &cblocks[i])) {
258 if (sync_all)
259 aiocb[i] = NULL;
260 else
261 return i;
262 } else {
263 /*
264 * Started aio write is not complete yet
265 * so it has to be waited before the
266 * next allocation.
267 */
268 aiocb[i] = &cblocks[i];
269 do_suspend = 1;
270 }
271 }
272 if (!do_suspend)
273 return -1;
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300274
Alexey Budankov93f20c02018-11-06 12:07:19 +0300275 while (aio_suspend((const struct aiocb **)aiocb, md->aio.nr_cblocks, &timeout)) {
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300276 if (!(errno == EAGAIN || errno == EINTR))
277 pr_err("failed to sync perf data, error: %m\n");
278 }
279 } while (1);
280}
281
Alexey Budankovef781122019-03-18 20:44:12 +0300282struct record_aio {
283 struct record *rec;
284 void *data;
285 size_t size;
286};
287
Jiri Olsaa5830532019-07-27 20:30:53 +0200288static int record__aio_pushfn(struct mmap *map, void *to, void *buf, size_t size)
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300289{
Alexey Budankovef781122019-03-18 20:44:12 +0300290 struct record_aio *aio = to;
291
292 /*
Jiri Olsa547740f2019-07-27 22:07:44 +0200293 * map->core.base data pointed by buf is copied into free map->aio.data[] buffer
Alexey Budankovef781122019-03-18 20:44:12 +0300294 * to release space in the kernel buffer as fast as possible, calling
295 * perf_mmap__consume() from perf_mmap__push() function.
296 *
297 * That lets the kernel to proceed with storing more profiling data into
298 * the kernel buffer earlier than other per-cpu kernel buffers are handled.
299 *
300 * Coping can be done in two steps in case the chunk of profiling data
301 * crosses the upper bound of the kernel buffer. In this case we first move
302 * part of data from map->start till the upper bound and then the reminder
303 * from the beginning of the kernel buffer till the end of the data chunk.
304 */
305
306 if (record__comp_enabled(aio->rec)) {
307 size = zstd_compress(aio->rec->session, aio->data + aio->size,
Jiri Olsabf59b302019-10-07 14:53:11 +0200308 mmap__mmap_len(map) - aio->size,
Alexey Budankovef781122019-03-18 20:44:12 +0300309 buf, size);
310 } else {
311 memcpy(aio->data + aio->size, buf, size);
312 }
313
314 if (!aio->size) {
315 /*
316 * Increment map->refcount to guard map->aio.data[] buffer
317 * from premature deallocation because map object can be
318 * released earlier than aio write request started on
319 * map->aio.data[] buffer is complete.
320 *
321 * perf_mmap__put() is done at record__aio_complete()
322 * after started aio request completion or at record__aio_push()
323 * if the request failed to start.
324 */
Jiri Olsae75710f2019-10-07 14:53:13 +0200325 perf_mmap__get(&map->core);
Alexey Budankovef781122019-03-18 20:44:12 +0300326 }
327
328 aio->size += size;
329
330 return size;
331}
332
Jiri Olsaa5830532019-07-27 20:30:53 +0200333static int record__aio_push(struct record *rec, struct mmap *map, off_t *off)
Alexey Budankovef781122019-03-18 20:44:12 +0300334{
335 int ret, idx;
336 int trace_fd = rec->session->data->file.fd;
337 struct record_aio aio = { .rec = rec, .size = 0 };
338
339 /*
340 * Call record__aio_sync() to wait till map->aio.data[] buffer
341 * becomes available after previous aio write operation.
342 */
343
344 idx = record__aio_sync(map, false);
345 aio.data = map->aio.data[idx];
346 ret = perf_mmap__push(map, &aio, record__aio_pushfn);
347 if (ret != 0) /* ret > 0 - no data, ret < 0 - error */
348 return ret;
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300349
350 rec->samples++;
Alexey Budankovef781122019-03-18 20:44:12 +0300351 ret = record__aio_write(&(map->aio.cblocks[idx]), trace_fd, aio.data, aio.size, *off);
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300352 if (!ret) {
Alexey Budankovef781122019-03-18 20:44:12 +0300353 *off += aio.size;
354 rec->bytes_written += aio.size;
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300355 if (switch_output_size(rec))
356 trigger_hit(&switch_output_trigger);
Alexey Budankovef781122019-03-18 20:44:12 +0300357 } else {
358 /*
359 * Decrement map->refcount incremented in record__aio_pushfn()
360 * back if record__aio_write() operation failed to start, otherwise
361 * map->refcount is decremented in record__aio_complete() after
362 * aio write operation finishes successfully.
363 */
Jiri Olsa80e53d12019-10-07 14:53:15 +0200364 perf_mmap__put(&map->core);
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300365 }
366
367 return ret;
368}
369
370static off_t record__aio_get_pos(int trace_fd)
371{
372 return lseek(trace_fd, 0, SEEK_CUR);
373}
374
375static void record__aio_set_pos(int trace_fd, off_t pos)
376{
377 lseek(trace_fd, pos, SEEK_SET);
378}
379
380static void record__aio_mmap_read_sync(struct record *rec)
381{
382 int i;
Jiri Olsa63503db2019-07-21 13:23:52 +0200383 struct evlist *evlist = rec->evlist;
Jiri Olsaa5830532019-07-27 20:30:53 +0200384 struct mmap *maps = evlist->mmap;
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300385
Alexey Budankovef781122019-03-18 20:44:12 +0300386 if (!record__aio_enabled(rec))
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300387 return;
388
Jiri Olsac976ee12019-07-30 13:04:59 +0200389 for (i = 0; i < evlist->core.nr_mmaps; i++) {
Jiri Olsaa5830532019-07-27 20:30:53 +0200390 struct mmap *map = &maps[i];
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300391
Jiri Olsa547740f2019-07-27 22:07:44 +0200392 if (map->core.base)
Alexey Budankov93f20c02018-11-06 12:07:19 +0300393 record__aio_sync(map, true);
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300394 }
395}
396
397static int nr_cblocks_default = 1;
Alexey Budankov93f20c02018-11-06 12:07:19 +0300398static int nr_cblocks_max = 4;
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300399
400static int record__aio_parse(const struct option *opt,
Alexey Budankov93f20c02018-11-06 12:07:19 +0300401 const char *str,
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300402 int unset)
403{
404 struct record_opts *opts = (struct record_opts *)opt->value;
405
Alexey Budankov93f20c02018-11-06 12:07:19 +0300406 if (unset) {
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300407 opts->nr_cblocks = 0;
Alexey Budankov93f20c02018-11-06 12:07:19 +0300408 } else {
409 if (str)
410 opts->nr_cblocks = strtol(str, NULL, 0);
411 if (!opts->nr_cblocks)
412 opts->nr_cblocks = nr_cblocks_default;
413 }
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300414
415 return 0;
416}
417#else /* HAVE_AIO_SUPPORT */
Alexey Budankov93f20c02018-11-06 12:07:19 +0300418static int nr_cblocks_max = 0;
419
Jiri Olsaa5830532019-07-27 20:30:53 +0200420static int record__aio_push(struct record *rec __maybe_unused, struct mmap *map __maybe_unused,
Alexey Budankovef781122019-03-18 20:44:12 +0300421 off_t *off __maybe_unused)
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300422{
423 return -1;
424}
425
426static off_t record__aio_get_pos(int trace_fd __maybe_unused)
427{
428 return -1;
429}
430
431static void record__aio_set_pos(int trace_fd __maybe_unused, off_t pos __maybe_unused)
432{
433}
434
435static void record__aio_mmap_read_sync(struct record *rec __maybe_unused)
436{
437}
438#endif
439
440static int record__aio_enabled(struct record *rec)
441{
442 return rec->opts.nr_cblocks > 0;
443}
444
Alexey Budankov470530b2019-03-18 20:40:26 +0300445#define MMAP_FLUSH_DEFAULT 1
446static int record__mmap_flush_parse(const struct option *opt,
447 const char *str,
448 int unset)
449{
450 int flush_max;
451 struct record_opts *opts = (struct record_opts *)opt->value;
452 static struct parse_tag tags[] = {
453 { .tag = 'B', .mult = 1 },
454 { .tag = 'K', .mult = 1 << 10 },
455 { .tag = 'M', .mult = 1 << 20 },
456 { .tag = 'G', .mult = 1 << 30 },
457 { .tag = 0 },
458 };
459
460 if (unset)
461 return 0;
462
463 if (str) {
464 opts->mmap_flush = parse_tag_value(str, tags);
465 if (opts->mmap_flush == (int)-1)
466 opts->mmap_flush = strtol(str, NULL, 0);
467 }
468
469 if (!opts->mmap_flush)
470 opts->mmap_flush = MMAP_FLUSH_DEFAULT;
471
Jiri Olsa9521b5f2019-07-28 12:45:35 +0200472 flush_max = evlist__mmap_size(opts->mmap_pages);
Alexey Budankov470530b2019-03-18 20:40:26 +0300473 flush_max /= 4;
474 if (opts->mmap_flush > flush_max)
475 opts->mmap_flush = flush_max;
476
477 return 0;
478}
479
Alexey Budankov504c1ad2019-03-18 20:44:42 +0300480#ifdef HAVE_ZSTD_SUPPORT
481static unsigned int comp_level_default = 1;
482
483static int record__parse_comp_level(const struct option *opt, const char *str, int unset)
484{
485 struct record_opts *opts = opt->value;
486
487 if (unset) {
488 opts->comp_level = 0;
489 } else {
490 if (str)
491 opts->comp_level = strtol(str, NULL, 0);
492 if (!opts->comp_level)
493 opts->comp_level = comp_level_default;
494 }
495
496 return 0;
497}
498#endif
Alexey Budankov51255a82019-03-18 20:42:19 +0300499static unsigned int comp_level_max = 22;
500
Alexey Budankov42e1fd82019-03-18 20:41:33 +0300501static int record__comp_enabled(struct record *rec)
502{
503 return rec->opts.comp_level > 0;
504}
505
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200506static int process_synthesized_event(struct perf_tool *tool,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200507 union perf_event *event,
Irina Tirdea1d037ca2012-09-11 01:15:03 +0300508 struct perf_sample *sample __maybe_unused,
509 struct machine *machine __maybe_unused)
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -0200510{
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300511 struct record *rec = container_of(tool, struct record, tool);
Jiri Olsaded2b8f2018-09-13 14:54:06 +0200512 return record__write(rec, NULL, event, event->header.size);
Arnaldo Carvalho de Melo234fbbf2009-10-26 19:23:18 -0200513}
514
Stephane Eraniand99c22e2020-04-22 08:50:38 -0700515static int process_locked_synthesized_event(struct perf_tool *tool,
516 union perf_event *event,
517 struct perf_sample *sample __maybe_unused,
518 struct machine *machine __maybe_unused)
519{
520 static pthread_mutex_t synth_lock = PTHREAD_MUTEX_INITIALIZER;
521 int ret;
522
523 pthread_mutex_lock(&synth_lock);
524 ret = process_synthesized_event(tool, event, sample, machine);
525 pthread_mutex_unlock(&synth_lock);
526 return ret;
527}
528
Jiri Olsaa5830532019-07-27 20:30:53 +0200529static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size)
Arnaldo Carvalho de Melod37f1582017-10-05 16:39:55 -0300530{
531 struct record *rec = to;
532
Alexey Budankov5d7f4112019-03-18 20:43:35 +0300533 if (record__comp_enabled(rec)) {
Jiri Olsabf59b302019-10-07 14:53:11 +0200534 size = zstd_compress(rec->session, map->data, mmap__mmap_len(map), bf, size);
Alexey Budankov5d7f4112019-03-18 20:43:35 +0300535 bf = map->data;
536 }
537
Arnaldo Carvalho de Melod37f1582017-10-05 16:39:55 -0300538 rec->samples++;
Jiri Olsaded2b8f2018-09-13 14:54:06 +0200539 return record__write(rec, map, bf, size);
Arnaldo Carvalho de Melod37f1582017-10-05 16:39:55 -0300540}
541
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300542static volatile int signr = -1;
543static volatile int child_finished;
Anand K Mistryda231332020-05-13 12:20:23 +1000544#ifdef HAVE_EVENTFD_SUPPORT
545static int done_fd = -1;
546#endif
Wang Nanc0bdc1c2016-04-13 08:21:06 +0000547
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300548static void sig_handler(int sig)
549{
550 if (sig == SIGCHLD)
551 child_finished = 1;
552 else
553 signr = sig;
554
555 done = 1;
Anand K Mistryda231332020-05-13 12:20:23 +1000556#ifdef HAVE_EVENTFD_SUPPORT
557{
558 u64 tmp = 1;
559 /*
560 * It is possible for this signal handler to run after done is checked
561 * in the main loop, but before the perf counter fds are polled. If this
562 * happens, the poll() will continue to wait even though done is set,
563 * and will only break out if either another signal is received, or the
564 * counters are ready for read. To ensure the poll() doesn't sleep when
565 * done is set, use an eventfd (done_fd) to wake up the poll().
566 */
567 if (write(done_fd, &tmp, sizeof(tmp)) < 0)
568 pr_err("failed to signal wakeup fd, error: %m\n");
569}
570#endif // HAVE_EVENTFD_SUPPORT
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300571}
572
Wang Nana0748652016-11-26 07:03:28 +0000573static void sigsegv_handler(int sig)
574{
575 perf_hooks__recover();
576 sighandler_dump_stack(sig);
577}
578
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300579static void record__sig_exit(void)
580{
581 if (signr == -1)
582 return;
583
584 signal(signr, SIG_DFL);
585 raise(signr);
586}
587
Adrian Huntere31f0d02015-04-30 17:37:27 +0300588#ifdef HAVE_AUXTRACE_SUPPORT
589
Adrian Hunteref149c22015-04-09 18:53:45 +0300590static int record__process_auxtrace(struct perf_tool *tool,
Jiri Olsaa5830532019-07-27 20:30:53 +0200591 struct mmap *map,
Adrian Hunteref149c22015-04-09 18:53:45 +0300592 union perf_event *event, void *data1,
593 size_t len1, void *data2, size_t len2)
594{
595 struct record *rec = container_of(tool, struct record, tool);
Jiri Olsa8ceb41d2017-01-23 22:07:59 +0100596 struct perf_data *data = &rec->data;
Adrian Hunteref149c22015-04-09 18:53:45 +0300597 size_t padding;
598 u8 pad[8] = {0};
599
Adrian Hunter46e201e2019-10-04 11:31:20 +0300600 if (!perf_data__is_pipe(data) && perf_data__is_single_file(data)) {
Adrian Hunter99fa2982015-04-30 17:37:25 +0300601 off_t file_offset;
Jiri Olsa8ceb41d2017-01-23 22:07:59 +0100602 int fd = perf_data__fd(data);
Adrian Hunter99fa2982015-04-30 17:37:25 +0300603 int err;
604
605 file_offset = lseek(fd, 0, SEEK_CUR);
606 if (file_offset == -1)
607 return -1;
608 err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index,
609 event, file_offset);
610 if (err)
611 return err;
612 }
613
Adrian Hunteref149c22015-04-09 18:53:45 +0300614 /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */
615 padding = (len1 + len2) & 7;
616 if (padding)
617 padding = 8 - padding;
618
Jiri Olsaded2b8f2018-09-13 14:54:06 +0200619 record__write(rec, map, event, event->header.size);
620 record__write(rec, map, data1, len1);
Adrian Hunteref149c22015-04-09 18:53:45 +0300621 if (len2)
Jiri Olsaded2b8f2018-09-13 14:54:06 +0200622 record__write(rec, map, data2, len2);
623 record__write(rec, map, &pad, padding);
Adrian Hunteref149c22015-04-09 18:53:45 +0300624
625 return 0;
626}
627
628static int record__auxtrace_mmap_read(struct record *rec,
Jiri Olsaa5830532019-07-27 20:30:53 +0200629 struct mmap *map)
Adrian Hunteref149c22015-04-09 18:53:45 +0300630{
631 int ret;
632
Jiri Olsae035f4c2018-09-13 14:54:05 +0200633 ret = auxtrace_mmap__read(map, rec->itr, &rec->tool,
Adrian Hunteref149c22015-04-09 18:53:45 +0300634 record__process_auxtrace);
635 if (ret < 0)
636 return ret;
637
638 if (ret)
639 rec->samples++;
640
641 return 0;
642}
643
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300644static int record__auxtrace_mmap_read_snapshot(struct record *rec,
Jiri Olsaa5830532019-07-27 20:30:53 +0200645 struct mmap *map)
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300646{
647 int ret;
648
Jiri Olsae035f4c2018-09-13 14:54:05 +0200649 ret = auxtrace_mmap__read_snapshot(map, rec->itr, &rec->tool,
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300650 record__process_auxtrace,
651 rec->opts.auxtrace_snapshot_size);
652 if (ret < 0)
653 return ret;
654
655 if (ret)
656 rec->samples++;
657
658 return 0;
659}
660
661static int record__auxtrace_read_snapshot_all(struct record *rec)
662{
663 int i;
664 int rc = 0;
665
Jiri Olsac976ee12019-07-30 13:04:59 +0200666 for (i = 0; i < rec->evlist->core.nr_mmaps; i++) {
Jiri Olsaa5830532019-07-27 20:30:53 +0200667 struct mmap *map = &rec->evlist->mmap[i];
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300668
Jiri Olsae035f4c2018-09-13 14:54:05 +0200669 if (!map->auxtrace_mmap.base)
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300670 continue;
671
Jiri Olsae035f4c2018-09-13 14:54:05 +0200672 if (record__auxtrace_mmap_read_snapshot(rec, map) != 0) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300673 rc = -1;
674 goto out;
675 }
676 }
677out:
678 return rc;
679}
680
Alexander Shishkince7b0e42019-08-06 17:41:01 +0300681static void record__read_auxtrace_snapshot(struct record *rec, bool on_exit)
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300682{
683 pr_debug("Recording AUX area tracing snapshot\n");
684 if (record__auxtrace_read_snapshot_all(rec) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +0000685 trigger_error(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300686 } else {
Alexander Shishkince7b0e42019-08-06 17:41:01 +0300687 if (auxtrace_record__snapshot_finish(rec->itr, on_exit))
Wang Nan5f9cf592016-04-20 18:59:49 +0000688 trigger_error(&auxtrace_snapshot_trigger);
689 else
690 trigger_ready(&auxtrace_snapshot_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300691 }
692}
693
Alexander Shishkince7b0e42019-08-06 17:41:01 +0300694static int record__auxtrace_snapshot_exit(struct record *rec)
695{
696 if (trigger_is_error(&auxtrace_snapshot_trigger))
697 return 0;
698
699 if (!auxtrace_record__snapshot_started &&
700 auxtrace_record__snapshot_start(rec->itr))
701 return -1;
702
703 record__read_auxtrace_snapshot(rec, true);
704 if (trigger_is_error(&auxtrace_snapshot_trigger))
705 return -1;
706
707 return 0;
708}
709
Adrian Hunter4b5ea3b2018-03-06 11:13:12 +0200710static int record__auxtrace_init(struct record *rec)
711{
712 int err;
713
714 if (!rec->itr) {
715 rec->itr = auxtrace_record__init(rec->evlist, &err);
716 if (err)
717 return err;
718 }
719
720 err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
721 rec->opts.auxtrace_snapshot_opts);
722 if (err)
723 return err;
724
Adrian Hunterc0a6de02019-11-15 14:42:16 +0200725 err = auxtrace_parse_sample_options(rec->itr, rec->evlist, &rec->opts,
726 rec->opts.auxtrace_sample_opts);
727 if (err)
728 return err;
729
Adrian Hunter4b5ea3b2018-03-06 11:13:12 +0200730 return auxtrace_parse_filters(rec->evlist);
731}
732
Adrian Huntere31f0d02015-04-30 17:37:27 +0300733#else
734
735static inline
736int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
Jiri Olsaa5830532019-07-27 20:30:53 +0200737 struct mmap *map __maybe_unused)
Adrian Huntere31f0d02015-04-30 17:37:27 +0300738{
739 return 0;
740}
741
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300742static inline
Alexander Shishkince7b0e42019-08-06 17:41:01 +0300743void record__read_auxtrace_snapshot(struct record *rec __maybe_unused,
744 bool on_exit __maybe_unused)
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +0300745{
746}
747
748static inline
749int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
750{
751 return 0;
752}
753
Alexander Shishkince7b0e42019-08-06 17:41:01 +0300754static inline
755int record__auxtrace_snapshot_exit(struct record *rec __maybe_unused)
756{
757 return 0;
758}
759
Adrian Hunter4b5ea3b2018-03-06 11:13:12 +0200760static int record__auxtrace_init(struct record *rec __maybe_unused)
761{
762 return 0;
763}
764
Adrian Huntere31f0d02015-04-30 17:37:27 +0300765#endif
766
Adrian Huntereeb399b2019-10-04 11:31:21 +0300767static bool record__kcore_readable(struct machine *machine)
768{
769 char kcore[PATH_MAX];
770 int fd;
771
772 scnprintf(kcore, sizeof(kcore), "%s/proc/kcore", machine->root_dir);
773
774 fd = open(kcore, O_RDONLY);
775 if (fd < 0)
776 return false;
777
778 close(fd);
779
780 return true;
781}
782
783static int record__kcore_copy(struct machine *machine, struct perf_data *data)
784{
785 char from_dir[PATH_MAX];
786 char kcore_dir[PATH_MAX];
787 int ret;
788
789 snprintf(from_dir, sizeof(from_dir), "%s/proc", machine->root_dir);
790
791 ret = perf_data__make_kcore_dir(data, kcore_dir, sizeof(kcore_dir));
792 if (ret)
793 return ret;
794
795 return kcore_copy(from_dir, kcore_dir);
796}
797
Wang Nancda57a82016-06-27 10:24:03 +0000798static int record__mmap_evlist(struct record *rec,
Jiri Olsa63503db2019-07-21 13:23:52 +0200799 struct evlist *evlist)
Wang Nancda57a82016-06-27 10:24:03 +0000800{
801 struct record_opts *opts = &rec->opts;
Adrian Hunterc0a6de02019-11-15 14:42:16 +0200802 bool auxtrace_overwrite = opts->auxtrace_snapshot_mode ||
803 opts->auxtrace_sample_mode;
Wang Nancda57a82016-06-27 10:24:03 +0000804 char msg[512];
805
Alexey Budankovf13de662019-01-22 20:50:57 +0300806 if (opts->affinity != PERF_AFFINITY_SYS)
807 cpu__setup_cpunode_map();
808
Jiri Olsa9521b5f2019-07-28 12:45:35 +0200809 if (evlist__mmap_ex(evlist, opts->mmap_pages,
Wang Nancda57a82016-06-27 10:24:03 +0000810 opts->auxtrace_mmap_pages,
Adrian Hunterc0a6de02019-11-15 14:42:16 +0200811 auxtrace_overwrite,
Alexey Budankov470530b2019-03-18 20:40:26 +0300812 opts->nr_cblocks, opts->affinity,
Alexey Budankov51255a82019-03-18 20:42:19 +0300813 opts->mmap_flush, opts->comp_level) < 0) {
Wang Nancda57a82016-06-27 10:24:03 +0000814 if (errno == EPERM) {
815 pr_err("Permission error mapping pages.\n"
816 "Consider increasing "
817 "/proc/sys/kernel/perf_event_mlock_kb,\n"
818 "or try again with a smaller value of -m/--mmap_pages.\n"
819 "(current value: %u,%u)\n",
820 opts->mmap_pages, opts->auxtrace_mmap_pages);
821 return -errno;
822 } else {
823 pr_err("failed to mmap with %d (%s)\n", errno,
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300824 str_error_r(errno, msg, sizeof(msg)));
Wang Nancda57a82016-06-27 10:24:03 +0000825 if (errno)
826 return -errno;
827 else
828 return -EINVAL;
829 }
830 }
831 return 0;
832}
833
834static int record__mmap(struct record *rec)
835{
836 return record__mmap_evlist(rec, rec->evlist);
837}
838
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300839static int record__open(struct record *rec)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200840{
Arnaldo Carvalho de Melod6195a62017-02-13 16:45:24 -0300841 char msg[BUFSIZ];
Jiri Olsa32dcd022019-07-21 13:23:51 +0200842 struct evsel *pos;
Jiri Olsa63503db2019-07-21 13:23:52 +0200843 struct evlist *evlist = rec->evlist;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -0200844 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -0300845 struct record_opts *opts = &rec->opts;
David Ahern8d3eca22012-08-26 12:24:47 -0600846 int rc = 0;
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -0200847
Arnaldo Carvalho de Melod3dbf432017-11-03 15:34:34 -0300848 /*
Ian Rogers0a892c12020-04-22 10:36:15 -0700849 * For initial_delay or system wide, we need to add a dummy event so
850 * that we can track PERF_RECORD_MMAP to cover the delay of waiting or
851 * event synthesis.
Arnaldo Carvalho de Melod3dbf432017-11-03 15:34:34 -0300852 */
Ian Rogers0a892c12020-04-22 10:36:15 -0700853 if (opts->initial_delay || target__has_cpu(&opts->target)) {
Arnaldo Carvalho de Melod3dbf432017-11-03 15:34:34 -0300854 if (perf_evlist__add_dummy(evlist))
855 return -ENOMEM;
856
Ian Rogers0a892c12020-04-22 10:36:15 -0700857 /* Disable tracking of mmaps on lead event. */
Jiri Olsa515dbe42019-09-03 10:39:52 +0200858 pos = evlist__first(evlist);
Arnaldo Carvalho de Melod3dbf432017-11-03 15:34:34 -0300859 pos->tracking = 0;
Ian Rogers0a892c12020-04-22 10:36:15 -0700860 /* Set up dummy event. */
Jiri Olsa515dbe42019-09-03 10:39:52 +0200861 pos = evlist__last(evlist);
Arnaldo Carvalho de Melod3dbf432017-11-03 15:34:34 -0300862 pos->tracking = 1;
Ian Rogers0a892c12020-04-22 10:36:15 -0700863 /*
864 * Enable the dummy event when the process is forked for
865 * initial_delay, immediately for system wide.
866 */
867 if (opts->initial_delay)
868 pos->core.attr.enable_on_exec = 1;
869 else
870 pos->immediate = 1;
Arnaldo Carvalho de Melod3dbf432017-11-03 15:34:34 -0300871 }
872
Arnaldo Carvalho de Meloe68ae9c2016-04-11 18:15:29 -0300873 perf_evlist__config(evlist, opts, &callchain_param);
Jiri Olsacac21422012-11-12 18:34:00 +0100874
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -0300875 evlist__for_each_entry(evlist, pos) {
Ingo Molnar3da297a2009-06-07 17:39:02 +0200876try_again:
Jiri Olsaaf663bd2019-07-21 13:24:39 +0200877 if (evsel__open(pos, pos->core.cpus, pos->core.threads) < 0) {
Arnaldo Carvalho de Meloae430892020-04-30 11:46:15 -0300878 if (evsel__fallback(pos, errno, msg, sizeof(msg))) {
Namhyung Kimbb963e12017-02-17 17:17:38 +0900879 if (verbose > 0)
Arnaldo Carvalho de Meloc0a54342012-12-13 14:16:30 -0300880 ui__warning("%s\n", msg);
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300881 goto try_again;
882 }
Andi Kleencf99ad12018-10-01 12:59:27 -0700883 if ((errno == EINVAL || errno == EBADF) &&
884 pos->leader != pos &&
885 pos->weak_group) {
Andi Kleen4804e012019-11-20 16:15:19 -0800886 pos = perf_evlist__reset_weak_group(evlist, pos, true);
Andi Kleencf99ad12018-10-01 12:59:27 -0700887 goto try_again;
888 }
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300889 rc = -errno;
Arnaldo Carvalho de Melo2bb72db2020-05-04 13:43:03 -0300890 evsel__open_strerror(pos, &opts->target, errno, msg, sizeof(msg));
Arnaldo Carvalho de Melo56e52e82012-12-13 15:10:58 -0300891 ui__error("%s\n", msg);
David Ahern8d3eca22012-08-26 12:24:47 -0600892 goto out;
Zhang, Yanmind6d901c2010-03-18 11:36:05 -0300893 }
Andi Kleenbfd8f722017-11-17 13:42:58 -0800894
895 pos->supported = true;
Li Zefanc171b552009-10-15 11:22:07 +0800896 }
Arnaldo Carvalho de Meloa43d3f02010-12-25 12:12:25 -0200897
Arnaldo Carvalho de Meloc8b567c2019-09-23 11:07:29 -0300898 if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(evlist)) {
899 pr_warning(
900"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
901"check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\n\n"
902"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
903"file is not found in the buildid cache or in the vmlinux path.\n\n"
904"Samples in kernel modules won't be resolved at all.\n\n"
905"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
906"even with a suitable vmlinux or kallsyms file.\n\n");
907 }
908
Arnaldo Carvalho de Melo23d4aad2015-03-24 19:23:47 -0300909 if (perf_evlist__apply_filters(evlist, &pos)) {
Arnaldo Carvalho de Melo62d94b02017-06-27 11:22:31 -0300910 pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
Arnaldo Carvalho de Melo8ab2e962020-04-29 16:07:09 -0300911 pos->filter, evsel__name(pos), errno,
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300912 str_error_r(errno, msg, sizeof(msg)));
David Ahern8d3eca22012-08-26 12:24:47 -0600913 rc = -1;
914 goto out;
Frederic Weisbecker0a102472011-02-26 04:51:54 +0100915 }
916
Wang Nancda57a82016-06-27 10:24:03 +0000917 rc = record__mmap(rec);
918 if (rc)
David Ahern8d3eca22012-08-26 12:24:47 -0600919 goto out;
Arnaldo Carvalho de Melo0a27d7f2011-01-14 15:50:51 -0200920
Jiri Olsa563aecb2013-06-05 13:35:06 +0200921 session->evlist = evlist;
Arnaldo Carvalho de Melo7b56cce2012-08-01 19:31:00 -0300922 perf_session__set_id_hdr_size(session);
David Ahern8d3eca22012-08-26 12:24:47 -0600923out:
924 return rc;
Peter Zijlstra16c8a102009-05-05 17:50:27 +0200925}
926
Namhyung Kime3d59112015-01-29 17:06:44 +0900927static int process_sample_event(struct perf_tool *tool,
928 union perf_event *event,
929 struct perf_sample *sample,
Jiri Olsa32dcd022019-07-21 13:23:51 +0200930 struct evsel *evsel,
Namhyung Kime3d59112015-01-29 17:06:44 +0900931 struct machine *machine)
932{
933 struct record *rec = container_of(tool, struct record, tool);
934
Jin Yao68588ba2017-12-08 21:13:42 +0800935 if (rec->evlist->first_sample_time == 0)
936 rec->evlist->first_sample_time = sample->time;
Namhyung Kime3d59112015-01-29 17:06:44 +0900937
Jin Yao68588ba2017-12-08 21:13:42 +0800938 rec->evlist->last_sample_time = sample->time;
939
940 if (rec->buildid_all)
941 return 0;
942
943 rec->samples++;
Namhyung Kime3d59112015-01-29 17:06:44 +0900944 return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
945}
946
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -0300947static int process_buildids(struct record *rec)
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200948{
Jiri Olsaf5fc14122013-10-15 16:27:32 +0200949 struct perf_session *session = rec->session;
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200950
Jiri Olsa45112e82019-02-21 10:41:29 +0100951 if (perf_data__size(&rec->data) == 0)
Arnaldo Carvalho de Melo9f591fd2010-03-11 15:53:11 -0300952 return 0;
953
Namhyung Kim00dc8652014-11-04 10:14:32 +0900954 /*
955 * During this process, it'll load kernel map and replace the
956 * dso->long_name to a real pathname it found. In this case
957 * we prefer the vmlinux path like
958 * /lib/modules/3.16.4/build/vmlinux
959 *
960 * rather than build-id path (in debug directory).
961 * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551
962 */
963 symbol_conf.ignore_vmlinux_buildid = true;
964
Namhyung Kim61566812016-01-11 22:37:09 +0900965 /*
966 * If --buildid-all is given, it marks all DSO regardless of hits,
Jin Yao68588ba2017-12-08 21:13:42 +0800967 * so no need to process samples. But if timestamp_boundary is enabled,
968 * it still needs to walk on all samples to get the timestamps of
969 * first/last samples.
Namhyung Kim61566812016-01-11 22:37:09 +0900970 */
Jin Yao68588ba2017-12-08 21:13:42 +0800971 if (rec->buildid_all && !rec->timestamp_boundary)
Namhyung Kim61566812016-01-11 22:37:09 +0900972 rec->tool.sample = NULL;
973
Arnaldo Carvalho de Melob7b61cb2015-03-03 11:58:45 -0300974 return perf_session__process_events(session);
Arnaldo Carvalho de Melo6122e4e2010-02-03 16:52:05 -0200975}
976
Arnaldo Carvalho de Melo8115d602011-01-29 14:01:45 -0200977static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800978{
979 int err;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200980 struct perf_tool *tool = data;
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800981 /*
982 *As for guest kernel when processing subcommand record&report,
983 *we arrange module mmap prior to guest kernel mmap and trigger
984 *a preload dso because default guest module symbols are loaded
985 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
986 *method is used to avoid symbol missing when the first addr is
987 *in module instead of in guest kernel.
988 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200989 err = perf_event__synthesize_modules(tool, process_synthesized_event,
Arnaldo Carvalho de Melo743eb862011-11-28 07:56:39 -0200990 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800991 if (err < 0)
992 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -0300993 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800994
Zhang, Yanmina1645ce2010-04-19 13:32:50 +0800995 /*
996 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
997 * have no _text sometimes.
998 */
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -0200999 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
Adrian Hunter0ae617b2014-01-29 16:14:40 +02001000 machine);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +08001001 if (err < 0)
1002 pr_err("Couldn't record guest kernel [%d]'s reference"
Arnaldo Carvalho de Melo23346f22010-04-27 21:17:50 -03001003 " relocation symbol.\n", machine->pid);
Zhang, Yanmina1645ce2010-04-19 13:32:50 +08001004}
1005
Frederic Weisbecker98402802010-05-02 22:05:29 +02001006static struct perf_event_header finished_round_event = {
1007 .size = sizeof(struct perf_event_header),
1008 .type = PERF_RECORD_FINISHED_ROUND,
1009};
1010
Jiri Olsaa5830532019-07-27 20:30:53 +02001011static void record__adjust_affinity(struct record *rec, struct mmap *map)
Alexey Budankovf13de662019-01-22 20:50:57 +03001012{
1013 if (rec->opts.affinity != PERF_AFFINITY_SYS &&
Alexey Budankov8384a262019-12-03 14:45:27 +03001014 !bitmap_equal(rec->affinity_mask.bits, map->affinity_mask.bits,
1015 rec->affinity_mask.nbits)) {
1016 bitmap_zero(rec->affinity_mask.bits, rec->affinity_mask.nbits);
1017 bitmap_or(rec->affinity_mask.bits, rec->affinity_mask.bits,
1018 map->affinity_mask.bits, rec->affinity_mask.nbits);
1019 sched_setaffinity(0, MMAP_CPU_MASK_BYTES(&rec->affinity_mask),
1020 (cpu_set_t *)rec->affinity_mask.bits);
1021 if (verbose == 2)
1022 mmap_cpu_mask__scnprintf(&rec->affinity_mask, "thread");
Alexey Budankovf13de662019-01-22 20:50:57 +03001023 }
1024}
1025
Alexey Budankov5d7f4112019-03-18 20:43:35 +03001026static size_t process_comp_header(void *record, size_t increment)
1027{
Jiri Olsa72932372019-08-28 15:57:16 +02001028 struct perf_record_compressed *event = record;
Alexey Budankov5d7f4112019-03-18 20:43:35 +03001029 size_t size = sizeof(*event);
1030
1031 if (increment) {
1032 event->header.size += increment;
1033 return increment;
1034 }
1035
1036 event->header.type = PERF_RECORD_COMPRESSED;
1037 event->header.size = size;
1038
1039 return size;
1040}
1041
1042static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_size,
1043 void *src, size_t src_size)
1044{
1045 size_t compressed;
Jiri Olsa72932372019-08-28 15:57:16 +02001046 size_t max_record_size = PERF_SAMPLE_MAX_SIZE - sizeof(struct perf_record_compressed) - 1;
Alexey Budankov5d7f4112019-03-18 20:43:35 +03001047
1048 compressed = zstd_compress_stream_to_records(&session->zstd_data, dst, dst_size, src, src_size,
1049 max_record_size, process_comp_header);
1050
1051 session->bytes_transferred += src_size;
1052 session->bytes_compressed += compressed;
1053
1054 return compressed;
1055}
1056
Jiri Olsa63503db2019-07-21 13:23:52 +02001057static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist,
Alexey Budankov470530b2019-03-18 20:40:26 +03001058 bool overwrite, bool synch)
Frederic Weisbecker98402802010-05-02 22:05:29 +02001059{
Jiri Olsadcabb502014-07-25 16:56:16 +02001060 u64 bytes_written = rec->bytes_written;
Peter Zijlstra0e2e63d2010-05-20 14:45:26 +02001061 int i;
David Ahern8d3eca22012-08-26 12:24:47 -06001062 int rc = 0;
Jiri Olsaa5830532019-07-27 20:30:53 +02001063 struct mmap *maps;
Alexey Budankovd3d1af62018-11-06 12:04:58 +03001064 int trace_fd = rec->data.file.fd;
Alexey Budankovef781122019-03-18 20:44:12 +03001065 off_t off = 0;
Frederic Weisbecker98402802010-05-02 22:05:29 +02001066
Wang Nancb216862016-06-27 10:24:04 +00001067 if (!evlist)
1068 return 0;
Adrian Hunteref149c22015-04-09 18:53:45 +03001069
Wang Nan0b72d692017-12-04 16:51:07 +00001070 maps = overwrite ? evlist->overwrite_mmap : evlist->mmap;
Wang Nana4ea0ec2016-07-14 08:34:36 +00001071 if (!maps)
1072 return 0;
Wang Nancb216862016-06-27 10:24:04 +00001073
Wang Nan0b72d692017-12-04 16:51:07 +00001074 if (overwrite && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING)
Wang Nan54cc54d2016-07-14 08:34:42 +00001075 return 0;
1076
Alexey Budankovd3d1af62018-11-06 12:04:58 +03001077 if (record__aio_enabled(rec))
1078 off = record__aio_get_pos(trace_fd);
1079
Jiri Olsac976ee12019-07-30 13:04:59 +02001080 for (i = 0; i < evlist->core.nr_mmaps; i++) {
Alexey Budankov470530b2019-03-18 20:40:26 +03001081 u64 flush = 0;
Jiri Olsaa5830532019-07-27 20:30:53 +02001082 struct mmap *map = &maps[i];
Wang Nana4ea0ec2016-07-14 08:34:36 +00001083
Jiri Olsa547740f2019-07-27 22:07:44 +02001084 if (map->core.base) {
Alexey Budankovf13de662019-01-22 20:50:57 +03001085 record__adjust_affinity(rec, map);
Alexey Budankov470530b2019-03-18 20:40:26 +03001086 if (synch) {
Jiri Olsa65aa2e62019-08-27 16:05:18 +02001087 flush = map->core.flush;
1088 map->core.flush = 1;
Alexey Budankov470530b2019-03-18 20:40:26 +03001089 }
Alexey Budankovd3d1af62018-11-06 12:04:58 +03001090 if (!record__aio_enabled(rec)) {
Alexey Budankovef781122019-03-18 20:44:12 +03001091 if (perf_mmap__push(map, rec, record__pushfn) < 0) {
Alexey Budankov470530b2019-03-18 20:40:26 +03001092 if (synch)
Jiri Olsa65aa2e62019-08-27 16:05:18 +02001093 map->core.flush = flush;
Alexey Budankovd3d1af62018-11-06 12:04:58 +03001094 rc = -1;
1095 goto out;
1096 }
1097 } else {
Alexey Budankovef781122019-03-18 20:44:12 +03001098 if (record__aio_push(rec, map, &off) < 0) {
Alexey Budankovd3d1af62018-11-06 12:04:58 +03001099 record__aio_set_pos(trace_fd, off);
Alexey Budankov470530b2019-03-18 20:40:26 +03001100 if (synch)
Jiri Olsa65aa2e62019-08-27 16:05:18 +02001101 map->core.flush = flush;
Alexey Budankovd3d1af62018-11-06 12:04:58 +03001102 rc = -1;
1103 goto out;
1104 }
David Ahern8d3eca22012-08-26 12:24:47 -06001105 }
Alexey Budankov470530b2019-03-18 20:40:26 +03001106 if (synch)
Jiri Olsa65aa2e62019-08-27 16:05:18 +02001107 map->core.flush = flush;
David Ahern8d3eca22012-08-26 12:24:47 -06001108 }
Adrian Hunteref149c22015-04-09 18:53:45 +03001109
Jiri Olsae035f4c2018-09-13 14:54:05 +02001110 if (map->auxtrace_mmap.base && !rec->opts.auxtrace_snapshot_mode &&
Adrian Hunterc0a6de02019-11-15 14:42:16 +02001111 !rec->opts.auxtrace_sample_mode &&
Jiri Olsae035f4c2018-09-13 14:54:05 +02001112 record__auxtrace_mmap_read(rec, map) != 0) {
Adrian Hunteref149c22015-04-09 18:53:45 +03001113 rc = -1;
1114 goto out;
1115 }
Frederic Weisbecker98402802010-05-02 22:05:29 +02001116 }
1117
Alexey Budankovd3d1af62018-11-06 12:04:58 +03001118 if (record__aio_enabled(rec))
1119 record__aio_set_pos(trace_fd, off);
1120
Jiri Olsadcabb502014-07-25 16:56:16 +02001121 /*
1122 * Mark the round finished in case we wrote
1123 * at least one event.
1124 */
1125 if (bytes_written != rec->bytes_written)
Jiri Olsaded2b8f2018-09-13 14:54:06 +02001126 rc = record__write(rec, NULL, &finished_round_event, sizeof(finished_round_event));
David Ahern8d3eca22012-08-26 12:24:47 -06001127
Wang Nan0b72d692017-12-04 16:51:07 +00001128 if (overwrite)
Wang Nan54cc54d2016-07-14 08:34:42 +00001129 perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY);
David Ahern8d3eca22012-08-26 12:24:47 -06001130out:
1131 return rc;
Frederic Weisbecker98402802010-05-02 22:05:29 +02001132}
1133
Alexey Budankov470530b2019-03-18 20:40:26 +03001134static int record__mmap_read_all(struct record *rec, bool synch)
Wang Nancb216862016-06-27 10:24:04 +00001135{
1136 int err;
1137
Alexey Budankov470530b2019-03-18 20:40:26 +03001138 err = record__mmap_read_evlist(rec, rec->evlist, false, synch);
Wang Nancb216862016-06-27 10:24:04 +00001139 if (err)
1140 return err;
1141
Alexey Budankov470530b2019-03-18 20:40:26 +03001142 return record__mmap_read_evlist(rec, rec->evlist, true, synch);
Wang Nancb216862016-06-27 10:24:04 +00001143}
1144
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001145static void record__init_features(struct record *rec)
David Ahern57706ab2013-11-06 11:41:34 -07001146{
David Ahern57706ab2013-11-06 11:41:34 -07001147 struct perf_session *session = rec->session;
1148 int feat;
1149
1150 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
1151 perf_header__set_feat(&session->header, feat);
1152
1153 if (rec->no_buildid)
1154 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
1155
Jiri Olsace9036a2019-07-21 13:24:23 +02001156 if (!have_tracepoints(&rec->evlist->core.entries))
David Ahern57706ab2013-11-06 11:41:34 -07001157 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
1158
1159 if (!rec->opts.branch_stack)
1160 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
Adrian Hunteref149c22015-04-09 18:53:45 +03001161
1162 if (!rec->opts.full_auxtrace)
1163 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
Jiri Olsaffa517a2015-10-25 15:51:43 +01001164
Alexey Budankovcf790512018-10-09 17:36:24 +03001165 if (!(rec->opts.use_clockid && rec->opts.clockid_res_ns))
1166 perf_header__clear_feat(&session->header, HEADER_CLOCKID);
1167
Jiri Olsa258031c2019-03-08 14:47:39 +01001168 perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
Alexey Budankov42e1fd82019-03-18 20:41:33 +03001169 if (!record__comp_enabled(rec))
1170 perf_header__clear_feat(&session->header, HEADER_COMPRESSED);
Jiri Olsa258031c2019-03-08 14:47:39 +01001171
Jiri Olsaffa517a2015-10-25 15:51:43 +01001172 perf_header__clear_feat(&session->header, HEADER_STAT);
David Ahern57706ab2013-11-06 11:41:34 -07001173}
1174
Wang Nane1ab48b2016-02-26 09:32:10 +00001175static void
1176record__finish_output(struct record *rec)
1177{
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001178 struct perf_data *data = &rec->data;
1179 int fd = perf_data__fd(data);
Wang Nane1ab48b2016-02-26 09:32:10 +00001180
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001181 if (data->is_pipe)
Wang Nane1ab48b2016-02-26 09:32:10 +00001182 return;
1183
1184 rec->session->header.data_size += rec->bytes_written;
Jiri Olsa45112e82019-02-21 10:41:29 +01001185 data->file.size = lseek(perf_data__fd(data), 0, SEEK_CUR);
Wang Nane1ab48b2016-02-26 09:32:10 +00001186
1187 if (!rec->no_buildid) {
1188 process_buildids(rec);
1189
1190 if (rec->buildid_all)
1191 dsos__hit_all(rec->session);
1192 }
1193 perf_session__write_header(rec->session, rec->evlist, fd, true);
1194
1195 return;
1196}
1197
Wang Nan4ea648a2016-07-14 08:34:47 +00001198static int record__synthesize_workload(struct record *rec, bool tail)
Wang Nanbe7b0c92016-04-20 18:59:54 +00001199{
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -03001200 int err;
Jiri Olsa9749b902019-07-21 13:23:50 +02001201 struct perf_thread_map *thread_map;
Wang Nanbe7b0c92016-04-20 18:59:54 +00001202
Wang Nan4ea648a2016-07-14 08:34:47 +00001203 if (rec->opts.tail_synthesize != tail)
1204 return 0;
1205
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -03001206 thread_map = thread_map__new_by_tid(rec->evlist->workload.pid);
1207 if (thread_map == NULL)
1208 return -1;
1209
1210 err = perf_event__synthesize_thread_map(&rec->tool, thread_map,
Wang Nanbe7b0c92016-04-20 18:59:54 +00001211 process_synthesized_event,
1212 &rec->session->machines.host,
Mark Drayton3fcb10e2018-12-04 12:34:20 -08001213 rec->opts.sample_address);
Jiri Olsa7836e522019-07-21 13:24:20 +02001214 perf_thread_map__put(thread_map);
Arnaldo Carvalho de Melo9d6aae72017-02-14 10:59:04 -03001215 return err;
Wang Nanbe7b0c92016-04-20 18:59:54 +00001216}
1217
Wang Nan4ea648a2016-07-14 08:34:47 +00001218static int record__synthesize(struct record *rec, bool tail);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001219
Wang Nanecfd7a92016-04-13 08:21:07 +00001220static int
1221record__switch_output(struct record *rec, bool at_exit)
1222{
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001223 struct perf_data *data = &rec->data;
Wang Nanecfd7a92016-04-13 08:21:07 +00001224 int fd, err;
Andi Kleen03724b22019-03-14 15:49:55 -07001225 char *new_filename;
Wang Nanecfd7a92016-04-13 08:21:07 +00001226
1227 /* Same Size: "2015122520103046"*/
1228 char timestamp[] = "InvalidTimestamp";
1229
Alexey Budankovd3d1af62018-11-06 12:04:58 +03001230 record__aio_mmap_read_sync(rec);
1231
Wang Nan4ea648a2016-07-14 08:34:47 +00001232 record__synthesize(rec, true);
1233 if (target__none(&rec->opts.target))
1234 record__synthesize_workload(rec, true);
1235
Wang Nanecfd7a92016-04-13 08:21:07 +00001236 rec->samples = 0;
1237 record__finish_output(rec);
1238 err = fetch_current_timestamp(timestamp, sizeof(timestamp));
1239 if (err) {
1240 pr_err("Failed to get current timestamp\n");
1241 return -EINVAL;
1242 }
1243
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001244 fd = perf_data__switch(data, timestamp,
Wang Nanecfd7a92016-04-13 08:21:07 +00001245 rec->session->header.data_offset,
Andi Kleen03724b22019-03-14 15:49:55 -07001246 at_exit, &new_filename);
Wang Nanecfd7a92016-04-13 08:21:07 +00001247 if (fd >= 0 && !at_exit) {
1248 rec->bytes_written = 0;
1249 rec->session->header.data_size = 0;
1250 }
1251
1252 if (!quiet)
1253 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
Jiri Olsa2d4f2792019-02-21 10:41:30 +01001254 data->path, timestamp);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001255
Andi Kleen03724b22019-03-14 15:49:55 -07001256 if (rec->switch_output.num_files) {
1257 int n = rec->switch_output.cur_file + 1;
1258
1259 if (n >= rec->switch_output.num_files)
1260 n = 0;
1261 rec->switch_output.cur_file = n;
1262 if (rec->switch_output.filenames[n]) {
1263 remove(rec->switch_output.filenames[n]);
Arnaldo Carvalho de Melod8f9da22019-07-04 12:06:20 -03001264 zfree(&rec->switch_output.filenames[n]);
Andi Kleen03724b22019-03-14 15:49:55 -07001265 }
1266 rec->switch_output.filenames[n] = new_filename;
1267 } else {
1268 free(new_filename);
1269 }
1270
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001271 /* Output tracking events */
Wang Nanbe7b0c92016-04-20 18:59:54 +00001272 if (!at_exit) {
Wang Nan4ea648a2016-07-14 08:34:47 +00001273 record__synthesize(rec, false);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001274
Wang Nanbe7b0c92016-04-20 18:59:54 +00001275 /*
1276 * In 'perf record --switch-output' without -a,
1277 * record__synthesize() in record__switch_output() won't
1278 * generate tracking events because there's no thread_map
1279 * in evlist. Which causes newly created perf.data doesn't
1280 * contain map and comm information.
1281 * Create a fake thread_map and directly call
1282 * perf_event__synthesize_thread_map() for those events.
1283 */
1284 if (target__none(&rec->opts.target))
Wang Nan4ea648a2016-07-14 08:34:47 +00001285 record__synthesize_workload(rec, false);
Wang Nanbe7b0c92016-04-20 18:59:54 +00001286 }
Wang Nanecfd7a92016-04-13 08:21:07 +00001287 return fd;
1288}
1289
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001290static volatile int workload_exec_errno;
1291
1292/*
1293 * perf_evlist__prepare_workload will send a SIGUSR1
1294 * if the fork fails, since we asked by setting its
1295 * want_signal to true.
1296 */
Namhyung Kim45604712014-05-12 09:47:24 +09001297static void workload_exec_failed_signal(int signo __maybe_unused,
1298 siginfo_t *info,
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001299 void *ucontext __maybe_unused)
1300{
1301 workload_exec_errno = info->si_value.sival_int;
1302 done = 1;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001303 child_finished = 1;
1304}
1305
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001306static void snapshot_sig_handler(int sig);
Jiri Olsabfacbe32017-01-09 10:52:00 +01001307static void alarm_sig_handler(int sig);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001308
Wang Nanee667f92016-06-27 10:24:05 +00001309static const struct perf_event_mmap_page *
Jiri Olsa63503db2019-07-21 13:23:52 +02001310perf_evlist__pick_pc(struct evlist *evlist)
Wang Nanee667f92016-06-27 10:24:05 +00001311{
Wang Nanb2cb6152016-07-14 08:34:39 +00001312 if (evlist) {
Jiri Olsa547740f2019-07-27 22:07:44 +02001313 if (evlist->mmap && evlist->mmap[0].core.base)
1314 return evlist->mmap[0].core.base;
1315 if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].core.base)
1316 return evlist->overwrite_mmap[0].core.base;
Wang Nanb2cb6152016-07-14 08:34:39 +00001317 }
Wang Nanee667f92016-06-27 10:24:05 +00001318 return NULL;
1319}
1320
Wang Nanc45628b2016-05-24 02:28:59 +00001321static const struct perf_event_mmap_page *record__pick_pc(struct record *rec)
1322{
Wang Nanee667f92016-06-27 10:24:05 +00001323 const struct perf_event_mmap_page *pc;
1324
1325 pc = perf_evlist__pick_pc(rec->evlist);
1326 if (pc)
1327 return pc;
Wang Nanc45628b2016-05-24 02:28:59 +00001328 return NULL;
1329}
1330
Wang Nan4ea648a2016-07-14 08:34:47 +00001331static int record__synthesize(struct record *rec, bool tail)
Wang Nanc45c86e2016-02-26 09:32:07 +00001332{
1333 struct perf_session *session = rec->session;
1334 struct machine *machine = &session->machines.host;
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001335 struct perf_data *data = &rec->data;
Wang Nanc45c86e2016-02-26 09:32:07 +00001336 struct record_opts *opts = &rec->opts;
1337 struct perf_tool *tool = &rec->tool;
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001338 int fd = perf_data__fd(data);
Wang Nanc45c86e2016-02-26 09:32:07 +00001339 int err = 0;
Stephane Eraniand99c22e2020-04-22 08:50:38 -07001340 event_op f = process_synthesized_event;
Wang Nanc45c86e2016-02-26 09:32:07 +00001341
Wang Nan4ea648a2016-07-14 08:34:47 +00001342 if (rec->opts.tail_synthesize != tail)
1343 return 0;
1344
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001345 if (data->is_pipe) {
Jiri Olsaa2015512018-03-14 10:22:04 +01001346 /*
1347 * We need to synthesize events first, because some
1348 * features works on top of them (on report side).
1349 */
Jiri Olsa318ec182018-08-30 08:32:15 +02001350 err = perf_event__synthesize_attrs(tool, rec->evlist,
Wang Nanc45c86e2016-02-26 09:32:07 +00001351 process_synthesized_event);
1352 if (err < 0) {
1353 pr_err("Couldn't synthesize attrs.\n");
1354 goto out;
1355 }
1356
Jiri Olsaa2015512018-03-14 10:22:04 +01001357 err = perf_event__synthesize_features(tool, session, rec->evlist,
1358 process_synthesized_event);
1359 if (err < 0) {
1360 pr_err("Couldn't synthesize features.\n");
1361 return err;
1362 }
1363
Jiri Olsace9036a2019-07-21 13:24:23 +02001364 if (have_tracepoints(&rec->evlist->core.entries)) {
Wang Nanc45c86e2016-02-26 09:32:07 +00001365 /*
1366 * FIXME err <= 0 here actually means that
1367 * there were no tracepoints so its not really
1368 * an error, just that we don't need to
1369 * synthesize anything. We really have to
1370 * return this more properly and also
1371 * propagate errors that now are calling die()
1372 */
1373 err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
1374 process_synthesized_event);
1375 if (err <= 0) {
1376 pr_err("Couldn't record tracing data.\n");
1377 goto out;
1378 }
1379 rec->bytes_written += err;
1380 }
1381 }
1382
Wang Nanc45628b2016-05-24 02:28:59 +00001383 err = perf_event__synth_time_conv(record__pick_pc(rec), tool,
Adrian Hunter46bc29b2016-03-08 10:38:44 +02001384 process_synthesized_event, machine);
1385 if (err)
1386 goto out;
1387
Adrian Hunterc0a6de02019-11-15 14:42:16 +02001388 /* Synthesize id_index before auxtrace_info */
1389 if (rec->opts.auxtrace_sample_mode) {
1390 err = perf_event__synthesize_id_index(tool,
1391 process_synthesized_event,
1392 session->evlist, machine);
1393 if (err)
1394 goto out;
1395 }
1396
Wang Nanc45c86e2016-02-26 09:32:07 +00001397 if (rec->opts.full_auxtrace) {
1398 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
1399 session, process_synthesized_event);
1400 if (err)
1401 goto out;
1402 }
1403
Arnaldo Carvalho de Melo6c443952017-11-14 11:03:19 -03001404 if (!perf_evlist__exclude_kernel(rec->evlist)) {
1405 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
1406 machine);
1407 WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
1408 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
1409 "Check /proc/kallsyms permission or run as root.\n");
Wang Nanc45c86e2016-02-26 09:32:07 +00001410
Arnaldo Carvalho de Melo6c443952017-11-14 11:03:19 -03001411 err = perf_event__synthesize_modules(tool, process_synthesized_event,
1412 machine);
1413 WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
1414 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
1415 "Check /proc/modules permission or run as root.\n");
1416 }
Wang Nanc45c86e2016-02-26 09:32:07 +00001417
1418 if (perf_guest) {
1419 machines__process_guests(&session->machines,
1420 perf_event__synthesize_guest_os, tool);
1421 }
1422
Andi Kleenbfd8f722017-11-17 13:42:58 -08001423 err = perf_event__synthesize_extra_attr(&rec->tool,
1424 rec->evlist,
1425 process_synthesized_event,
1426 data->is_pipe);
1427 if (err)
1428 goto out;
1429
Jiri Olsa03617c22019-07-21 13:24:42 +02001430 err = perf_event__synthesize_thread_map2(&rec->tool, rec->evlist->core.threads,
Andi Kleen373565d2017-11-17 13:42:59 -08001431 process_synthesized_event,
1432 NULL);
1433 if (err < 0) {
1434 pr_err("Couldn't synthesize thread map.\n");
1435 return err;
1436 }
1437
Jiri Olsaf72f9012019-07-21 13:24:41 +02001438 err = perf_event__synthesize_cpu_map(&rec->tool, rec->evlist->core.cpus,
Andi Kleen373565d2017-11-17 13:42:59 -08001439 process_synthesized_event, NULL);
1440 if (err < 0) {
1441 pr_err("Couldn't synthesize cpu map.\n");
1442 return err;
1443 }
1444
Song Liue5416952019-03-11 22:30:41 -07001445 err = perf_event__synthesize_bpf_events(session, process_synthesized_event,
Song Liu7b612e22019-01-17 08:15:19 -08001446 machine, opts);
1447 if (err < 0)
1448 pr_warning("Couldn't synthesize bpf events.\n");
1449
Namhyung Kimab640692020-03-25 21:45:33 +09001450 err = perf_event__synthesize_cgroups(tool, process_synthesized_event,
1451 machine);
1452 if (err < 0)
1453 pr_warning("Couldn't synthesize cgroup events.\n");
1454
Stephane Eraniand99c22e2020-04-22 08:50:38 -07001455 if (rec->opts.nr_threads_synthesize > 1) {
1456 perf_set_multithreaded();
1457 f = process_locked_synthesized_event;
1458 }
1459
Jiri Olsa03617c22019-07-21 13:24:42 +02001460 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->core.threads,
Stephane Eraniand99c22e2020-04-22 08:50:38 -07001461 f, opts->sample_address,
1462 rec->opts.nr_threads_synthesize);
1463
1464 if (rec->opts.nr_threads_synthesize > 1)
1465 perf_set_singlethreaded();
1466
Wang Nanc45c86e2016-02-26 09:32:07 +00001467out:
1468 return err;
1469}
1470
Arnaldo Carvalho de Melo899e5ff2020-04-27 17:56:37 -03001471static int record__process_signal_event(union perf_event *event __maybe_unused, void *data)
1472{
1473 struct record *rec = data;
1474 pthread_kill(rec->thread_id, SIGUSR2);
1475 return 0;
1476}
1477
Arnaldo Carvalho de Melo23cbb412020-04-28 14:58:29 -03001478static int record__setup_sb_evlist(struct record *rec)
1479{
1480 struct record_opts *opts = &rec->opts;
1481
1482 if (rec->sb_evlist != NULL) {
1483 /*
1484 * We get here if --switch-output-event populated the
1485 * sb_evlist, so associate a callback that will send a SIGUSR2
1486 * to the main thread.
1487 */
1488 evlist__set_cb(rec->sb_evlist, record__process_signal_event, rec);
1489 rec->thread_id = pthread_self();
1490 }
1491
1492 if (!opts->no_bpf_event) {
1493 if (rec->sb_evlist == NULL) {
1494 rec->sb_evlist = evlist__new();
1495
1496 if (rec->sb_evlist == NULL) {
1497 pr_err("Couldn't create side band evlist.\n.");
1498 return -1;
1499 }
1500 }
1501
1502 if (evlist__add_bpf_sb_event(rec->sb_evlist, &rec->session->header.env)) {
1503 pr_err("Couldn't ask for PERF_RECORD_BPF_EVENT side band events.\n.");
1504 return -1;
1505 }
1506 }
1507
1508 if (perf_evlist__start_sb_thread(rec->sb_evlist, &rec->opts.target)) {
1509 pr_debug("Couldn't start the BPF side band thread:\nBPF programs starting from now on won't be annotatable\n");
1510 opts->no_bpf_event = true;
1511 }
1512
1513 return 0;
1514}
1515
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001516static int __cmd_record(struct record *rec, int argc, const char **argv)
Peter Zijlstra16c8a102009-05-05 17:50:27 +02001517{
David Ahern57706ab2013-11-06 11:41:34 -07001518 int err;
Namhyung Kim45604712014-05-12 09:47:24 +09001519 int status = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001520 unsigned long waking = 0;
Zhang, Yanmin46be6042010-03-18 11:36:04 -03001521 const bool forks = argc > 0;
Arnaldo Carvalho de Melo45694aa2011-11-28 08:30:20 -02001522 struct perf_tool *tool = &rec->tool;
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03001523 struct record_opts *opts = &rec->opts;
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001524 struct perf_data *data = &rec->data;
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001525 struct perf_session *session;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001526 bool disabled = false, draining = false;
Namhyung Kim42aa2762015-01-29 17:06:48 +09001527 int fd;
Alexey Budankovd3c8c082019-03-18 20:41:02 +03001528 float ratio = 0;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001529
Namhyung Kim45604712014-05-12 09:47:24 +09001530 atexit(record__sig_exit);
Peter Zijlstraf5970552009-06-18 23:22:55 +02001531 signal(SIGCHLD, sig_handler);
1532 signal(SIGINT, sig_handler);
David Ahern804f7ac2013-05-06 12:24:23 -06001533 signal(SIGTERM, sig_handler);
Wang Nana0748652016-11-26 07:03:28 +00001534 signal(SIGSEGV, sigsegv_handler);
Wang Nanc0bdc1c2016-04-13 08:21:06 +00001535
Hari Bathinif3b36142017-03-08 02:11:43 +05301536 if (rec->opts.record_namespaces)
1537 tool->namespace_events = true;
1538
Namhyung Kim8fb4b672020-03-25 21:45:34 +09001539 if (rec->opts.record_cgroup) {
1540#ifdef HAVE_FILE_HANDLE
1541 tool->cgroup_events = true;
1542#else
1543 pr_err("cgroup tracking is not supported\n");
1544 return -1;
1545#endif
1546 }
1547
Jiri Olsadc0c6122017-01-09 10:51:58 +01001548 if (rec->opts.auxtrace_snapshot_mode || rec->switch_output.enabled) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001549 signal(SIGUSR2, snapshot_sig_handler);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001550 if (rec->opts.auxtrace_snapshot_mode)
1551 trigger_on(&auxtrace_snapshot_trigger);
Jiri Olsadc0c6122017-01-09 10:51:58 +01001552 if (rec->switch_output.enabled)
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001553 trigger_on(&switch_output_trigger);
Wang Nanc0bdc1c2016-04-13 08:21:06 +00001554 } else {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001555 signal(SIGUSR2, SIG_IGN);
Wang Nanc0bdc1c2016-04-13 08:21:06 +00001556 }
Peter Zijlstraf5970552009-06-18 23:22:55 +02001557
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001558 session = perf_session__new(data, false, tool);
Mamatha Inamdar6ef81c52019-08-22 12:50:49 +05301559 if (IS_ERR(session)) {
Adrien BAKffa91882014-04-18 11:00:43 +09001560 pr_err("Perf session creation failed.\n");
Mamatha Inamdar6ef81c52019-08-22 12:50:49 +05301561 return PTR_ERR(session);
Arnaldo Carvalho de Meloa9a70bb2009-11-17 01:18:11 -02001562 }
1563
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001564 fd = perf_data__fd(data);
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001565 rec->session = session;
1566
Alexey Budankov5d7f4112019-03-18 20:43:35 +03001567 if (zstd_init(&session->zstd_data, rec->opts.comp_level) < 0) {
1568 pr_err("Compression initialization failed.\n");
1569 return -1;
1570 }
Anand K Mistryda231332020-05-13 12:20:23 +10001571#ifdef HAVE_EVENTFD_SUPPORT
1572 done_fd = eventfd(0, EFD_NONBLOCK);
1573 if (done_fd < 0) {
1574 pr_err("Failed to create wakeup eventfd, error: %m\n");
1575 status = -1;
1576 goto out_delete_session;
1577 }
1578 err = evlist__add_pollfd(rec->evlist, done_fd);
1579 if (err < 0) {
1580 pr_err("Failed to add wakeup eventfd to poll list\n");
1581 status = err;
1582 goto out_delete_session;
1583 }
1584#endif // HAVE_EVENTFD_SUPPORT
Alexey Budankov5d7f4112019-03-18 20:43:35 +03001585
1586 session->header.env.comp_type = PERF_COMP_ZSTD;
1587 session->header.env.comp_level = rec->opts.comp_level;
1588
Adrian Huntereeb399b2019-10-04 11:31:21 +03001589 if (rec->opts.kcore &&
1590 !record__kcore_readable(&session->machines.host)) {
1591 pr_err("ERROR: kcore is not readable.\n");
1592 return -1;
1593 }
1594
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001595 record__init_features(rec);
Stephane Eranian330aa672012-03-08 23:47:46 +01001596
Alexey Budankovcf790512018-10-09 17:36:24 +03001597 if (rec->opts.use_clockid && rec->opts.clockid_res_ns)
1598 session->header.env.clockid_res_ns = rec->opts.clockid_res_ns;
1599
Arnaldo Carvalho de Melod4db3f12009-12-27 21:36:57 -02001600 if (forks) {
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001601 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001602 argv, data->is_pipe,
Arnaldo Carvalho de Melo735f7e02014-01-03 14:56:49 -03001603 workload_exec_failed_signal);
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -02001604 if (err < 0) {
1605 pr_err("Couldn't run the workload!\n");
Namhyung Kim45604712014-05-12 09:47:24 +09001606 status = err;
Arnaldo Carvalho de Melo35b9d882011-11-09 08:47:15 -02001607 goto out_delete_session;
Jens Axboe0a5ac842009-08-12 11:18:01 +02001608 }
Peter Zijlstra856e9662009-12-16 17:55:55 +01001609 }
1610
Jiri Olsaad46e48c2018-03-02 17:13:54 +01001611 /*
1612 * If we have just single event and are sending data
1613 * through pipe, we need to force the ids allocation,
1614 * because we synthesize event name through the pipe
1615 * and need the id for that.
1616 */
Jiri Olsa6484d2f2019-07-21 13:24:28 +02001617 if (data->is_pipe && rec->evlist->core.nr_entries == 1)
Jiri Olsaad46e48c2018-03-02 17:13:54 +01001618 rec->opts.sample_id = true;
1619
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03001620 if (record__open(rec) != 0) {
David Ahern8d3eca22012-08-26 12:24:47 -06001621 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001622 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -06001623 }
Jiri Olsaf6fa4372019-08-06 15:14:05 +02001624 session->header.env.comp_mmap_len = session->evlist->core.mmap_len;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001625
Adrian Huntereeb399b2019-10-04 11:31:21 +03001626 if (rec->opts.kcore) {
1627 err = record__kcore_copy(&session->machines.host, data);
1628 if (err) {
1629 pr_err("ERROR: Failed to copy kcore\n");
1630 goto out_child;
1631 }
1632 }
1633
Wang Nan8690a2a2016-02-22 09:10:32 +00001634 err = bpf__apply_obj_config();
1635 if (err) {
1636 char errbuf[BUFSIZ];
1637
1638 bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
1639 pr_err("ERROR: Apply config to BPF failed: %s\n",
1640 errbuf);
1641 goto out_child;
1642 }
1643
Adrian Huntercca84822015-08-19 17:29:21 +03001644 /*
1645 * Normally perf_session__new would do this, but it doesn't have the
1646 * evlist.
1647 */
1648 if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
1649 pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
1650 rec->tool.ordered_events = false;
1651 }
1652
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001653 if (!rec->evlist->nr_groups)
Namhyung Kima8bb5592013-01-22 18:09:31 +09001654 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
1655
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001656 if (data->is_pipe) {
Namhyung Kim42aa2762015-01-29 17:06:48 +09001657 err = perf_header__write_pipe(fd);
Tom Zanussi529870e2010-04-01 23:59:16 -05001658 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +09001659 goto out_child;
Jiri Olsa563aecb2013-06-05 13:35:06 +02001660 } else {
Namhyung Kim42aa2762015-01-29 17:06:48 +09001661 err = perf_session__write_header(session, rec->evlist, fd, false);
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -02001662 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +09001663 goto out_child;
Arnaldo Carvalho de Melod5eed902009-11-19 14:55:56 -02001664 }
Peter Zijlstra7c6a1c62009-06-25 17:05:54 +02001665
Arnaldo Carvalho de Melob38d85e2020-04-24 12:24:51 -03001666 err = -1;
David Ahernd3665492012-02-06 15:27:52 -07001667 if (!rec->no_buildid
Robert Richtere20960c2011-12-07 10:02:55 +01001668 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
David Ahernd3665492012-02-06 15:27:52 -07001669 pr_err("Couldn't generate buildids. "
Robert Richtere20960c2011-12-07 10:02:55 +01001670 "Use --no-buildid to profile anyway.\n");
Namhyung Kim45604712014-05-12 09:47:24 +09001671 goto out_child;
Robert Richtere20960c2011-12-07 10:02:55 +01001672 }
1673
Arnaldo Carvalho de Melo23cbb412020-04-28 14:58:29 -03001674 err = record__setup_sb_evlist(rec);
1675 if (err)
1676 goto out_child;
Song Liu657ee552019-03-11 22:30:50 -07001677
Wang Nan4ea648a2016-07-14 08:34:47 +00001678 err = record__synthesize(rec, false);
Wang Nanc45c86e2016-02-26 09:32:07 +00001679 if (err < 0)
Namhyung Kim45604712014-05-12 09:47:24 +09001680 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -06001681
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001682 if (rec->realtime_prio) {
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001683 struct sched_param param;
1684
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001685 param.sched_priority = rec->realtime_prio;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001686 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
Arnaldo Carvalho de Melo6beba7a2009-10-21 17:34:06 -02001687 pr_err("Could not set realtime priority.\n");
David Ahern8d3eca22012-08-26 12:24:47 -06001688 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001689 goto out_child;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001690 }
1691 }
1692
Jiri Olsa774cb492012-11-12 18:34:01 +01001693 /*
1694 * When perf is starting the traced process, all the events
1695 * (apart from group members) have enable_on_exec=1 set,
1696 * so don't spoil it by prematurely enabling them.
1697 */
Andi Kleen6619a532014-01-11 13:38:27 -08001698 if (!target__none(&opts->target) && !opts->initial_delay)
Jiri Olsa1c87f162019-07-21 13:24:08 +02001699 evlist__enable(rec->evlist);
David Ahern764e16a32011-08-25 10:17:55 -06001700
Peter Zijlstra856e9662009-12-16 17:55:55 +01001701 /*
1702 * Let the child rip
1703 */
Namhyung Kime803cf92015-09-22 09:24:55 +09001704 if (forks) {
Jiri Olsa20a8a3c2018-03-07 16:50:04 +01001705 struct machine *machine = &session->machines.host;
Namhyung Kime5bed562015-09-30 10:45:24 +09001706 union perf_event *event;
Hari Bathinie907caf2017-03-08 02:11:51 +05301707 pid_t tgid;
Namhyung Kime5bed562015-09-30 10:45:24 +09001708
1709 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
1710 if (event == NULL) {
1711 err = -ENOMEM;
1712 goto out_child;
1713 }
1714
Namhyung Kime803cf92015-09-22 09:24:55 +09001715 /*
1716 * Some H/W events are generated before COMM event
1717 * which is emitted during exec(), so perf script
1718 * cannot see a correct process name for those events.
1719 * Synthesize COMM event to prevent it.
1720 */
Hari Bathinie907caf2017-03-08 02:11:51 +05301721 tgid = perf_event__synthesize_comm(tool, event,
1722 rec->evlist->workload.pid,
1723 process_synthesized_event,
1724 machine);
1725 free(event);
1726
1727 if (tgid == -1)
1728 goto out_child;
1729
1730 event = malloc(sizeof(event->namespaces) +
1731 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
1732 machine->id_hdr_size);
1733 if (event == NULL) {
1734 err = -ENOMEM;
1735 goto out_child;
1736 }
1737
1738 /*
1739 * Synthesize NAMESPACES event for the command specified.
1740 */
1741 perf_event__synthesize_namespaces(tool, event,
1742 rec->evlist->workload.pid,
1743 tgid, process_synthesized_event,
1744 machine);
Namhyung Kime5bed562015-09-30 10:45:24 +09001745 free(event);
Namhyung Kime803cf92015-09-22 09:24:55 +09001746
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03001747 perf_evlist__start_workload(rec->evlist);
Namhyung Kime803cf92015-09-22 09:24:55 +09001748 }
Peter Zijlstra856e9662009-12-16 17:55:55 +01001749
Andi Kleen6619a532014-01-11 13:38:27 -08001750 if (opts->initial_delay) {
Arnaldo Carvalho de Melo0693e682016-08-08 15:05:46 -03001751 usleep(opts->initial_delay * USEC_PER_MSEC);
Jiri Olsa1c87f162019-07-21 13:24:08 +02001752 evlist__enable(rec->evlist);
Andi Kleen6619a532014-01-11 13:38:27 -08001753 }
1754
Wang Nan5f9cf592016-04-20 18:59:49 +00001755 trigger_ready(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001756 trigger_ready(&switch_output_trigger);
Wang Nana0748652016-11-26 07:03:28 +00001757 perf_hooks__invoke_record_start();
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001758 for (;;) {
Yang Shi9f065192015-09-29 14:49:43 -07001759 unsigned long long hits = rec->samples;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001760
Wang Nan057374642016-07-14 08:34:43 +00001761 /*
1762 * rec->evlist->bkw_mmap_state is possible to be
1763 * BKW_MMAP_EMPTY here: when done == true and
1764 * hits != rec->samples in previous round.
1765 *
1766 * perf_evlist__toggle_bkw_mmap ensure we never
1767 * convert BKW_MMAP_EMPTY to BKW_MMAP_DATA_PENDING.
1768 */
1769 if (trigger_is_hit(&switch_output_trigger) || done || draining)
1770 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_DATA_PENDING);
1771
Alexey Budankov470530b2019-03-18 20:40:26 +03001772 if (record__mmap_read_all(rec, false) < 0) {
Wang Nan5f9cf592016-04-20 18:59:49 +00001773 trigger_error(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001774 trigger_error(&switch_output_trigger);
David Ahern8d3eca22012-08-26 12:24:47 -06001775 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001776 goto out_child;
David Ahern8d3eca22012-08-26 12:24:47 -06001777 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001778
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001779 if (auxtrace_record__snapshot_started) {
1780 auxtrace_record__snapshot_started = 0;
Wang Nan5f9cf592016-04-20 18:59:49 +00001781 if (!trigger_is_error(&auxtrace_snapshot_trigger))
Alexander Shishkince7b0e42019-08-06 17:41:01 +03001782 record__read_auxtrace_snapshot(rec, false);
Wang Nan5f9cf592016-04-20 18:59:49 +00001783 if (trigger_is_error(&auxtrace_snapshot_trigger)) {
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03001784 pr_err("AUX area tracing snapshot failed\n");
1785 err = -1;
1786 goto out_child;
1787 }
1788 }
1789
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001790 if (trigger_is_hit(&switch_output_trigger)) {
Wang Nan057374642016-07-14 08:34:43 +00001791 /*
1792 * If switch_output_trigger is hit, the data in
1793 * overwritable ring buffer should have been collected,
1794 * so bkw_mmap_state should be set to BKW_MMAP_EMPTY.
1795 *
1796 * If SIGUSR2 raise after or during record__mmap_read_all(),
1797 * record__mmap_read_all() didn't collect data from
1798 * overwritable ring buffer. Read again.
1799 */
1800 if (rec->evlist->bkw_mmap_state == BKW_MMAP_RUNNING)
1801 continue;
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001802 trigger_ready(&switch_output_trigger);
1803
Wang Nan057374642016-07-14 08:34:43 +00001804 /*
1805 * Reenable events in overwrite ring buffer after
1806 * record__mmap_read_all(): we should have collected
1807 * data from it.
1808 */
1809 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_RUNNING);
1810
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001811 if (!quiet)
1812 fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
1813 waking);
1814 waking = 0;
1815 fd = record__switch_output(rec, false);
1816 if (fd < 0) {
1817 pr_err("Failed to switch to new file\n");
1818 trigger_error(&switch_output_trigger);
1819 err = fd;
1820 goto out_child;
1821 }
Jiri Olsabfacbe32017-01-09 10:52:00 +01001822
1823 /* re-arm the alarm */
1824 if (rec->switch_output.time)
1825 alarm(rec->switch_output.time);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001826 }
1827
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02001828 if (hits == rec->samples) {
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001829 if (done || draining)
Peter Zijlstra649c48a2009-06-24 21:12:48 +02001830 break;
Jiri Olsa80ab2982019-08-31 22:48:33 +02001831 err = evlist__poll(rec->evlist, -1);
Jiri Olsaa5151142014-06-02 13:44:23 -04001832 /*
1833 * Propagate error, only if there's any. Ignore positive
1834 * number of returned events and interrupt error.
1835 */
1836 if (err > 0 || (err < 0 && errno == EINTR))
Namhyung Kim45604712014-05-12 09:47:24 +09001837 err = 0;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001838 waking++;
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001839
Jiri Olsaf4009e72019-08-16 16:00:45 +02001840 if (evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
Arnaldo Carvalho de Melo6dcf45ef2014-08-13 11:33:59 -03001841 draining = true;
Peter Zijlstra8b412662009-09-17 19:59:05 +02001842 }
1843
Jiri Olsa774cb492012-11-12 18:34:01 +01001844 /*
1845 * When perf is starting the traced process, at the end events
1846 * die with the process and we wait for that. Thus no need to
1847 * disable events in this case.
1848 */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03001849 if (done && !disabled && !target__none(&opts->target)) {
Wang Nan5f9cf592016-04-20 18:59:49 +00001850 trigger_off(&auxtrace_snapshot_trigger);
Jiri Olsae74676d2019-07-21 13:24:09 +02001851 evlist__disable(rec->evlist);
Jiri Olsa27119262012-11-12 18:34:02 +01001852 disabled = true;
1853 }
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001854 }
Alexander Shishkince7b0e42019-08-06 17:41:01 +03001855
Wang Nan5f9cf592016-04-20 18:59:49 +00001856 trigger_off(&auxtrace_snapshot_trigger);
Wang Nan3c1cb7e2016-04-20 18:59:50 +00001857 trigger_off(&switch_output_trigger);
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001858
Alexander Shishkince7b0e42019-08-06 17:41:01 +03001859 if (opts->auxtrace_snapshot_on_exit)
1860 record__auxtrace_snapshot_exit(rec);
1861
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001862 if (forks && workload_exec_errno) {
Masami Hiramatsu35550da2014-08-14 02:22:43 +00001863 char msg[STRERR_BUFSIZE];
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -03001864 const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001865 pr_err("Workload failed: %s\n", emsg);
1866 err = -1;
Namhyung Kim45604712014-05-12 09:47:24 +09001867 goto out_child;
Arnaldo Carvalho de Melof33cbe72014-01-02 15:11:25 -03001868 }
1869
Namhyung Kime3d59112015-01-29 17:06:44 +09001870 if (!quiet)
Namhyung Kim45604712014-05-12 09:47:24 +09001871 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02001872
Wang Nan4ea648a2016-07-14 08:34:47 +00001873 if (target__none(&rec->opts.target))
1874 record__synthesize_workload(rec, true);
1875
Namhyung Kim45604712014-05-12 09:47:24 +09001876out_child:
Alexey Budankov470530b2019-03-18 20:40:26 +03001877 record__mmap_read_all(rec, true);
Alexey Budankovd3d1af62018-11-06 12:04:58 +03001878 record__aio_mmap_read_sync(rec);
1879
Alexey Budankovd3c8c082019-03-18 20:41:02 +03001880 if (rec->session->bytes_transferred && rec->session->bytes_compressed) {
1881 ratio = (float)rec->session->bytes_transferred/(float)rec->session->bytes_compressed;
1882 session->header.env.comp_ratio = ratio + 0.5;
1883 }
1884
Namhyung Kim45604712014-05-12 09:47:24 +09001885 if (forks) {
1886 int exit_status;
Ingo Molnaraddc2782009-06-02 23:43:11 +02001887
Namhyung Kim45604712014-05-12 09:47:24 +09001888 if (!child_finished)
1889 kill(rec->evlist->workload.pid, SIGTERM);
1890
1891 wait(&exit_status);
1892
1893 if (err < 0)
1894 status = err;
1895 else if (WIFEXITED(exit_status))
1896 status = WEXITSTATUS(exit_status);
1897 else if (WIFSIGNALED(exit_status))
1898 signr = WTERMSIG(exit_status);
1899 } else
1900 status = err;
1901
Wang Nan4ea648a2016-07-14 08:34:47 +00001902 record__synthesize(rec, true);
Namhyung Kime3d59112015-01-29 17:06:44 +09001903 /* this will be recalculated during process_buildids() */
1904 rec->samples = 0;
1905
Wang Nanecfd7a92016-04-13 08:21:07 +00001906 if (!err) {
1907 if (!rec->timestamp_filename) {
1908 record__finish_output(rec);
1909 } else {
1910 fd = record__switch_output(rec, true);
1911 if (fd < 0) {
1912 status = fd;
1913 goto out_delete_session;
1914 }
1915 }
1916 }
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001917
Wang Nana0748652016-11-26 07:03:28 +00001918 perf_hooks__invoke_record_end();
1919
Namhyung Kime3d59112015-01-29 17:06:44 +09001920 if (!err && !quiet) {
1921 char samples[128];
Wang Nanecfd7a92016-04-13 08:21:07 +00001922 const char *postfix = rec->timestamp_filename ?
1923 ".<timestamp>" : "";
Namhyung Kime3d59112015-01-29 17:06:44 +09001924
Adrian Hunteref149c22015-04-09 18:53:45 +03001925 if (rec->samples && !rec->opts.full_auxtrace)
Namhyung Kime3d59112015-01-29 17:06:44 +09001926 scnprintf(samples, sizeof(samples),
1927 " (%" PRIu64 " samples)", rec->samples);
1928 else
1929 samples[0] = '\0';
1930
Alexey Budankovd3c8c082019-03-18 20:41:02 +03001931 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s",
Jiri Olsa8ceb41d2017-01-23 22:07:59 +01001932 perf_data__size(data) / 1024.0 / 1024.0,
Jiri Olsa2d4f2792019-02-21 10:41:30 +01001933 data->path, postfix, samples);
Alexey Budankovd3c8c082019-03-18 20:41:02 +03001934 if (ratio) {
1935 fprintf(stderr, ", compressed (original %.3f MB, ratio is %.3f)",
1936 rec->session->bytes_transferred / 1024.0 / 1024.0,
1937 ratio);
1938 }
1939 fprintf(stderr, " ]\n");
Namhyung Kime3d59112015-01-29 17:06:44 +09001940 }
1941
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001942out_delete_session:
Anand K Mistryda231332020-05-13 12:20:23 +10001943#ifdef HAVE_EVENTFD_SUPPORT
1944 if (done_fd >= 0)
1945 close(done_fd);
1946#endif
Alexey Budankov5d7f4112019-03-18 20:43:35 +03001947 zstd_fini(&session->zstd_data);
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03001948 perf_session__delete(session);
Song Liu657ee552019-03-11 22:30:50 -07001949
1950 if (!opts->no_bpf_event)
Arnaldo Carvalho de Melobc477d792020-04-24 10:24:04 -03001951 perf_evlist__stop_sb_thread(rec->sb_evlist);
Namhyung Kim45604712014-05-12 09:47:24 +09001952 return status;
Peter Zijlstrade9ac072009-04-08 15:01:31 +02001953}
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02001954
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001955static void callchain_debug(struct callchain_param *callchain)
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001956{
Kan Liangaad2b212015-01-05 13:23:04 -05001957 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
Jiri Olsaa601fdf2014-02-03 12:44:43 +01001958
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001959 pr_debug("callchain: type %s\n", str[callchain->record_mode]);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001960
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001961 if (callchain->record_mode == CALLCHAIN_DWARF)
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001962 pr_debug("callchain: stack dump size %d\n",
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001963 callchain->dump_size);
1964}
1965
1966int record_opts__parse_callchain(struct record_opts *record,
1967 struct callchain_param *callchain,
1968 const char *arg, bool unset)
1969{
1970 int ret;
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001971 callchain->enabled = !unset;
1972
1973 /* --no-call-graph */
1974 if (unset) {
1975 callchain->record_mode = CALLCHAIN_NONE;
1976 pr_debug("callchain: disabled\n");
1977 return 0;
1978 }
1979
1980 ret = parse_callchain_record_opt(arg, callchain);
1981 if (!ret) {
1982 /* Enable data address sampling for DWARF unwind. */
1983 if (callchain->record_mode == CALLCHAIN_DWARF)
1984 record->sample_address = true;
1985 callchain_debug(callchain);
1986 }
1987
1988 return ret;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001989}
1990
Kan Liangc421e802015-07-29 05:42:12 -04001991int record_parse_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001992 const char *arg,
1993 int unset)
1994{
Arnaldo Carvalho de Melo0883e822016-04-15 16:37:17 -03001995 return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
Jiri Olsa26d33022012-08-07 15:20:47 +02001996}
1997
Kan Liangc421e802015-07-29 05:42:12 -04001998int record_callchain_opt(const struct option *opt,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02001999 const char *arg __maybe_unused,
2000 int unset __maybe_unused)
2001{
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03002002 struct callchain_param *callchain = opt->value;
Kan Liangc421e802015-07-29 05:42:12 -04002003
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03002004 callchain->enabled = true;
Jiri Olsa09b0fd42013-10-26 16:25:33 +02002005
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03002006 if (callchain->record_mode == CALLCHAIN_NONE)
2007 callchain->record_mode = CALLCHAIN_FP;
Jiri Olsaeb853e82014-02-03 12:44:42 +01002008
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03002009 callchain_debug(callchain);
Jiri Olsa09b0fd42013-10-26 16:25:33 +02002010 return 0;
2011}
2012
Jiri Olsaeb853e82014-02-03 12:44:42 +01002013static int perf_record_config(const char *var, const char *value, void *cb)
2014{
Namhyung Kim7a29c082015-12-15 10:49:56 +09002015 struct record *rec = cb;
2016
2017 if (!strcmp(var, "record.build-id")) {
2018 if (!strcmp(value, "cache"))
2019 rec->no_buildid_cache = false;
2020 else if (!strcmp(value, "no-cache"))
2021 rec->no_buildid_cache = true;
2022 else if (!strcmp(value, "skip"))
2023 rec->no_buildid = true;
2024 else
2025 return -1;
2026 return 0;
2027 }
Yisheng Xiecff17202018-03-12 19:25:57 +08002028 if (!strcmp(var, "record.call-graph")) {
2029 var = "call-graph.record-mode";
2030 return perf_default_config(var, value, cb);
2031 }
Alexey Budankov93f20c02018-11-06 12:07:19 +03002032#ifdef HAVE_AIO_SUPPORT
2033 if (!strcmp(var, "record.aio")) {
2034 rec->opts.nr_cblocks = strtol(value, NULL, 0);
2035 if (!rec->opts.nr_cblocks)
2036 rec->opts.nr_cblocks = nr_cblocks_default;
2037 }
2038#endif
Jiri Olsaeb853e82014-02-03 12:44:42 +01002039
Yisheng Xiecff17202018-03-12 19:25:57 +08002040 return 0;
Jiri Olsaeb853e82014-02-03 12:44:42 +01002041}
2042
Peter Zijlstra814c8c32015-03-31 00:19:31 +02002043struct clockid_map {
2044 const char *name;
2045 int clockid;
2046};
2047
2048#define CLOCKID_MAP(n, c) \
2049 { .name = n, .clockid = (c), }
2050
2051#define CLOCKID_END { .name = NULL, }
2052
2053
2054/*
2055 * Add the missing ones, we need to build on many distros...
2056 */
2057#ifndef CLOCK_MONOTONIC_RAW
2058#define CLOCK_MONOTONIC_RAW 4
2059#endif
2060#ifndef CLOCK_BOOTTIME
2061#define CLOCK_BOOTTIME 7
2062#endif
2063#ifndef CLOCK_TAI
2064#define CLOCK_TAI 11
2065#endif
2066
2067static const struct clockid_map clockids[] = {
2068 /* available for all events, NMI safe */
2069 CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
2070 CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
2071
2072 /* available for some events */
2073 CLOCKID_MAP("realtime", CLOCK_REALTIME),
2074 CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
2075 CLOCKID_MAP("tai", CLOCK_TAI),
2076
2077 /* available for the lazy */
2078 CLOCKID_MAP("mono", CLOCK_MONOTONIC),
2079 CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
2080 CLOCKID_MAP("real", CLOCK_REALTIME),
2081 CLOCKID_MAP("boot", CLOCK_BOOTTIME),
2082
2083 CLOCKID_END,
2084};
2085
Alexey Budankovcf790512018-10-09 17:36:24 +03002086static int get_clockid_res(clockid_t clk_id, u64 *res_ns)
2087{
2088 struct timespec res;
2089
2090 *res_ns = 0;
2091 if (!clock_getres(clk_id, &res))
2092 *res_ns = res.tv_nsec + res.tv_sec * NSEC_PER_SEC;
2093 else
2094 pr_warning("WARNING: Failed to determine specified clock resolution.\n");
2095
2096 return 0;
2097}
2098
Peter Zijlstra814c8c32015-03-31 00:19:31 +02002099static int parse_clockid(const struct option *opt, const char *str, int unset)
2100{
2101 struct record_opts *opts = (struct record_opts *)opt->value;
2102 const struct clockid_map *cm;
2103 const char *ostr = str;
2104
2105 if (unset) {
2106 opts->use_clockid = 0;
2107 return 0;
2108 }
2109
2110 /* no arg passed */
2111 if (!str)
2112 return 0;
2113
2114 /* no setting it twice */
2115 if (opts->use_clockid)
2116 return -1;
2117
2118 opts->use_clockid = true;
2119
2120 /* if its a number, we're done */
2121 if (sscanf(str, "%d", &opts->clockid) == 1)
Alexey Budankovcf790512018-10-09 17:36:24 +03002122 return get_clockid_res(opts->clockid, &opts->clockid_res_ns);
Peter Zijlstra814c8c32015-03-31 00:19:31 +02002123
2124 /* allow a "CLOCK_" prefix to the name */
2125 if (!strncasecmp(str, "CLOCK_", 6))
2126 str += 6;
2127
2128 for (cm = clockids; cm->name; cm++) {
2129 if (!strcasecmp(str, cm->name)) {
2130 opts->clockid = cm->clockid;
Alexey Budankovcf790512018-10-09 17:36:24 +03002131 return get_clockid_res(opts->clockid,
2132 &opts->clockid_res_ns);
Peter Zijlstra814c8c32015-03-31 00:19:31 +02002133 }
2134 }
2135
2136 opts->use_clockid = false;
2137 ui__warning("unknown clockid %s, check man page\n", ostr);
2138 return -1;
2139}
2140
Alexey Budankovf4fe11b2019-01-22 20:52:03 +03002141static int record__parse_affinity(const struct option *opt, const char *str, int unset)
2142{
2143 struct record_opts *opts = (struct record_opts *)opt->value;
2144
2145 if (unset || !str)
2146 return 0;
2147
2148 if (!strcasecmp(str, "node"))
2149 opts->affinity = PERF_AFFINITY_NODE;
2150 else if (!strcasecmp(str, "cpu"))
2151 opts->affinity = PERF_AFFINITY_CPU;
2152
2153 return 0;
2154}
2155
Jiwei Sun6d575812019-10-22 16:09:01 +08002156static int parse_output_max_size(const struct option *opt,
2157 const char *str, int unset)
2158{
2159 unsigned long *s = (unsigned long *)opt->value;
2160 static struct parse_tag tags_size[] = {
2161 { .tag = 'B', .mult = 1 },
2162 { .tag = 'K', .mult = 1 << 10 },
2163 { .tag = 'M', .mult = 1 << 20 },
2164 { .tag = 'G', .mult = 1 << 30 },
2165 { .tag = 0 },
2166 };
2167 unsigned long val;
2168
2169 if (unset) {
2170 *s = 0;
2171 return 0;
2172 }
2173
2174 val = parse_tag_value(str, tags_size);
2175 if (val != (unsigned long) -1) {
2176 *s = val;
2177 return 0;
2178 }
2179
2180 return -1;
2181}
2182
Adrian Huntere9db1312015-04-09 18:53:46 +03002183static int record__parse_mmap_pages(const struct option *opt,
2184 const char *str,
2185 int unset __maybe_unused)
2186{
2187 struct record_opts *opts = opt->value;
2188 char *s, *p;
2189 unsigned int mmap_pages;
2190 int ret;
2191
2192 if (!str)
2193 return -EINVAL;
2194
2195 s = strdup(str);
2196 if (!s)
2197 return -ENOMEM;
2198
2199 p = strchr(s, ',');
2200 if (p)
2201 *p = '\0';
2202
2203 if (*s) {
2204 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
2205 if (ret)
2206 goto out_free;
2207 opts->mmap_pages = mmap_pages;
2208 }
2209
2210 if (!p) {
2211 ret = 0;
2212 goto out_free;
2213 }
2214
2215 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
2216 if (ret)
2217 goto out_free;
2218
2219 opts->auxtrace_mmap_pages = mmap_pages;
2220
2221out_free:
2222 free(s);
2223 return ret;
2224}
2225
Jiri Olsa0c582442017-01-09 10:51:59 +01002226static void switch_output_size_warn(struct record *rec)
2227{
Jiri Olsa9521b5f2019-07-28 12:45:35 +02002228 u64 wakeup_size = evlist__mmap_size(rec->opts.mmap_pages);
Jiri Olsa0c582442017-01-09 10:51:59 +01002229 struct switch_output *s = &rec->switch_output;
2230
2231 wakeup_size /= 2;
2232
2233 if (s->size < wakeup_size) {
2234 char buf[100];
2235
2236 unit_number__scnprintf(buf, sizeof(buf), wakeup_size);
2237 pr_warning("WARNING: switch-output data size lower than "
2238 "wakeup kernel buffer size (%s) "
2239 "expect bigger perf.data sizes\n", buf);
2240 }
2241}
2242
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01002243static int switch_output_setup(struct record *rec)
2244{
2245 struct switch_output *s = &rec->switch_output;
Jiri Olsadc0c6122017-01-09 10:51:58 +01002246 static struct parse_tag tags_size[] = {
2247 { .tag = 'B', .mult = 1 },
2248 { .tag = 'K', .mult = 1 << 10 },
2249 { .tag = 'M', .mult = 1 << 20 },
2250 { .tag = 'G', .mult = 1 << 30 },
2251 { .tag = 0 },
2252 };
Jiri Olsabfacbe32017-01-09 10:52:00 +01002253 static struct parse_tag tags_time[] = {
2254 { .tag = 's', .mult = 1 },
2255 { .tag = 'm', .mult = 60 },
2256 { .tag = 'h', .mult = 60*60 },
2257 { .tag = 'd', .mult = 60*60*24 },
2258 { .tag = 0 },
2259 };
Jiri Olsadc0c6122017-01-09 10:51:58 +01002260 unsigned long val;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01002261
Arnaldo Carvalho de Melo899e5ff2020-04-27 17:56:37 -03002262 /*
2263 * If we're using --switch-output-events, then we imply its
2264 * --switch-output=signal, as we'll send a SIGUSR2 from the side band
2265 * thread to its parent.
2266 */
2267 if (rec->switch_output_event_set)
2268 goto do_signal;
2269
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01002270 if (!s->set)
2271 return 0;
2272
2273 if (!strcmp(s->str, "signal")) {
Arnaldo Carvalho de Melo899e5ff2020-04-27 17:56:37 -03002274do_signal:
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01002275 s->signal = true;
2276 pr_debug("switch-output with SIGUSR2 signal\n");
Jiri Olsadc0c6122017-01-09 10:51:58 +01002277 goto enabled;
2278 }
2279
2280 val = parse_tag_value(s->str, tags_size);
2281 if (val != (unsigned long) -1) {
2282 s->size = val;
2283 pr_debug("switch-output with %s size threshold\n", s->str);
2284 goto enabled;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01002285 }
2286
Jiri Olsabfacbe32017-01-09 10:52:00 +01002287 val = parse_tag_value(s->str, tags_time);
2288 if (val != (unsigned long) -1) {
2289 s->time = val;
2290 pr_debug("switch-output with %s time threshold (%lu seconds)\n",
2291 s->str, s->time);
2292 goto enabled;
2293 }
2294
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01002295 return -1;
Jiri Olsadc0c6122017-01-09 10:51:58 +01002296
2297enabled:
2298 rec->timestamp_filename = true;
2299 s->enabled = true;
Jiri Olsa0c582442017-01-09 10:51:59 +01002300
2301 if (s->size && !rec->opts.no_buffering)
2302 switch_output_size_warn(rec);
2303
Jiri Olsadc0c6122017-01-09 10:51:58 +01002304 return 0;
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01002305}
2306
Namhyung Kime5b2c202014-10-23 00:15:46 +09002307static const char * const __record_usage[] = {
Mike Galbraith9e0967532009-05-28 16:25:34 +02002308 "perf record [<options>] [<command>]",
2309 "perf record [<options>] -- <command> [<options>]",
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02002310 NULL
2311};
Namhyung Kime5b2c202014-10-23 00:15:46 +09002312const char * const *record_usage = __record_usage;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02002313
Arnaldo Carvalho de Melo6e0a9b32019-11-14 12:15:34 -03002314static int build_id__process_mmap(struct perf_tool *tool, union perf_event *event,
2315 struct perf_sample *sample, struct machine *machine)
2316{
2317 /*
2318 * We already have the kernel maps, put in place via perf_session__create_kernel_maps()
2319 * no need to add them twice.
2320 */
2321 if (!(event->header.misc & PERF_RECORD_MISC_USER))
2322 return 0;
2323 return perf_event__process_mmap(tool, event, sample, machine);
2324}
2325
2326static int build_id__process_mmap2(struct perf_tool *tool, union perf_event *event,
2327 struct perf_sample *sample, struct machine *machine)
2328{
2329 /*
2330 * We already have the kernel maps, put in place via perf_session__create_kernel_maps()
2331 * no need to add them twice.
2332 */
2333 if (!(event->header.misc & PERF_RECORD_MISC_USER))
2334 return 0;
2335
2336 return perf_event__process_mmap2(tool, event, sample, machine);
2337}
2338
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002339/*
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03002340 * XXX Ideally would be local to cmd_record() and passed to a record__new
2341 * because we need to have access to it in record__exit, that is called
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002342 * after cmd_record() exits, but since record_options need to be accessible to
2343 * builtin-script, leave it here.
2344 *
2345 * At least we don't ouch it in all the other functions here directly.
2346 *
2347 * Just say no to tons of global variables, sigh.
2348 */
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03002349static struct record record = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002350 .opts = {
Andi Kleen8affc2b2014-07-31 14:45:04 +08002351 .sample_time = true,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002352 .mmap_pages = UINT_MAX,
2353 .user_freq = UINT_MAX,
2354 .user_interval = ULLONG_MAX,
Arnaldo Carvalho de Melo447a6012012-05-22 13:14:18 -03002355 .freq = 4000,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09002356 .target = {
2357 .uses_mmap = true,
Adrian Hunter3aa59392013-11-15 15:52:29 +02002358 .default_per_cpu = true,
Namhyung Kimd1cb9fc2012-05-16 18:45:49 +09002359 },
Alexey Budankov470530b2019-03-18 20:40:26 +03002360 .mmap_flush = MMAP_FLUSH_DEFAULT,
Stephane Eraniand99c22e2020-04-22 08:50:38 -07002361 .nr_threads_synthesize = 1,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002362 },
Namhyung Kime3d59112015-01-29 17:06:44 +09002363 .tool = {
2364 .sample = process_sample_event,
2365 .fork = perf_event__process_fork,
Adrian Huntercca84822015-08-19 17:29:21 +03002366 .exit = perf_event__process_exit,
Namhyung Kime3d59112015-01-29 17:06:44 +09002367 .comm = perf_event__process_comm,
Hari Bathinif3b36142017-03-08 02:11:43 +05302368 .namespaces = perf_event__process_namespaces,
Arnaldo Carvalho de Melo6e0a9b32019-11-14 12:15:34 -03002369 .mmap = build_id__process_mmap,
2370 .mmap2 = build_id__process_mmap2,
Adrian Huntercca84822015-08-19 17:29:21 +03002371 .ordered_events = true,
Namhyung Kime3d59112015-01-29 17:06:44 +09002372 },
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002373};
Frederic Weisbecker7865e812010-04-14 19:42:07 +02002374
Namhyung Kim76a26542015-10-22 23:28:32 +09002375const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
2376 "\n\t\t\t\tDefault: fp";
Arnaldo Carvalho de Melo61eaa3b2012-10-01 15:20:58 -03002377
Wang Nan0aab2132016-06-16 08:02:41 +00002378static bool dry_run;
2379
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002380/*
2381 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
2382 * with it and switch to use the library functions in perf_evlist that came
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03002383 * from builtin-record.c, i.e. use record_opts,
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002384 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
2385 * using pipes, etc.
2386 */
Jiri Olsaefd21302017-01-03 09:19:55 +01002387static struct option __record_options[] = {
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002388 OPT_CALLBACK('e', "event", &record.evlist, "event",
Thomas Gleixner86847b62009-06-06 12:24:17 +02002389 "event selector. use 'perf list' to list available events",
Jiri Olsaf120f9d2011-07-14 11:25:32 +02002390 parse_events_option),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002391 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
Li Zefanc171b552009-10-15 11:22:07 +08002392 "event filter", parse_filter),
Wang Nan4ba1faa2015-07-10 07:36:10 +00002393 OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
2394 NULL, "don't record events from perf itself",
2395 exclude_perf),
Namhyung Kimbea03402012-04-26 14:15:15 +09002396 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03002397 "record events on existing process id"),
Namhyung Kimbea03402012-04-26 14:15:15 +09002398 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
Zhang, Yanmind6d901c2010-03-18 11:36:05 -03002399 "record events on existing thread id"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002400 OPT_INTEGER('r', "realtime", &record.realtime_prio,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02002401 "collect data with this RT SCHED_FIFO priority"),
Arnaldo Carvalho de Melo509051e2014-01-14 17:52:14 -03002402 OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
Kirill Smelkovacac03f2011-01-12 17:59:36 +03002403 "collect data without buffering"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002404 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
Frederic Weisbeckerdaac07b2009-08-13 10:27:19 +02002405 "collect raw sample records from all opened counters"),
Namhyung Kimbea03402012-04-26 14:15:15 +09002406 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02002407 "system-wide collection from all CPUs"),
Namhyung Kimbea03402012-04-26 14:15:15 +09002408 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
Stephane Eranianc45c6ea2010-05-28 12:00:01 +02002409 "list of cpus to monitor"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002410 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
Jiri Olsa2d4f2792019-02-21 10:41:30 +01002411 OPT_STRING('o', "output", &record.data.path, "file",
Ingo Molnarabaff322009-06-02 22:59:57 +02002412 "output file name"),
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02002413 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
2414 &record.opts.no_inherit_set,
2415 "child tasks do not inherit counters"),
Wang Nan4ea648a2016-07-14 08:34:47 +00002416 OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize,
2417 "synthesize non-sample events at the end of output"),
Wang Nan626a6b72016-07-14 08:34:45 +00002418 OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
Song Liu71184c62019-03-11 22:30:37 -07002419 OPT_BOOLEAN(0, "no-bpf-event", &record.opts.no_bpf_event, "record bpf events"),
Arnaldo Carvalho de Melob09c2362018-03-01 14:52:50 -03002420 OPT_BOOLEAN(0, "strict-freq", &record.opts.strict_freq,
2421 "Fail if the specified frequency can't be used"),
Arnaldo Carvalho de Melo67230472018-03-01 13:46:23 -03002422 OPT_CALLBACK('F', "freq", &record.opts, "freq or 'max'",
2423 "profile at this frequency",
2424 record__parse_freq),
Adrian Huntere9db1312015-04-09 18:53:46 +03002425 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
2426 "number of mmap data pages and AUX area tracing mmap pages",
2427 record__parse_mmap_pages),
Alexey Budankov470530b2019-03-18 20:40:26 +03002428 OPT_CALLBACK(0, "mmap-flush", &record.opts, "number",
2429 "Minimal number of bytes that is extracted from mmap data pages (default: 1)",
2430 record__mmap_flush_parse),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002431 OPT_BOOLEAN(0, "group", &record.opts.group,
Lin Ming43bece72011-08-17 18:42:07 +08002432 "put the counters into a counter group"),
Arnaldo Carvalho de Melo2ddd5c02016-04-18 12:09:08 -03002433 OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02002434 NULL, "enables call-graph recording" ,
2435 &record_callchain_opt),
2436 OPT_CALLBACK(0, "call-graph", &record.opts,
Namhyung Kim76a26542015-10-22 23:28:32 +09002437 "record_mode[,record_size]", record_callchain_help,
Jiri Olsa09b0fd42013-10-26 16:25:33 +02002438 &record_parse_callchain_opt),
Ian Munsiec0555642010-04-13 18:37:33 +10002439 OPT_INCR('v', "verbose", &verbose,
Ingo Molnar3da297a2009-06-07 17:39:02 +02002440 "be more verbose (show counter open errors, etc)"),
Arnaldo Carvalho de Melob44308f2010-10-26 15:20:09 -02002441 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002442 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02002443 "per thread counts"),
Peter Zijlstra56100322015-06-10 16:48:50 +02002444 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
Kan Liang3b0a5da2017-08-29 13:11:08 -04002445 OPT_BOOLEAN(0, "phys-data", &record.opts.sample_phys_addr,
2446 "Record the sample physical addresses"),
Jiri Olsab6f35ed2016-08-01 20:02:35 +02002447 OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"),
Adrian Hunter3abebc52015-07-06 14:51:01 +03002448 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
2449 &record.opts.sample_time_set,
2450 "Record the sample timestamps"),
Jiri Olsaf290aa12018-02-01 09:38:11 +01002451 OPT_BOOLEAN_SET('P', "period", &record.opts.period, &record.opts.period_set,
2452 "Record the sample period"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002453 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
Peter Zijlstra649c48a2009-06-24 21:12:48 +02002454 "don't sample"),
Wang Nand2db9a92016-01-25 09:56:19 +00002455 OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
2456 &record.no_buildid_cache_set,
2457 "do not update the buildid cache"),
2458 OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
2459 &record.no_buildid_set,
2460 "do not collect buildids in perf.data"),
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002461 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
Stephane Eranian023695d2011-02-14 11:20:01 +02002462 "monitor event in cgroup name only",
2463 parse_cgroups),
Arnaldo Carvalho de Meloa6205a32014-01-14 17:58:12 -03002464 OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
Andi Kleen6619a532014-01-11 13:38:27 -08002465 "ms to wait before starting measurement after program start"),
Adrian Huntereeb399b2019-10-04 11:31:21 +03002466 OPT_BOOLEAN(0, "kcore", &record.opts.kcore, "copy /proc/kcore"),
Namhyung Kimbea03402012-04-26 14:15:15 +09002467 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
2468 "user to profile"),
Stephane Eraniana5aabda2012-03-08 23:47:45 +01002469
2470 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
2471 "branch any", "sample any taken branches",
2472 parse_branch_stack),
2473
2474 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
2475 "branch filter mask", "branch stack filter modes",
Roberto Agostino Vitillobdfebd82012-02-09 23:21:02 +01002476 parse_branch_stack),
Andi Kleen05484292013-01-24 16:10:29 +01002477 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
2478 "sample by weight (on special events only)"),
Andi Kleen475eeab2013-09-20 07:40:43 -07002479 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
2480 "sample transaction flags (special events only)"),
Adrian Hunter3aa59392013-11-15 15:52:29 +02002481 OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
2482 "use per-thread mmaps"),
Stephane Eranianbcc84ec2015-08-31 18:41:12 +02002483 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
2484 "sample selected machine registers on interrupt,"
Kan Liangaeea9062019-05-14 13:19:32 -07002485 " use '-I?' to list register names", parse_intr_regs),
Andi Kleen84c41742017-09-05 10:00:28 -07002486 OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register",
2487 "sample selected machine registers on interrupt,"
Kan Liangaeea9062019-05-14 13:19:32 -07002488 " use '--user-regs=?' to list register names", parse_user_regs),
Andi Kleen85c273d2015-02-24 15:13:40 -08002489 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
2490 "Record running/enabled time of read (:S) events"),
Peter Zijlstra814c8c32015-03-31 00:19:31 +02002491 OPT_CALLBACK('k', "clockid", &record.opts,
2492 "clockid", "clockid to use for events, see clock_gettime()",
2493 parse_clockid),
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03002494 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
2495 "opts", "AUX area tracing Snapshot Mode", ""),
Adrian Hunterc0a6de02019-11-15 14:42:16 +02002496 OPT_STRING_OPTARG(0, "aux-sample", &record.opts.auxtrace_sample_opts,
2497 "opts", "sample AUX area", ""),
Mark Drayton3fcb10e2018-12-04 12:34:20 -08002498 OPT_UINTEGER(0, "proc-map-timeout", &proc_map_timeout,
Kan Liang9d9cad72015-06-17 09:51:11 -04002499 "per thread proc mmap processing timeout in ms"),
Hari Bathinif3b36142017-03-08 02:11:43 +05302500 OPT_BOOLEAN(0, "namespaces", &record.opts.record_namespaces,
2501 "Record namespaces events"),
Namhyung Kim8fb4b672020-03-25 21:45:34 +09002502 OPT_BOOLEAN(0, "all-cgroups", &record.opts.record_cgroup,
2503 "Record cgroup events"),
Adrian Hunter16b4b4e2020-05-28 15:08:58 +03002504 OPT_BOOLEAN_SET(0, "switch-events", &record.opts.record_switch_events,
2505 &record.opts.record_switch_events_set,
2506 "Record context switch events"),
Jiri Olsa85723882016-02-15 09:34:31 +01002507 OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
2508 "Configure all used events to run in kernel space.",
2509 PARSE_OPT_EXCLUSIVE),
2510 OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
2511 "Configure all used events to run in user space.",
2512 PARSE_OPT_EXCLUSIVE),
yuzhoujian53651b22019-05-30 14:29:22 +01002513 OPT_BOOLEAN(0, "kernel-callchains", &record.opts.kernel_callchains,
2514 "collect kernel callchains"),
2515 OPT_BOOLEAN(0, "user-callchains", &record.opts.user_callchains,
2516 "collect user callchains"),
Wang Nan71dc23262015-10-14 12:41:19 +00002517 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
2518 "clang binary to use for compiling BPF scriptlets"),
2519 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
2520 "options passed to clang when compiling BPF scriptlets"),
He Kuang7efe0e02015-12-14 10:39:23 +00002521 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
2522 "file", "vmlinux pathname"),
Namhyung Kim61566812016-01-11 22:37:09 +09002523 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
2524 "Record build-id of all DSOs regardless of hits"),
Wang Nanecfd7a92016-04-13 08:21:07 +00002525 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
2526 "append timestamp to output filename"),
Jin Yao68588ba2017-12-08 21:13:42 +08002527 OPT_BOOLEAN(0, "timestamp-boundary", &record.timestamp_boundary,
2528 "Record timestamp boundary (time of first/last samples)"),
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01002529 OPT_STRING_OPTARG_SET(0, "switch-output", &record.switch_output.str,
Andi Kleenc38dab72019-03-14 15:49:56 -07002530 &record.switch_output.set, "signal or size[BKMG] or time[smhd]",
2531 "Switch output when receiving SIGUSR2 (signal) or cross a size or time threshold",
Jiri Olsadc0c6122017-01-09 10:51:58 +01002532 "signal"),
Arnaldo Carvalho de Melo899e5ff2020-04-27 17:56:37 -03002533 OPT_CALLBACK_SET(0, "switch-output-event", &record.sb_evlist, &record.switch_output_event_set, "switch output event",
2534 "switch output event selector. use 'perf list' to list available events",
2535 parse_events_option_new_evlist),
Andi Kleen03724b22019-03-14 15:49:55 -07002536 OPT_INTEGER(0, "switch-max-files", &record.switch_output.num_files,
2537 "Limit number of switch output generated files"),
Wang Nan0aab2132016-06-16 08:02:41 +00002538 OPT_BOOLEAN(0, "dry-run", &dry_run,
2539 "Parse options then exit"),
Alexey Budankovd3d1af62018-11-06 12:04:58 +03002540#ifdef HAVE_AIO_SUPPORT
Alexey Budankov93f20c02018-11-06 12:07:19 +03002541 OPT_CALLBACK_OPTARG(0, "aio", &record.opts,
2542 &nr_cblocks_default, "n", "Use <n> control blocks in asynchronous trace writing mode (default: 1, max: 4)",
Alexey Budankovd3d1af62018-11-06 12:04:58 +03002543 record__aio_parse),
2544#endif
Alexey Budankovf4fe11b2019-01-22 20:52:03 +03002545 OPT_CALLBACK(0, "affinity", &record.opts, "node|cpu",
2546 "Set affinity mask of trace reading thread to NUMA node cpu mask or cpu of processed mmap buffer",
2547 record__parse_affinity),
Alexey Budankov504c1ad2019-03-18 20:44:42 +03002548#ifdef HAVE_ZSTD_SUPPORT
2549 OPT_CALLBACK_OPTARG('z', "compression-level", &record.opts, &comp_level_default,
2550 "n", "Compressed records using specified level (default: 1 - fastest compression, 22 - greatest compression)",
2551 record__parse_comp_level),
2552#endif
Jiwei Sun6d575812019-10-22 16:09:01 +08002553 OPT_CALLBACK(0, "max-size", &record.output_max_size,
2554 "size", "Limit the maximum size of the output file", parse_output_max_size),
Stephane Eraniand99c22e2020-04-22 08:50:38 -07002555 OPT_UINTEGER(0, "num-thread-synthesize",
2556 &record.opts.nr_threads_synthesize,
2557 "number of threads to run for event synthesis"),
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02002558 OPT_END()
2559};
2560
Namhyung Kime5b2c202014-10-23 00:15:46 +09002561struct option *record_options = __record_options;
2562
Arnaldo Carvalho de Melob0ad8ea2017-03-27 11:47:20 -03002563int cmd_record(int argc, const char **argv)
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02002564{
Adrian Hunteref149c22015-04-09 18:53:45 +03002565 int err;
Arnaldo Carvalho de Melo8c6f45a2013-12-19 14:38:03 -03002566 struct record *rec = &record;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09002567 char errbuf[BUFSIZ];
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02002568
Arnaldo Carvalho de Melo67230472018-03-01 13:46:23 -03002569 setlocale(LC_ALL, "");
2570
Wang Nan48e1cab2015-12-14 10:39:22 +00002571#ifndef HAVE_LIBBPF_SUPPORT
2572# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
2573 set_nobuild('\0', "clang-path", true);
2574 set_nobuild('\0', "clang-opt", true);
2575# undef set_nobuild
2576#endif
2577
He Kuang7efe0e02015-12-14 10:39:23 +00002578#ifndef HAVE_BPF_PROLOGUE
2579# if !defined (HAVE_DWARF_SUPPORT)
2580# define REASON "NO_DWARF=1"
2581# elif !defined (HAVE_LIBBPF_SUPPORT)
2582# define REASON "NO_LIBBPF=1"
2583# else
2584# define REASON "this architecture doesn't support BPF prologue"
2585# endif
2586# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
2587 set_nobuild('\0', "vmlinux", true);
2588# undef set_nobuild
2589# undef REASON
2590#endif
2591
Alexey Budankov9d2ed642019-01-22 20:47:43 +03002592 rec->opts.affinity = PERF_AFFINITY_SYS;
2593
Jiri Olsa0f98b112019-07-21 13:23:55 +02002594 rec->evlist = evlist__new();
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03002595 if (rec->evlist == NULL)
Arnaldo Carvalho de Melo361c99a2011-01-11 20:56:53 -02002596 return -ENOMEM;
2597
Arnaldo Carvalho de Meloecc4c562017-01-24 13:44:10 -03002598 err = perf_config(perf_record_config, rec);
2599 if (err)
2600 return err;
Jiri Olsaeb853e82014-02-03 12:44:42 +01002601
Tom Zanussibca647a2010-11-10 08:11:30 -06002602 argc = parse_options(argc, argv, record_options, record_usage,
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02002603 PARSE_OPT_STOP_AT_NON_OPTION);
Namhyung Kim68ba3232017-02-17 17:17:42 +09002604 if (quiet)
2605 perf_quiet_option();
Jiri Olsa483635a2017-02-17 18:00:18 +01002606
2607 /* Make system wide (-a) the default target. */
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03002608 if (!argc && target__none(&rec->opts.target))
Jiri Olsa483635a2017-02-17 18:00:18 +01002609 rec->opts.target.system_wide = true;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02002610
Namhyung Kimbea03402012-04-26 14:15:15 +09002611 if (nr_cgroups && !rec->opts.target.system_wide) {
Namhyung Kimc7118362015-10-25 00:49:27 +09002612 usage_with_options_msg(record_usage, record_options,
2613 "cgroup monitoring only available in system-wide mode");
2614
Stephane Eranian023695d2011-02-14 11:20:01 +02002615 }
Alexey Budankov504c1ad2019-03-18 20:44:42 +03002616
Adrian Huntereeb399b2019-10-04 11:31:21 +03002617 if (rec->opts.kcore)
2618 rec->data.is_dir = true;
2619
Alexey Budankov504c1ad2019-03-18 20:44:42 +03002620 if (rec->opts.comp_level != 0) {
2621 pr_debug("Compression enabled, disabling build id collection at the end of the session.\n");
2622 rec->no_buildid = true;
2623 }
2624
Adrian Hunterb757bb02015-07-21 12:44:04 +03002625 if (rec->opts.record_switch_events &&
2626 !perf_can_record_switch_events()) {
Namhyung Kimc7118362015-10-25 00:49:27 +09002627 ui__error("kernel does not support recording context switch events\n");
2628 parse_options_usage(record_usage, record_options, "switch-events", 0);
2629 return -EINVAL;
Adrian Hunterb757bb02015-07-21 12:44:04 +03002630 }
Stephane Eranian023695d2011-02-14 11:20:01 +02002631
Jiri Olsacb4e1eb2017-01-09 10:51:57 +01002632 if (switch_output_setup(rec)) {
2633 parse_options_usage(record_usage, record_options, "switch-output", 0);
2634 return -EINVAL;
2635 }
2636
Jiri Olsabfacbe32017-01-09 10:52:00 +01002637 if (rec->switch_output.time) {
2638 signal(SIGALRM, alarm_sig_handler);
2639 alarm(rec->switch_output.time);
2640 }
2641
Andi Kleen03724b22019-03-14 15:49:55 -07002642 if (rec->switch_output.num_files) {
2643 rec->switch_output.filenames = calloc(sizeof(char *),
2644 rec->switch_output.num_files);
2645 if (!rec->switch_output.filenames)
2646 return -EINVAL;
2647 }
2648
Adrian Hunter1b36c032016-09-23 17:38:39 +03002649 /*
2650 * Allow aliases to facilitate the lookup of symbols for address
2651 * filters. Refer to auxtrace_parse_filters().
2652 */
2653 symbol_conf.allow_aliases = true;
2654
2655 symbol__init(NULL);
2656
Alexey Budankov8384a262019-12-03 14:45:27 +03002657 if (rec->opts.affinity != PERF_AFFINITY_SYS) {
2658 rec->affinity_mask.nbits = cpu__max_cpu();
2659 rec->affinity_mask.bits = bitmap_alloc(rec->affinity_mask.nbits);
2660 if (!rec->affinity_mask.bits) {
2661 pr_err("Failed to allocate thread mask for %zd cpus\n", rec->affinity_mask.nbits);
2662 return -ENOMEM;
2663 }
2664 pr_debug2("thread mask[%zd]: empty\n", rec->affinity_mask.nbits);
2665 }
2666
Adrian Hunter4b5ea3b2018-03-06 11:13:12 +02002667 err = record__auxtrace_init(rec);
Adrian Hunter1b36c032016-09-23 17:38:39 +03002668 if (err)
2669 goto out;
2670
Wang Nan0aab2132016-06-16 08:02:41 +00002671 if (dry_run)
Adrian Hunter5c01ad602016-09-23 17:38:37 +03002672 goto out;
Wang Nan0aab2132016-06-16 08:02:41 +00002673
Wang Nand7888572016-04-08 15:07:24 +00002674 err = bpf__setup_stdout(rec->evlist);
2675 if (err) {
2676 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
2677 pr_err("ERROR: Setup BPF stdout failed: %s\n",
2678 errbuf);
Adrian Hunter5c01ad602016-09-23 17:38:37 +03002679 goto out;
Wang Nand7888572016-04-08 15:07:24 +00002680 }
2681
Adrian Hunteref149c22015-04-09 18:53:45 +03002682 err = -ENOMEM;
2683
Wang Nan0c1d46a2016-04-20 18:59:52 +00002684 if (rec->no_buildid_cache || rec->no_buildid) {
Stephane Eraniana1ac1d32010-06-17 11:39:01 +02002685 disable_buildid_cache();
Jiri Olsadc0c6122017-01-09 10:51:58 +01002686 } else if (rec->switch_output.enabled) {
Wang Nan0c1d46a2016-04-20 18:59:52 +00002687 /*
2688 * In 'perf record --switch-output', disable buildid
2689 * generation by default to reduce data file switching
2690 * overhead. Still generate buildid if they are required
2691 * explicitly using
2692 *
Jiri Olsa60437ac2017-01-03 09:19:56 +01002693 * perf record --switch-output --no-no-buildid \
Wang Nan0c1d46a2016-04-20 18:59:52 +00002694 * --no-no-buildid-cache
2695 *
2696 * Following code equals to:
2697 *
2698 * if ((rec->no_buildid || !rec->no_buildid_set) &&
2699 * (rec->no_buildid_cache || !rec->no_buildid_cache_set))
2700 * disable_buildid_cache();
2701 */
2702 bool disable = true;
2703
2704 if (rec->no_buildid_set && !rec->no_buildid)
2705 disable = false;
2706 if (rec->no_buildid_cache_set && !rec->no_buildid_cache)
2707 disable = false;
2708 if (disable) {
2709 rec->no_buildid = true;
2710 rec->no_buildid_cache = true;
2711 disable_buildid_cache();
2712 }
2713 }
Arnaldo Carvalho de Melo655000e2009-12-15 20:04:40 -02002714
Wang Nan4ea648a2016-07-14 08:34:47 +00002715 if (record.opts.overwrite)
2716 record.opts.tail_synthesize = true;
2717
Jiri Olsa6484d2f2019-07-21 13:24:28 +02002718 if (rec->evlist->core.nr_entries == 0 &&
Arnaldo Carvalho de Melo4b4cd502017-07-03 13:26:32 -03002719 __perf_evlist__add_default(rec->evlist, !record.opts.no_samples) < 0) {
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02002720 pr_err("Not enough memory for event selector list\n");
Adrian Hunter394c01e2016-09-23 17:38:36 +03002721 goto out;
Peter Zijlstrabbd36e52009-06-11 23:11:50 +02002722 }
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02002723
Adrian Hunter69e7e5b2013-11-18 11:55:57 +02002724 if (rec->opts.target.tid && !rec->opts.no_inherit_set)
2725 rec->opts.no_inherit = true;
2726
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03002727 err = target__validate(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09002728 if (err) {
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03002729 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Jiri Olsac3dec272018-02-06 19:17:58 +01002730 ui__warning("%s\n", errbuf);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09002731 }
Namhyung Kim4bd0f2d2012-04-26 14:15:18 +09002732
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03002733 err = target__parse_uid(&rec->opts.target);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09002734 if (err) {
2735 int saved_errno = errno;
2736
Arnaldo Carvalho de Melo602ad872013-11-12 16:46:16 -03002737 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
Namhyung Kim3780f482012-05-29 13:22:57 +09002738 ui__error("%s", errbuf);
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09002739
2740 err = -saved_errno;
Adrian Hunter394c01e2016-09-23 17:38:36 +03002741 goto out;
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09002742 }
Arnaldo Carvalho de Melo0d37aa32012-01-19 14:08:15 -02002743
Mengting Zhangca800062017-12-13 15:01:53 +08002744 /* Enable ignoring missing threads when -u/-p option is defined. */
2745 rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX || rec->opts.target.pid;
Jiri Olsa23dc4f12016-12-12 11:35:43 +01002746
Namhyung Kim16ad2ff2012-05-07 14:09:02 +09002747 err = -ENOMEM;
Arnaldo Carvalho de Melo3e2be2d2014-01-03 15:03:26 -03002748 if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
Arnaldo Carvalho de Melodd7927f2011-01-12 14:28:51 -02002749 usage_with_options(record_usage, record_options);
Arnaldo Carvalho de Melo69aad6f2011-01-03 16:39:04 -02002750
Adrian Hunteref149c22015-04-09 18:53:45 +03002751 err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
2752 if (err)
Adrian Hunter394c01e2016-09-23 17:38:36 +03002753 goto out;
Adrian Hunteref149c22015-04-09 18:53:45 +03002754
Namhyung Kim61566812016-01-11 22:37:09 +09002755 /*
2756 * We take all buildids when the file contains
2757 * AUX area tracing data because we do not decode the
2758 * trace because it would take too long.
2759 */
2760 if (rec->opts.full_auxtrace)
2761 rec->buildid_all = true;
2762
Arnaldo Carvalho de Melob4006792013-12-19 14:43:45 -03002763 if (record_opts__config(&rec->opts)) {
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03002764 err = -EINVAL;
Adrian Hunter394c01e2016-09-23 17:38:36 +03002765 goto out;
Mike Galbraith7e4ff9e2009-10-12 07:56:03 +02002766 }
2767
Alexey Budankov93f20c02018-11-06 12:07:19 +03002768 if (rec->opts.nr_cblocks > nr_cblocks_max)
2769 rec->opts.nr_cblocks = nr_cblocks_max;
Alexey Budankov5d7f4112019-03-18 20:43:35 +03002770 pr_debug("nr_cblocks: %d\n", rec->opts.nr_cblocks);
Alexey Budankovd3d1af62018-11-06 12:04:58 +03002771
Alexey Budankov9d2ed642019-01-22 20:47:43 +03002772 pr_debug("affinity: %s\n", affinity_tags[rec->opts.affinity]);
Alexey Budankov470530b2019-03-18 20:40:26 +03002773 pr_debug("mmap flush: %d\n", rec->opts.mmap_flush);
Alexey Budankov9d2ed642019-01-22 20:47:43 +03002774
Alexey Budankov51255a82019-03-18 20:42:19 +03002775 if (rec->opts.comp_level > comp_level_max)
2776 rec->opts.comp_level = comp_level_max;
2777 pr_debug("comp level: %d\n", rec->opts.comp_level);
2778
Arnaldo Carvalho de Melod20deb62011-11-25 08:19:45 -02002779 err = __cmd_record(&record, argc, argv);
Adrian Hunter394c01e2016-09-23 17:38:36 +03002780out:
Alexey Budankov8384a262019-12-03 14:45:27 +03002781 bitmap_free(rec->affinity_mask.bits);
Jiri Olsac12995a2019-07-21 13:23:56 +02002782 evlist__delete(rec->evlist);
Arnaldo Carvalho de Melod65a4582010-07-30 18:31:28 -03002783 symbol__exit();
Adrian Hunteref149c22015-04-09 18:53:45 +03002784 auxtrace_record__free(rec->itr);
Arnaldo Carvalho de Melo39d17da2010-07-29 14:08:55 -03002785 return err;
Ingo Molnar0e9b20b2009-05-26 09:17:18 +02002786}
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03002787
2788static void snapshot_sig_handler(int sig __maybe_unused)
2789{
Jiri Olsadc0c6122017-01-09 10:51:58 +01002790 struct record *rec = &record;
2791
Wang Nan5f9cf592016-04-20 18:59:49 +00002792 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
2793 trigger_hit(&auxtrace_snapshot_trigger);
2794 auxtrace_record__snapshot_started = 1;
2795 if (auxtrace_record__snapshot_start(record.itr))
2796 trigger_error(&auxtrace_snapshot_trigger);
2797 }
Wang Nan3c1cb7e2016-04-20 18:59:50 +00002798
Jiri Olsadc0c6122017-01-09 10:51:58 +01002799 if (switch_output_signal(rec))
Wang Nan3c1cb7e2016-04-20 18:59:50 +00002800 trigger_hit(&switch_output_trigger);
Adrian Hunter2dd6d8a2015-04-30 17:37:32 +03002801}
Jiri Olsabfacbe32017-01-09 10:52:00 +01002802
2803static void alarm_sig_handler(int sig __maybe_unused)
2804{
2805 struct record *rec = &record;
2806
2807 if (switch_output_time(rec))
2808 trigger_hit(&switch_output_trigger);
2809}