1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 286470930SIngo Molnar /* 386470930SIngo Molnar * builtin-record.c 486470930SIngo Molnar * 586470930SIngo Molnar * Builtin record command: Record the profile of a workload 686470930SIngo Molnar * (or a CPU, or a PID) into the perf.data output file - for 786470930SIngo Molnar * later analysis via perf report. 886470930SIngo Molnar */ 986470930SIngo Molnar #include "builtin.h" 1086470930SIngo Molnar 116122e4e4SArnaldo Carvalho de Melo #include "util/build-id.h" 124b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h> 1386470930SIngo Molnar #include "util/parse-events.h" 1441840d21STaeung Song #include "util/config.h" 1586470930SIngo Molnar 168f651eaeSArnaldo Carvalho de Melo #include "util/callchain.h" 17f14d5707SArnaldo Carvalho de Melo #include "util/cgroup.h" 187c6a1c65SPeter Zijlstra #include "util/header.h" 1966e274f3SFrederic Weisbecker #include "util/event.h" 20361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h" 2169aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h" 228f28827aSFrederic Weisbecker #include "util/debug.h" 23e0fcfb08SArnaldo Carvalho de Melo #include "util/mmap.h" 24aeb00b1aSArnaldo Carvalho de Melo #include "util/target.h" 2594c744b6SArnaldo Carvalho de Melo #include "util/session.h" 2645694aa7SArnaldo Carvalho de Melo #include "util/tool.h" 278d06367fSArnaldo Carvalho de Melo #include "util/symbol.h" 28aeb00b1aSArnaldo Carvalho de Melo #include "util/record.h" 29a12b51c4SPaul Mackerras #include "util/cpumap.h" 30fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 31f5fc1412SJiri Olsa #include "util/data.h" 32bcc84ec6SStephane Eranian #include "util/perf_regs.h" 33ef149c25SAdrian Hunter #include "util/auxtrace.h" 3446bc29b9SAdrian Hunter #include "util/tsc.h" 35f00898f4SAndi Kleen #include "util/parse-branch-options.h" 36bcc84ec6SStephane Eranian #include "util/parse-regs-options.h" 3771dc2326SWang Nan #include "util/llvm-utils.h" 388690a2a7SWang Nan #include "util/bpf-loader.h" 395f9cf599SWang Nan #include "util/trigger.h" 40a074865eSWang Nan #include "util/perf-hooks.h" 41f13de660SAlexey Budankov #include "util/cpu-set-sched.h" 42ea49e01cSArnaldo Carvalho de Melo #include "util/synthetic-events.h" 43c5e4027eSArnaldo Carvalho de Melo #include "util/time-utils.h" 4458db1d6eSArnaldo Carvalho de Melo #include "util/units.h" 457b612e29SSong Liu #include "util/bpf-event.h" 46d8871ea7SWang Nan #include "asm/bug.h" 47c1a604dfSArnaldo Carvalho de Melo #include "perf.h" 487c6a1c65SPeter Zijlstra 49a43783aeSArnaldo Carvalho de Melo #include <errno.h> 50fd20e811SArnaldo Carvalho de Melo #include <inttypes.h> 5167230479SArnaldo Carvalho de Melo #include <locale.h> 524208735dSArnaldo Carvalho de Melo #include <poll.h> 5386470930SIngo Molnar #include <unistd.h> 5486470930SIngo Molnar #include <sched.h> 559607ad3aSArnaldo Carvalho de Melo #include <signal.h> 56a41794cdSArnaldo Carvalho de Melo #include <sys/mman.h> 574208735dSArnaldo Carvalho de Melo #include <sys/wait.h> 58eeb399b5SAdrian Hunter #include <sys/types.h> 59eeb399b5SAdrian Hunter #include <sys/stat.h> 60eeb399b5SAdrian Hunter #include <fcntl.h> 616ef81c55SMamatha Inamdar #include <linux/err.h> 628520a98dSArnaldo Carvalho de Melo #include <linux/string.h> 630693e680SArnaldo Carvalho de Melo #include <linux/time64.h> 64d8f9da24SArnaldo Carvalho de Melo #include <linux/zalloc.h> 6578da39faSBernhard Rosenkraenzer 661b43b704SJiri Olsa struct switch_output { 67dc0c6127SJiri Olsa bool enabled; 681b43b704SJiri Olsa bool signal; 69dc0c6127SJiri Olsa unsigned long size; 70bfacbe3bSJiri Olsa unsigned long time; 71cb4e1ebbSJiri Olsa const char *str; 72cb4e1ebbSJiri Olsa bool set; 7303724b2eSAndi Kleen char **filenames; 7403724b2eSAndi Kleen int num_files; 7503724b2eSAndi Kleen int cur_file; 761b43b704SJiri Olsa }; 771b43b704SJiri Olsa 788c6f45a7SArnaldo Carvalho de Melo struct record { 7945694aa7SArnaldo Carvalho de Melo struct perf_tool tool; 80b4006796SArnaldo Carvalho de Melo struct record_opts opts; 81d20deb64SArnaldo Carvalho de Melo u64 bytes_written; 828ceb41d7SJiri Olsa struct perf_data data; 83ef149c25SAdrian Hunter struct auxtrace_record *itr; 8463503dbaSJiri Olsa struct evlist *evlist; 85d20deb64SArnaldo Carvalho de Melo struct perf_session *session; 86d20deb64SArnaldo Carvalho de Melo int realtime_prio; 87d20deb64SArnaldo Carvalho de Melo bool no_buildid; 88d2db9a98SWang Nan bool no_buildid_set; 89d20deb64SArnaldo Carvalho de Melo bool no_buildid_cache; 90d2db9a98SWang Nan bool no_buildid_cache_set; 916156681bSNamhyung Kim bool buildid_all; 92ecfd7a9cSWang Nan bool timestamp_filename; 9368588bafSJin Yao bool timestamp_boundary; 941b43b704SJiri Olsa struct switch_output switch_output; 959f065194SYang Shi unsigned long long samples; 969d2ed645SAlexey Budankov cpu_set_t affinity_mask; 976d575816SJiwei Sun unsigned long output_max_size; /* = 0: unlimited */ 980f82ebc4SArnaldo Carvalho de Melo }; 9986470930SIngo Molnar 1006d575816SJiwei Sun static volatile int done; 1016d575816SJiwei Sun 102dc0c6127SJiri Olsa static volatile int auxtrace_record__snapshot_started; 103dc0c6127SJiri Olsa static DEFINE_TRIGGER(auxtrace_snapshot_trigger); 104dc0c6127SJiri Olsa static DEFINE_TRIGGER(switch_output_trigger); 105dc0c6127SJiri Olsa 1069d2ed645SAlexey Budankov static const char *affinity_tags[PERF_AFFINITY_MAX] = { 1079d2ed645SAlexey Budankov "SYS", "NODE", "CPU" 1089d2ed645SAlexey Budankov }; 1099d2ed645SAlexey Budankov 110dc0c6127SJiri Olsa static bool switch_output_signal(struct record *rec) 111dc0c6127SJiri Olsa { 112dc0c6127SJiri Olsa return rec->switch_output.signal && 113dc0c6127SJiri Olsa trigger_is_ready(&switch_output_trigger); 114dc0c6127SJiri Olsa } 115dc0c6127SJiri Olsa 116dc0c6127SJiri Olsa static bool switch_output_size(struct record *rec) 117dc0c6127SJiri Olsa { 118dc0c6127SJiri Olsa return rec->switch_output.size && 119dc0c6127SJiri Olsa trigger_is_ready(&switch_output_trigger) && 120dc0c6127SJiri Olsa (rec->bytes_written >= rec->switch_output.size); 121dc0c6127SJiri Olsa } 122dc0c6127SJiri Olsa 123bfacbe3bSJiri Olsa static bool switch_output_time(struct record *rec) 124bfacbe3bSJiri Olsa { 125bfacbe3bSJiri Olsa return rec->switch_output.time && 126bfacbe3bSJiri Olsa trigger_is_ready(&switch_output_trigger); 127bfacbe3bSJiri Olsa } 128bfacbe3bSJiri Olsa 1296d575816SJiwei Sun static bool record__output_max_size_exceeded(struct record *rec) 1306d575816SJiwei Sun { 1316d575816SJiwei Sun return rec->output_max_size && 1326d575816SJiwei Sun (rec->bytes_written >= rec->output_max_size); 1336d575816SJiwei Sun } 1346d575816SJiwei Sun 135a5830532SJiri Olsa static int record__write(struct record *rec, struct mmap *map __maybe_unused, 136ded2b8feSJiri Olsa void *bf, size_t size) 137f5970550SPeter Zijlstra { 138ded2b8feSJiri Olsa struct perf_data_file *file = &rec->session->data->file; 139ded2b8feSJiri Olsa 140ded2b8feSJiri Olsa if (perf_data_file__write(file, bf, size) < 0) { 1414f624685SAdrian Hunter pr_err("failed to write perf data, error: %m\n"); 1428d3eca20SDavid Ahern return -1; 1438d3eca20SDavid Ahern } 144f5970550SPeter Zijlstra 145cf8b2e69SArnaldo Carvalho de Melo rec->bytes_written += size; 146dc0c6127SJiri Olsa 1476d575816SJiwei Sun if (record__output_max_size_exceeded(rec) && !done) { 1486d575816SJiwei Sun fprintf(stderr, "[ perf record: perf size limit reached (%" PRIu64 " KB)," 1496d575816SJiwei Sun " stopping session ]\n", 1506d575816SJiwei Sun rec->bytes_written >> 10); 1516d575816SJiwei Sun done = 1; 1526d575816SJiwei Sun } 1536d575816SJiwei Sun 154dc0c6127SJiri Olsa if (switch_output_size(rec)) 155dc0c6127SJiri Olsa trigger_hit(&switch_output_trigger); 156dc0c6127SJiri Olsa 1578d3eca20SDavid Ahern return 0; 158f5970550SPeter Zijlstra } 159f5970550SPeter Zijlstra 160ef781128SAlexey Budankov static int record__aio_enabled(struct record *rec); 161ef781128SAlexey Budankov static int record__comp_enabled(struct record *rec); 1625d7f4116SAlexey Budankov static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_size, 1635d7f4116SAlexey Budankov void *src, size_t src_size); 1645d7f4116SAlexey Budankov 165d3d1af6fSAlexey Budankov #ifdef HAVE_AIO_SUPPORT 166d3d1af6fSAlexey Budankov static int record__aio_write(struct aiocb *cblock, int trace_fd, 167d3d1af6fSAlexey Budankov void *buf, size_t size, off_t off) 168d3d1af6fSAlexey Budankov { 169d3d1af6fSAlexey Budankov int rc; 170d3d1af6fSAlexey Budankov 171d3d1af6fSAlexey Budankov cblock->aio_fildes = trace_fd; 172d3d1af6fSAlexey Budankov cblock->aio_buf = buf; 173d3d1af6fSAlexey Budankov cblock->aio_nbytes = size; 174d3d1af6fSAlexey Budankov cblock->aio_offset = off; 175d3d1af6fSAlexey Budankov cblock->aio_sigevent.sigev_notify = SIGEV_NONE; 176d3d1af6fSAlexey Budankov 177d3d1af6fSAlexey Budankov do { 178d3d1af6fSAlexey Budankov rc = aio_write(cblock); 179d3d1af6fSAlexey Budankov if (rc == 0) { 180d3d1af6fSAlexey Budankov break; 181d3d1af6fSAlexey Budankov } else if (errno != EAGAIN) { 182d3d1af6fSAlexey Budankov cblock->aio_fildes = -1; 183d3d1af6fSAlexey Budankov pr_err("failed to queue perf data, error: %m\n"); 184d3d1af6fSAlexey Budankov break; 185d3d1af6fSAlexey Budankov } 186d3d1af6fSAlexey Budankov } while (1); 187d3d1af6fSAlexey Budankov 188d3d1af6fSAlexey Budankov return rc; 189d3d1af6fSAlexey Budankov } 190d3d1af6fSAlexey Budankov 191a5830532SJiri Olsa static int record__aio_complete(struct mmap *md, struct aiocb *cblock) 192d3d1af6fSAlexey Budankov { 193d3d1af6fSAlexey Budankov void *rem_buf; 194d3d1af6fSAlexey Budankov off_t rem_off; 195d3d1af6fSAlexey Budankov size_t rem_size; 196d3d1af6fSAlexey Budankov int rc, aio_errno; 197d3d1af6fSAlexey Budankov ssize_t aio_ret, written; 198d3d1af6fSAlexey Budankov 199d3d1af6fSAlexey Budankov aio_errno = aio_error(cblock); 200d3d1af6fSAlexey Budankov if (aio_errno == EINPROGRESS) 201d3d1af6fSAlexey Budankov return 0; 202d3d1af6fSAlexey Budankov 203d3d1af6fSAlexey Budankov written = aio_ret = aio_return(cblock); 204d3d1af6fSAlexey Budankov if (aio_ret < 0) { 205d3d1af6fSAlexey Budankov if (aio_errno != EINTR) 206d3d1af6fSAlexey Budankov pr_err("failed to write perf data, error: %m\n"); 207d3d1af6fSAlexey Budankov written = 0; 208d3d1af6fSAlexey Budankov } 209d3d1af6fSAlexey Budankov 210d3d1af6fSAlexey Budankov rem_size = cblock->aio_nbytes - written; 211d3d1af6fSAlexey Budankov 212d3d1af6fSAlexey Budankov if (rem_size == 0) { 213d3d1af6fSAlexey Budankov cblock->aio_fildes = -1; 214d3d1af6fSAlexey Budankov /* 215ef781128SAlexey Budankov * md->refcount is incremented in record__aio_pushfn() for 216ef781128SAlexey Budankov * every aio write request started in record__aio_push() so 217ef781128SAlexey Budankov * decrement it because the request is now complete. 218d3d1af6fSAlexey Budankov */ 21980e53d11SJiri Olsa perf_mmap__put(&md->core); 220d3d1af6fSAlexey Budankov rc = 1; 221d3d1af6fSAlexey Budankov } else { 222d3d1af6fSAlexey Budankov /* 223d3d1af6fSAlexey Budankov * aio write request may require restart with the 224d3d1af6fSAlexey Budankov * reminder if the kernel didn't write whole 225d3d1af6fSAlexey Budankov * chunk at once. 226d3d1af6fSAlexey Budankov */ 227d3d1af6fSAlexey Budankov rem_off = cblock->aio_offset + written; 228d3d1af6fSAlexey Budankov rem_buf = (void *)(cblock->aio_buf + written); 229d3d1af6fSAlexey Budankov record__aio_write(cblock, cblock->aio_fildes, 230d3d1af6fSAlexey Budankov rem_buf, rem_size, rem_off); 231d3d1af6fSAlexey Budankov rc = 0; 232d3d1af6fSAlexey Budankov } 233d3d1af6fSAlexey Budankov 234d3d1af6fSAlexey Budankov return rc; 235d3d1af6fSAlexey Budankov } 236d3d1af6fSAlexey Budankov 237a5830532SJiri Olsa static int record__aio_sync(struct mmap *md, bool sync_all) 238d3d1af6fSAlexey Budankov { 23993f20c0fSAlexey Budankov struct aiocb **aiocb = md->aio.aiocb; 24093f20c0fSAlexey Budankov struct aiocb *cblocks = md->aio.cblocks; 241d3d1af6fSAlexey Budankov struct timespec timeout = { 0, 1000 * 1000 * 1 }; /* 1ms */ 24293f20c0fSAlexey Budankov int i, do_suspend; 243d3d1af6fSAlexey Budankov 244d3d1af6fSAlexey Budankov do { 24593f20c0fSAlexey Budankov do_suspend = 0; 24693f20c0fSAlexey Budankov for (i = 0; i < md->aio.nr_cblocks; ++i) { 24793f20c0fSAlexey Budankov if (cblocks[i].aio_fildes == -1 || record__aio_complete(md, &cblocks[i])) { 24893f20c0fSAlexey Budankov if (sync_all) 24993f20c0fSAlexey Budankov aiocb[i] = NULL; 25093f20c0fSAlexey Budankov else 25193f20c0fSAlexey Budankov return i; 25293f20c0fSAlexey Budankov } else { 25393f20c0fSAlexey Budankov /* 25493f20c0fSAlexey Budankov * Started aio write is not complete yet 25593f20c0fSAlexey Budankov * so it has to be waited before the 25693f20c0fSAlexey Budankov * next allocation. 25793f20c0fSAlexey Budankov */ 25893f20c0fSAlexey Budankov aiocb[i] = &cblocks[i]; 25993f20c0fSAlexey Budankov do_suspend = 1; 26093f20c0fSAlexey Budankov } 26193f20c0fSAlexey Budankov } 26293f20c0fSAlexey Budankov if (!do_suspend) 26393f20c0fSAlexey Budankov return -1; 264d3d1af6fSAlexey Budankov 26593f20c0fSAlexey Budankov while (aio_suspend((const struct aiocb **)aiocb, md->aio.nr_cblocks, &timeout)) { 266d3d1af6fSAlexey Budankov if (!(errno == EAGAIN || errno == EINTR)) 267d3d1af6fSAlexey Budankov pr_err("failed to sync perf data, error: %m\n"); 268d3d1af6fSAlexey Budankov } 269d3d1af6fSAlexey Budankov } while (1); 270d3d1af6fSAlexey Budankov } 271d3d1af6fSAlexey Budankov 272ef781128SAlexey Budankov struct record_aio { 273ef781128SAlexey Budankov struct record *rec; 274ef781128SAlexey Budankov void *data; 275ef781128SAlexey Budankov size_t size; 276ef781128SAlexey Budankov }; 277ef781128SAlexey Budankov 278a5830532SJiri Olsa static int record__aio_pushfn(struct mmap *map, void *to, void *buf, size_t size) 279d3d1af6fSAlexey Budankov { 280ef781128SAlexey Budankov struct record_aio *aio = to; 281ef781128SAlexey Budankov 282ef781128SAlexey Budankov /* 283547740f7SJiri Olsa * map->core.base data pointed by buf is copied into free map->aio.data[] buffer 284ef781128SAlexey Budankov * to release space in the kernel buffer as fast as possible, calling 285ef781128SAlexey Budankov * perf_mmap__consume() from perf_mmap__push() function. 286ef781128SAlexey Budankov * 287ef781128SAlexey Budankov * That lets the kernel to proceed with storing more profiling data into 288ef781128SAlexey Budankov * the kernel buffer earlier than other per-cpu kernel buffers are handled. 289ef781128SAlexey Budankov * 290ef781128SAlexey Budankov * Coping can be done in two steps in case the chunk of profiling data 291ef781128SAlexey Budankov * crosses the upper bound of the kernel buffer. In this case we first move 292ef781128SAlexey Budankov * part of data from map->start till the upper bound and then the reminder 293ef781128SAlexey Budankov * from the beginning of the kernel buffer till the end of the data chunk. 294ef781128SAlexey Budankov */ 295ef781128SAlexey Budankov 296ef781128SAlexey Budankov if (record__comp_enabled(aio->rec)) { 297ef781128SAlexey Budankov size = zstd_compress(aio->rec->session, aio->data + aio->size, 298bf59b305SJiri Olsa mmap__mmap_len(map) - aio->size, 299ef781128SAlexey Budankov buf, size); 300ef781128SAlexey Budankov } else { 301ef781128SAlexey Budankov memcpy(aio->data + aio->size, buf, size); 302ef781128SAlexey Budankov } 303ef781128SAlexey Budankov 304ef781128SAlexey Budankov if (!aio->size) { 305ef781128SAlexey Budankov /* 306ef781128SAlexey Budankov * Increment map->refcount to guard map->aio.data[] buffer 307ef781128SAlexey Budankov * from premature deallocation because map object can be 308ef781128SAlexey Budankov * released earlier than aio write request started on 309ef781128SAlexey Budankov * map->aio.data[] buffer is complete. 310ef781128SAlexey Budankov * 311ef781128SAlexey Budankov * perf_mmap__put() is done at record__aio_complete() 312ef781128SAlexey Budankov * after started aio request completion or at record__aio_push() 313ef781128SAlexey Budankov * if the request failed to start. 314ef781128SAlexey Budankov */ 315e75710f0SJiri Olsa perf_mmap__get(&map->core); 316ef781128SAlexey Budankov } 317ef781128SAlexey Budankov 318ef781128SAlexey Budankov aio->size += size; 319ef781128SAlexey Budankov 320ef781128SAlexey Budankov return size; 321ef781128SAlexey Budankov } 322ef781128SAlexey Budankov 323a5830532SJiri Olsa static int record__aio_push(struct record *rec, struct mmap *map, off_t *off) 324ef781128SAlexey Budankov { 325ef781128SAlexey Budankov int ret, idx; 326ef781128SAlexey Budankov int trace_fd = rec->session->data->file.fd; 327ef781128SAlexey Budankov struct record_aio aio = { .rec = rec, .size = 0 }; 328ef781128SAlexey Budankov 329ef781128SAlexey Budankov /* 330ef781128SAlexey Budankov * Call record__aio_sync() to wait till map->aio.data[] buffer 331ef781128SAlexey Budankov * becomes available after previous aio write operation. 332ef781128SAlexey Budankov */ 333ef781128SAlexey Budankov 334ef781128SAlexey Budankov idx = record__aio_sync(map, false); 335ef781128SAlexey Budankov aio.data = map->aio.data[idx]; 336ef781128SAlexey Budankov ret = perf_mmap__push(map, &aio, record__aio_pushfn); 337ef781128SAlexey Budankov if (ret != 0) /* ret > 0 - no data, ret < 0 - error */ 338ef781128SAlexey Budankov return ret; 339d3d1af6fSAlexey Budankov 340d3d1af6fSAlexey Budankov rec->samples++; 341ef781128SAlexey Budankov ret = record__aio_write(&(map->aio.cblocks[idx]), trace_fd, aio.data, aio.size, *off); 342d3d1af6fSAlexey Budankov if (!ret) { 343ef781128SAlexey Budankov *off += aio.size; 344ef781128SAlexey Budankov rec->bytes_written += aio.size; 345d3d1af6fSAlexey Budankov if (switch_output_size(rec)) 346d3d1af6fSAlexey Budankov trigger_hit(&switch_output_trigger); 347ef781128SAlexey Budankov } else { 348ef781128SAlexey Budankov /* 349ef781128SAlexey Budankov * Decrement map->refcount incremented in record__aio_pushfn() 350ef781128SAlexey Budankov * back if record__aio_write() operation failed to start, otherwise 351ef781128SAlexey Budankov * map->refcount is decremented in record__aio_complete() after 352ef781128SAlexey Budankov * aio write operation finishes successfully. 353ef781128SAlexey Budankov */ 35480e53d11SJiri Olsa perf_mmap__put(&map->core); 355d3d1af6fSAlexey Budankov } 356d3d1af6fSAlexey Budankov 357d3d1af6fSAlexey Budankov return ret; 358d3d1af6fSAlexey Budankov } 359d3d1af6fSAlexey Budankov 360d3d1af6fSAlexey Budankov static off_t record__aio_get_pos(int trace_fd) 361d3d1af6fSAlexey Budankov { 362d3d1af6fSAlexey Budankov return lseek(trace_fd, 0, SEEK_CUR); 363d3d1af6fSAlexey Budankov } 364d3d1af6fSAlexey Budankov 365d3d1af6fSAlexey Budankov static void record__aio_set_pos(int trace_fd, off_t pos) 366d3d1af6fSAlexey Budankov { 367d3d1af6fSAlexey Budankov lseek(trace_fd, pos, SEEK_SET); 368d3d1af6fSAlexey Budankov } 369d3d1af6fSAlexey Budankov 370d3d1af6fSAlexey Budankov static void record__aio_mmap_read_sync(struct record *rec) 371d3d1af6fSAlexey Budankov { 372d3d1af6fSAlexey Budankov int i; 37363503dbaSJiri Olsa struct evlist *evlist = rec->evlist; 374a5830532SJiri Olsa struct mmap *maps = evlist->mmap; 375d3d1af6fSAlexey Budankov 376ef781128SAlexey Budankov if (!record__aio_enabled(rec)) 377d3d1af6fSAlexey Budankov return; 378d3d1af6fSAlexey Budankov 379c976ee11SJiri Olsa for (i = 0; i < evlist->core.nr_mmaps; i++) { 380a5830532SJiri Olsa struct mmap *map = &maps[i]; 381d3d1af6fSAlexey Budankov 382547740f7SJiri Olsa if (map->core.base) 38393f20c0fSAlexey Budankov record__aio_sync(map, true); 384d3d1af6fSAlexey Budankov } 385d3d1af6fSAlexey Budankov } 386d3d1af6fSAlexey Budankov 387d3d1af6fSAlexey Budankov static int nr_cblocks_default = 1; 38893f20c0fSAlexey Budankov static int nr_cblocks_max = 4; 389d3d1af6fSAlexey Budankov 390d3d1af6fSAlexey Budankov static int record__aio_parse(const struct option *opt, 39193f20c0fSAlexey Budankov const char *str, 392d3d1af6fSAlexey Budankov int unset) 393d3d1af6fSAlexey Budankov { 394d3d1af6fSAlexey Budankov struct record_opts *opts = (struct record_opts *)opt->value; 395d3d1af6fSAlexey Budankov 39693f20c0fSAlexey Budankov if (unset) { 397d3d1af6fSAlexey Budankov opts->nr_cblocks = 0; 39893f20c0fSAlexey Budankov } else { 39993f20c0fSAlexey Budankov if (str) 40093f20c0fSAlexey Budankov opts->nr_cblocks = strtol(str, NULL, 0); 40193f20c0fSAlexey Budankov if (!opts->nr_cblocks) 402d3d1af6fSAlexey Budankov opts->nr_cblocks = nr_cblocks_default; 40393f20c0fSAlexey Budankov } 404d3d1af6fSAlexey Budankov 405d3d1af6fSAlexey Budankov return 0; 406d3d1af6fSAlexey Budankov } 407d3d1af6fSAlexey Budankov #else /* HAVE_AIO_SUPPORT */ 40893f20c0fSAlexey Budankov static int nr_cblocks_max = 0; 40993f20c0fSAlexey Budankov 410a5830532SJiri Olsa static int record__aio_push(struct record *rec __maybe_unused, struct mmap *map __maybe_unused, 411ef781128SAlexey Budankov off_t *off __maybe_unused) 412d3d1af6fSAlexey Budankov { 413d3d1af6fSAlexey Budankov return -1; 414d3d1af6fSAlexey Budankov } 415d3d1af6fSAlexey Budankov 416d3d1af6fSAlexey Budankov static off_t record__aio_get_pos(int trace_fd __maybe_unused) 417d3d1af6fSAlexey Budankov { 418d3d1af6fSAlexey Budankov return -1; 419d3d1af6fSAlexey Budankov } 420d3d1af6fSAlexey Budankov 421d3d1af6fSAlexey Budankov static void record__aio_set_pos(int trace_fd __maybe_unused, off_t pos __maybe_unused) 422d3d1af6fSAlexey Budankov { 423d3d1af6fSAlexey Budankov } 424d3d1af6fSAlexey Budankov 425d3d1af6fSAlexey Budankov static void record__aio_mmap_read_sync(struct record *rec __maybe_unused) 426d3d1af6fSAlexey Budankov { 427d3d1af6fSAlexey Budankov } 428d3d1af6fSAlexey Budankov #endif 429d3d1af6fSAlexey Budankov 430d3d1af6fSAlexey Budankov static int record__aio_enabled(struct record *rec) 431d3d1af6fSAlexey Budankov { 432d3d1af6fSAlexey Budankov return rec->opts.nr_cblocks > 0; 433d3d1af6fSAlexey Budankov } 434d3d1af6fSAlexey Budankov 435470530bbSAlexey Budankov #define MMAP_FLUSH_DEFAULT 1 436470530bbSAlexey Budankov static int record__mmap_flush_parse(const struct option *opt, 437470530bbSAlexey Budankov const char *str, 438470530bbSAlexey Budankov int unset) 439470530bbSAlexey Budankov { 440470530bbSAlexey Budankov int flush_max; 441470530bbSAlexey Budankov struct record_opts *opts = (struct record_opts *)opt->value; 442470530bbSAlexey Budankov static struct parse_tag tags[] = { 443470530bbSAlexey Budankov { .tag = 'B', .mult = 1 }, 444470530bbSAlexey Budankov { .tag = 'K', .mult = 1 << 10 }, 445470530bbSAlexey Budankov { .tag = 'M', .mult = 1 << 20 }, 446470530bbSAlexey Budankov { .tag = 'G', .mult = 1 << 30 }, 447470530bbSAlexey Budankov { .tag = 0 }, 448470530bbSAlexey Budankov }; 449470530bbSAlexey Budankov 450470530bbSAlexey Budankov if (unset) 451470530bbSAlexey Budankov return 0; 452470530bbSAlexey Budankov 453470530bbSAlexey Budankov if (str) { 454470530bbSAlexey Budankov opts->mmap_flush = parse_tag_value(str, tags); 455470530bbSAlexey Budankov if (opts->mmap_flush == (int)-1) 456470530bbSAlexey Budankov opts->mmap_flush = strtol(str, NULL, 0); 457470530bbSAlexey Budankov } 458470530bbSAlexey Budankov 459470530bbSAlexey Budankov if (!opts->mmap_flush) 460470530bbSAlexey Budankov opts->mmap_flush = MMAP_FLUSH_DEFAULT; 461470530bbSAlexey Budankov 4629521b5f2SJiri Olsa flush_max = evlist__mmap_size(opts->mmap_pages); 463470530bbSAlexey Budankov flush_max /= 4; 464470530bbSAlexey Budankov if (opts->mmap_flush > flush_max) 465470530bbSAlexey Budankov opts->mmap_flush = flush_max; 466470530bbSAlexey Budankov 467470530bbSAlexey Budankov return 0; 468470530bbSAlexey Budankov } 469470530bbSAlexey Budankov 470504c1ad1SAlexey Budankov #ifdef HAVE_ZSTD_SUPPORT 471504c1ad1SAlexey Budankov static unsigned int comp_level_default = 1; 472504c1ad1SAlexey Budankov 473504c1ad1SAlexey Budankov static int record__parse_comp_level(const struct option *opt, const char *str, int unset) 474504c1ad1SAlexey Budankov { 475504c1ad1SAlexey Budankov struct record_opts *opts = opt->value; 476504c1ad1SAlexey Budankov 477504c1ad1SAlexey Budankov if (unset) { 478504c1ad1SAlexey Budankov opts->comp_level = 0; 479504c1ad1SAlexey Budankov } else { 480504c1ad1SAlexey Budankov if (str) 481504c1ad1SAlexey Budankov opts->comp_level = strtol(str, NULL, 0); 482504c1ad1SAlexey Budankov if (!opts->comp_level) 483504c1ad1SAlexey Budankov opts->comp_level = comp_level_default; 484504c1ad1SAlexey Budankov } 485504c1ad1SAlexey Budankov 486504c1ad1SAlexey Budankov return 0; 487504c1ad1SAlexey Budankov } 488504c1ad1SAlexey Budankov #endif 48951255a8aSAlexey Budankov static unsigned int comp_level_max = 22; 49051255a8aSAlexey Budankov 49142e1fd80SAlexey Budankov static int record__comp_enabled(struct record *rec) 49242e1fd80SAlexey Budankov { 49342e1fd80SAlexey Budankov return rec->opts.comp_level > 0; 49442e1fd80SAlexey Budankov } 49542e1fd80SAlexey Budankov 49645694aa7SArnaldo Carvalho de Melo static int process_synthesized_event(struct perf_tool *tool, 497d20deb64SArnaldo Carvalho de Melo union perf_event *event, 4981d037ca1SIrina Tirdea struct perf_sample *sample __maybe_unused, 4991d037ca1SIrina Tirdea struct machine *machine __maybe_unused) 500234fbbf5SArnaldo Carvalho de Melo { 5018c6f45a7SArnaldo Carvalho de Melo struct record *rec = container_of(tool, struct record, tool); 502ded2b8feSJiri Olsa return record__write(rec, NULL, event, event->header.size); 503234fbbf5SArnaldo Carvalho de Melo } 504234fbbf5SArnaldo Carvalho de Melo 505a5830532SJiri Olsa static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size) 506d37f1586SArnaldo Carvalho de Melo { 507d37f1586SArnaldo Carvalho de Melo struct record *rec = to; 508d37f1586SArnaldo Carvalho de Melo 5095d7f4116SAlexey Budankov if (record__comp_enabled(rec)) { 510bf59b305SJiri Olsa size = zstd_compress(rec->session, map->data, mmap__mmap_len(map), bf, size); 5115d7f4116SAlexey Budankov bf = map->data; 5125d7f4116SAlexey Budankov } 5135d7f4116SAlexey Budankov 514d37f1586SArnaldo Carvalho de Melo rec->samples++; 515ded2b8feSJiri Olsa return record__write(rec, map, bf, size); 516d37f1586SArnaldo Carvalho de Melo } 517d37f1586SArnaldo Carvalho de Melo 5182dd6d8a1SAdrian Hunter static volatile int signr = -1; 5192dd6d8a1SAdrian Hunter static volatile int child_finished; 520c0bdc1c4SWang Nan 5212dd6d8a1SAdrian Hunter static void sig_handler(int sig) 5222dd6d8a1SAdrian Hunter { 5232dd6d8a1SAdrian Hunter if (sig == SIGCHLD) 5242dd6d8a1SAdrian Hunter child_finished = 1; 5252dd6d8a1SAdrian Hunter else 5262dd6d8a1SAdrian Hunter signr = sig; 5272dd6d8a1SAdrian Hunter 5282dd6d8a1SAdrian Hunter done = 1; 5292dd6d8a1SAdrian Hunter } 5302dd6d8a1SAdrian Hunter 531a074865eSWang Nan static void sigsegv_handler(int sig) 532a074865eSWang Nan { 533a074865eSWang Nan perf_hooks__recover(); 534a074865eSWang Nan sighandler_dump_stack(sig); 535a074865eSWang Nan } 536a074865eSWang Nan 5372dd6d8a1SAdrian Hunter static void record__sig_exit(void) 5382dd6d8a1SAdrian Hunter { 5392dd6d8a1SAdrian Hunter if (signr == -1) 5402dd6d8a1SAdrian Hunter return; 5412dd6d8a1SAdrian Hunter 5422dd6d8a1SAdrian Hunter signal(signr, SIG_DFL); 5432dd6d8a1SAdrian Hunter raise(signr); 5442dd6d8a1SAdrian Hunter } 5452dd6d8a1SAdrian Hunter 546e31f0d01SAdrian Hunter #ifdef HAVE_AUXTRACE_SUPPORT 547e31f0d01SAdrian Hunter 548ef149c25SAdrian Hunter static int record__process_auxtrace(struct perf_tool *tool, 549a5830532SJiri Olsa struct mmap *map, 550ef149c25SAdrian Hunter union perf_event *event, void *data1, 551ef149c25SAdrian Hunter size_t len1, void *data2, size_t len2) 552ef149c25SAdrian Hunter { 553ef149c25SAdrian Hunter struct record *rec = container_of(tool, struct record, tool); 5548ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 555ef149c25SAdrian Hunter size_t padding; 556ef149c25SAdrian Hunter u8 pad[8] = {0}; 557ef149c25SAdrian Hunter 55846e201efSAdrian Hunter if (!perf_data__is_pipe(data) && perf_data__is_single_file(data)) { 55999fa2984SAdrian Hunter off_t file_offset; 5608ceb41d7SJiri Olsa int fd = perf_data__fd(data); 56199fa2984SAdrian Hunter int err; 56299fa2984SAdrian Hunter 56399fa2984SAdrian Hunter file_offset = lseek(fd, 0, SEEK_CUR); 56499fa2984SAdrian Hunter if (file_offset == -1) 56599fa2984SAdrian Hunter return -1; 56699fa2984SAdrian Hunter err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index, 56799fa2984SAdrian Hunter event, file_offset); 56899fa2984SAdrian Hunter if (err) 56999fa2984SAdrian Hunter return err; 57099fa2984SAdrian Hunter } 57199fa2984SAdrian Hunter 572ef149c25SAdrian Hunter /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */ 573ef149c25SAdrian Hunter padding = (len1 + len2) & 7; 574ef149c25SAdrian Hunter if (padding) 575ef149c25SAdrian Hunter padding = 8 - padding; 576ef149c25SAdrian Hunter 577ded2b8feSJiri Olsa record__write(rec, map, event, event->header.size); 578ded2b8feSJiri Olsa record__write(rec, map, data1, len1); 579ef149c25SAdrian Hunter if (len2) 580ded2b8feSJiri Olsa record__write(rec, map, data2, len2); 581ded2b8feSJiri Olsa record__write(rec, map, &pad, padding); 582ef149c25SAdrian Hunter 583ef149c25SAdrian Hunter return 0; 584ef149c25SAdrian Hunter } 585ef149c25SAdrian Hunter 586ef149c25SAdrian Hunter static int record__auxtrace_mmap_read(struct record *rec, 587a5830532SJiri Olsa struct mmap *map) 588ef149c25SAdrian Hunter { 589ef149c25SAdrian Hunter int ret; 590ef149c25SAdrian Hunter 591e035f4caSJiri Olsa ret = auxtrace_mmap__read(map, rec->itr, &rec->tool, 592ef149c25SAdrian Hunter record__process_auxtrace); 593ef149c25SAdrian Hunter if (ret < 0) 594ef149c25SAdrian Hunter return ret; 595ef149c25SAdrian Hunter 596ef149c25SAdrian Hunter if (ret) 597ef149c25SAdrian Hunter rec->samples++; 598ef149c25SAdrian Hunter 599ef149c25SAdrian Hunter return 0; 600ef149c25SAdrian Hunter } 601ef149c25SAdrian Hunter 6022dd6d8a1SAdrian Hunter static int record__auxtrace_mmap_read_snapshot(struct record *rec, 603a5830532SJiri Olsa struct mmap *map) 6042dd6d8a1SAdrian Hunter { 6052dd6d8a1SAdrian Hunter int ret; 6062dd6d8a1SAdrian Hunter 607e035f4caSJiri Olsa ret = auxtrace_mmap__read_snapshot(map, rec->itr, &rec->tool, 6082dd6d8a1SAdrian Hunter record__process_auxtrace, 6092dd6d8a1SAdrian Hunter rec->opts.auxtrace_snapshot_size); 6102dd6d8a1SAdrian Hunter if (ret < 0) 6112dd6d8a1SAdrian Hunter return ret; 6122dd6d8a1SAdrian Hunter 6132dd6d8a1SAdrian Hunter if (ret) 6142dd6d8a1SAdrian Hunter rec->samples++; 6152dd6d8a1SAdrian Hunter 6162dd6d8a1SAdrian Hunter return 0; 6172dd6d8a1SAdrian Hunter } 6182dd6d8a1SAdrian Hunter 6192dd6d8a1SAdrian Hunter static int record__auxtrace_read_snapshot_all(struct record *rec) 6202dd6d8a1SAdrian Hunter { 6212dd6d8a1SAdrian Hunter int i; 6222dd6d8a1SAdrian Hunter int rc = 0; 6232dd6d8a1SAdrian Hunter 624c976ee11SJiri Olsa for (i = 0; i < rec->evlist->core.nr_mmaps; i++) { 625a5830532SJiri Olsa struct mmap *map = &rec->evlist->mmap[i]; 6262dd6d8a1SAdrian Hunter 627e035f4caSJiri Olsa if (!map->auxtrace_mmap.base) 6282dd6d8a1SAdrian Hunter continue; 6292dd6d8a1SAdrian Hunter 630e035f4caSJiri Olsa if (record__auxtrace_mmap_read_snapshot(rec, map) != 0) { 6312dd6d8a1SAdrian Hunter rc = -1; 6322dd6d8a1SAdrian Hunter goto out; 6332dd6d8a1SAdrian Hunter } 6342dd6d8a1SAdrian Hunter } 6352dd6d8a1SAdrian Hunter out: 6362dd6d8a1SAdrian Hunter return rc; 6372dd6d8a1SAdrian Hunter } 6382dd6d8a1SAdrian Hunter 639ce7b0e42SAlexander Shishkin static void record__read_auxtrace_snapshot(struct record *rec, bool on_exit) 6402dd6d8a1SAdrian Hunter { 6412dd6d8a1SAdrian Hunter pr_debug("Recording AUX area tracing snapshot\n"); 6422dd6d8a1SAdrian Hunter if (record__auxtrace_read_snapshot_all(rec) < 0) { 6435f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 6442dd6d8a1SAdrian Hunter } else { 645ce7b0e42SAlexander Shishkin if (auxtrace_record__snapshot_finish(rec->itr, on_exit)) 6465f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 6475f9cf599SWang Nan else 6485f9cf599SWang Nan trigger_ready(&auxtrace_snapshot_trigger); 6492dd6d8a1SAdrian Hunter } 6502dd6d8a1SAdrian Hunter } 6512dd6d8a1SAdrian Hunter 652ce7b0e42SAlexander Shishkin static int record__auxtrace_snapshot_exit(struct record *rec) 653ce7b0e42SAlexander Shishkin { 654ce7b0e42SAlexander Shishkin if (trigger_is_error(&auxtrace_snapshot_trigger)) 655ce7b0e42SAlexander Shishkin return 0; 656ce7b0e42SAlexander Shishkin 657ce7b0e42SAlexander Shishkin if (!auxtrace_record__snapshot_started && 658ce7b0e42SAlexander Shishkin auxtrace_record__snapshot_start(rec->itr)) 659ce7b0e42SAlexander Shishkin return -1; 660ce7b0e42SAlexander Shishkin 661ce7b0e42SAlexander Shishkin record__read_auxtrace_snapshot(rec, true); 662ce7b0e42SAlexander Shishkin if (trigger_is_error(&auxtrace_snapshot_trigger)) 663ce7b0e42SAlexander Shishkin return -1; 664ce7b0e42SAlexander Shishkin 665ce7b0e42SAlexander Shishkin return 0; 666ce7b0e42SAlexander Shishkin } 667ce7b0e42SAlexander Shishkin 6684b5ea3bdSAdrian Hunter static int record__auxtrace_init(struct record *rec) 6694b5ea3bdSAdrian Hunter { 6704b5ea3bdSAdrian Hunter int err; 6714b5ea3bdSAdrian Hunter 6724b5ea3bdSAdrian Hunter if (!rec->itr) { 6734b5ea3bdSAdrian Hunter rec->itr = auxtrace_record__init(rec->evlist, &err); 6744b5ea3bdSAdrian Hunter if (err) 6754b5ea3bdSAdrian Hunter return err; 6764b5ea3bdSAdrian Hunter } 6774b5ea3bdSAdrian Hunter 6784b5ea3bdSAdrian Hunter err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts, 6794b5ea3bdSAdrian Hunter rec->opts.auxtrace_snapshot_opts); 6804b5ea3bdSAdrian Hunter if (err) 6814b5ea3bdSAdrian Hunter return err; 6824b5ea3bdSAdrian Hunter 683c0a6de06SAdrian Hunter err = auxtrace_parse_sample_options(rec->itr, rec->evlist, &rec->opts, 684c0a6de06SAdrian Hunter rec->opts.auxtrace_sample_opts); 685c0a6de06SAdrian Hunter if (err) 686c0a6de06SAdrian Hunter return err; 687c0a6de06SAdrian Hunter 6884b5ea3bdSAdrian Hunter return auxtrace_parse_filters(rec->evlist); 6894b5ea3bdSAdrian Hunter } 6904b5ea3bdSAdrian Hunter 691e31f0d01SAdrian Hunter #else 692e31f0d01SAdrian Hunter 693e31f0d01SAdrian Hunter static inline 694e31f0d01SAdrian Hunter int record__auxtrace_mmap_read(struct record *rec __maybe_unused, 695a5830532SJiri Olsa struct mmap *map __maybe_unused) 696e31f0d01SAdrian Hunter { 697e31f0d01SAdrian Hunter return 0; 698e31f0d01SAdrian Hunter } 699e31f0d01SAdrian Hunter 7002dd6d8a1SAdrian Hunter static inline 701ce7b0e42SAlexander Shishkin void record__read_auxtrace_snapshot(struct record *rec __maybe_unused, 702ce7b0e42SAlexander Shishkin bool on_exit __maybe_unused) 7032dd6d8a1SAdrian Hunter { 7042dd6d8a1SAdrian Hunter } 7052dd6d8a1SAdrian Hunter 7062dd6d8a1SAdrian Hunter static inline 7072dd6d8a1SAdrian Hunter int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused) 7082dd6d8a1SAdrian Hunter { 7092dd6d8a1SAdrian Hunter return 0; 7102dd6d8a1SAdrian Hunter } 7112dd6d8a1SAdrian Hunter 712ce7b0e42SAlexander Shishkin static inline 713ce7b0e42SAlexander Shishkin int record__auxtrace_snapshot_exit(struct record *rec __maybe_unused) 714ce7b0e42SAlexander Shishkin { 715ce7b0e42SAlexander Shishkin return 0; 716ce7b0e42SAlexander Shishkin } 717ce7b0e42SAlexander Shishkin 7184b5ea3bdSAdrian Hunter static int record__auxtrace_init(struct record *rec __maybe_unused) 7194b5ea3bdSAdrian Hunter { 7204b5ea3bdSAdrian Hunter return 0; 7214b5ea3bdSAdrian Hunter } 7224b5ea3bdSAdrian Hunter 723e31f0d01SAdrian Hunter #endif 724e31f0d01SAdrian Hunter 725eeb399b5SAdrian Hunter static bool record__kcore_readable(struct machine *machine) 726eeb399b5SAdrian Hunter { 727eeb399b5SAdrian Hunter char kcore[PATH_MAX]; 728eeb399b5SAdrian Hunter int fd; 729eeb399b5SAdrian Hunter 730eeb399b5SAdrian Hunter scnprintf(kcore, sizeof(kcore), "%s/proc/kcore", machine->root_dir); 731eeb399b5SAdrian Hunter 732eeb399b5SAdrian Hunter fd = open(kcore, O_RDONLY); 733eeb399b5SAdrian Hunter if (fd < 0) 734eeb399b5SAdrian Hunter return false; 735eeb399b5SAdrian Hunter 736eeb399b5SAdrian Hunter close(fd); 737eeb399b5SAdrian Hunter 738eeb399b5SAdrian Hunter return true; 739eeb399b5SAdrian Hunter } 740eeb399b5SAdrian Hunter 741eeb399b5SAdrian Hunter static int record__kcore_copy(struct machine *machine, struct perf_data *data) 742eeb399b5SAdrian Hunter { 743eeb399b5SAdrian Hunter char from_dir[PATH_MAX]; 744eeb399b5SAdrian Hunter char kcore_dir[PATH_MAX]; 745eeb399b5SAdrian Hunter int ret; 746eeb399b5SAdrian Hunter 747eeb399b5SAdrian Hunter snprintf(from_dir, sizeof(from_dir), "%s/proc", machine->root_dir); 748eeb399b5SAdrian Hunter 749eeb399b5SAdrian Hunter ret = perf_data__make_kcore_dir(data, kcore_dir, sizeof(kcore_dir)); 750eeb399b5SAdrian Hunter if (ret) 751eeb399b5SAdrian Hunter return ret; 752eeb399b5SAdrian Hunter 753eeb399b5SAdrian Hunter return kcore_copy(from_dir, kcore_dir); 754eeb399b5SAdrian Hunter } 755eeb399b5SAdrian Hunter 756cda57a8cSWang Nan static int record__mmap_evlist(struct record *rec, 75763503dbaSJiri Olsa struct evlist *evlist) 758cda57a8cSWang Nan { 759cda57a8cSWang Nan struct record_opts *opts = &rec->opts; 760c0a6de06SAdrian Hunter bool auxtrace_overwrite = opts->auxtrace_snapshot_mode || 761c0a6de06SAdrian Hunter opts->auxtrace_sample_mode; 762cda57a8cSWang Nan char msg[512]; 763cda57a8cSWang Nan 764f13de660SAlexey Budankov if (opts->affinity != PERF_AFFINITY_SYS) 765f13de660SAlexey Budankov cpu__setup_cpunode_map(); 766f13de660SAlexey Budankov 7679521b5f2SJiri Olsa if (evlist__mmap_ex(evlist, opts->mmap_pages, 768cda57a8cSWang Nan opts->auxtrace_mmap_pages, 769c0a6de06SAdrian Hunter auxtrace_overwrite, 770470530bbSAlexey Budankov opts->nr_cblocks, opts->affinity, 77151255a8aSAlexey Budankov opts->mmap_flush, opts->comp_level) < 0) { 772cda57a8cSWang Nan if (errno == EPERM) { 773cda57a8cSWang Nan pr_err("Permission error mapping pages.\n" 774cda57a8cSWang Nan "Consider increasing " 775cda57a8cSWang Nan "/proc/sys/kernel/perf_event_mlock_kb,\n" 776cda57a8cSWang Nan "or try again with a smaller value of -m/--mmap_pages.\n" 777cda57a8cSWang Nan "(current value: %u,%u)\n", 778cda57a8cSWang Nan opts->mmap_pages, opts->auxtrace_mmap_pages); 779cda57a8cSWang Nan return -errno; 780cda57a8cSWang Nan } else { 781cda57a8cSWang Nan pr_err("failed to mmap with %d (%s)\n", errno, 782c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, msg, sizeof(msg))); 783cda57a8cSWang Nan if (errno) 784cda57a8cSWang Nan return -errno; 785cda57a8cSWang Nan else 786cda57a8cSWang Nan return -EINVAL; 787cda57a8cSWang Nan } 788cda57a8cSWang Nan } 789cda57a8cSWang Nan return 0; 790cda57a8cSWang Nan } 791cda57a8cSWang Nan 792cda57a8cSWang Nan static int record__mmap(struct record *rec) 793cda57a8cSWang Nan { 794cda57a8cSWang Nan return record__mmap_evlist(rec, rec->evlist); 795cda57a8cSWang Nan } 796cda57a8cSWang Nan 7978c6f45a7SArnaldo Carvalho de Melo static int record__open(struct record *rec) 798dd7927f4SArnaldo Carvalho de Melo { 799d6195a6aSArnaldo Carvalho de Melo char msg[BUFSIZ]; 80032dcd021SJiri Olsa struct evsel *pos; 80163503dbaSJiri Olsa struct evlist *evlist = rec->evlist; 802d20deb64SArnaldo Carvalho de Melo struct perf_session *session = rec->session; 803b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &rec->opts; 8048d3eca20SDavid Ahern int rc = 0; 805dd7927f4SArnaldo Carvalho de Melo 806d3dbf43cSArnaldo Carvalho de Melo /* 807d3dbf43cSArnaldo Carvalho de Melo * For initial_delay we need to add a dummy event so that we can track 808d3dbf43cSArnaldo Carvalho de Melo * PERF_RECORD_MMAP while we wait for the initial delay to enable the 809d3dbf43cSArnaldo Carvalho de Melo * real events, the ones asked by the user. 810d3dbf43cSArnaldo Carvalho de Melo */ 811d3dbf43cSArnaldo Carvalho de Melo if (opts->initial_delay) { 812d3dbf43cSArnaldo Carvalho de Melo if (perf_evlist__add_dummy(evlist)) 813d3dbf43cSArnaldo Carvalho de Melo return -ENOMEM; 814d3dbf43cSArnaldo Carvalho de Melo 815515dbe48SJiri Olsa pos = evlist__first(evlist); 816d3dbf43cSArnaldo Carvalho de Melo pos->tracking = 0; 817515dbe48SJiri Olsa pos = evlist__last(evlist); 818d3dbf43cSArnaldo Carvalho de Melo pos->tracking = 1; 8191fc632ceSJiri Olsa pos->core.attr.enable_on_exec = 1; 820d3dbf43cSArnaldo Carvalho de Melo } 821d3dbf43cSArnaldo Carvalho de Melo 822e68ae9cfSArnaldo Carvalho de Melo perf_evlist__config(evlist, opts, &callchain_param); 823cac21425SJiri Olsa 824e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 8253da297a6SIngo Molnar try_again: 826af663bd0SJiri Olsa if (evsel__open(pos, pos->core.cpus, pos->core.threads) < 0) { 82756e52e85SArnaldo Carvalho de Melo if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { 828bb963e16SNamhyung Kim if (verbose > 0) 829c0a54341SArnaldo Carvalho de Melo ui__warning("%s\n", msg); 8303da297a6SIngo Molnar goto try_again; 8313da297a6SIngo Molnar } 832cf99ad14SAndi Kleen if ((errno == EINVAL || errno == EBADF) && 833cf99ad14SAndi Kleen pos->leader != pos && 834cf99ad14SAndi Kleen pos->weak_group) { 835*4804e011SAndi Kleen pos = perf_evlist__reset_weak_group(evlist, pos, true); 836cf99ad14SAndi Kleen goto try_again; 837cf99ad14SAndi Kleen } 83856e52e85SArnaldo Carvalho de Melo rc = -errno; 83956e52e85SArnaldo Carvalho de Melo perf_evsel__open_strerror(pos, &opts->target, 84056e52e85SArnaldo Carvalho de Melo errno, msg, sizeof(msg)); 84156e52e85SArnaldo Carvalho de Melo ui__error("%s\n", msg); 8428d3eca20SDavid Ahern goto out; 8437c6a1c65SPeter Zijlstra } 844bfd8f72cSAndi Kleen 845bfd8f72cSAndi Kleen pos->supported = true; 8467c6a1c65SPeter Zijlstra } 8477c6a1c65SPeter Zijlstra 848c8b567c8SArnaldo Carvalho de Melo if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(evlist)) { 849c8b567c8SArnaldo Carvalho de Melo pr_warning( 850c8b567c8SArnaldo Carvalho de Melo "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" 851c8b567c8SArnaldo Carvalho de Melo "check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\n\n" 852c8b567c8SArnaldo Carvalho de Melo "Samples in kernel functions may not be resolved if a suitable vmlinux\n" 853c8b567c8SArnaldo Carvalho de Melo "file is not found in the buildid cache or in the vmlinux path.\n\n" 854c8b567c8SArnaldo Carvalho de Melo "Samples in kernel modules won't be resolved at all.\n\n" 855c8b567c8SArnaldo Carvalho de Melo "If some relocation was applied (e.g. kexec) symbols may be misresolved\n" 856c8b567c8SArnaldo Carvalho de Melo "even with a suitable vmlinux or kallsyms file.\n\n"); 857c8b567c8SArnaldo Carvalho de Melo } 858c8b567c8SArnaldo Carvalho de Melo 85923d4aad4SArnaldo Carvalho de Melo if (perf_evlist__apply_filters(evlist, &pos)) { 86062d94b00SArnaldo Carvalho de Melo pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n", 86123d4aad4SArnaldo Carvalho de Melo pos->filter, perf_evsel__name(pos), errno, 862c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, msg, sizeof(msg))); 8638d3eca20SDavid Ahern rc = -1; 8648d3eca20SDavid Ahern goto out; 8650a102479SFrederic Weisbecker } 8660a102479SFrederic Weisbecker 867cda57a8cSWang Nan rc = record__mmap(rec); 868cda57a8cSWang Nan if (rc) 8698d3eca20SDavid Ahern goto out; 8700a27d7f9SArnaldo Carvalho de Melo 871a91e5431SArnaldo Carvalho de Melo session->evlist = evlist; 8727b56cce2SArnaldo Carvalho de Melo perf_session__set_id_hdr_size(session); 8738d3eca20SDavid Ahern out: 8748d3eca20SDavid Ahern return rc; 875a91e5431SArnaldo Carvalho de Melo } 876a91e5431SArnaldo Carvalho de Melo 877e3d59112SNamhyung Kim static int process_sample_event(struct perf_tool *tool, 878e3d59112SNamhyung Kim union perf_event *event, 879e3d59112SNamhyung Kim struct perf_sample *sample, 88032dcd021SJiri Olsa struct evsel *evsel, 881e3d59112SNamhyung Kim struct machine *machine) 882e3d59112SNamhyung Kim { 883e3d59112SNamhyung Kim struct record *rec = container_of(tool, struct record, tool); 884e3d59112SNamhyung Kim 88568588bafSJin Yao if (rec->evlist->first_sample_time == 0) 88668588bafSJin Yao rec->evlist->first_sample_time = sample->time; 887e3d59112SNamhyung Kim 88868588bafSJin Yao rec->evlist->last_sample_time = sample->time; 88968588bafSJin Yao 89068588bafSJin Yao if (rec->buildid_all) 89168588bafSJin Yao return 0; 89268588bafSJin Yao 89368588bafSJin Yao rec->samples++; 894e3d59112SNamhyung Kim return build_id__mark_dso_hit(tool, event, sample, evsel, machine); 895e3d59112SNamhyung Kim } 896e3d59112SNamhyung Kim 8978c6f45a7SArnaldo Carvalho de Melo static int process_buildids(struct record *rec) 8986122e4e4SArnaldo Carvalho de Melo { 899f5fc1412SJiri Olsa struct perf_session *session = rec->session; 9006122e4e4SArnaldo Carvalho de Melo 90145112e89SJiri Olsa if (perf_data__size(&rec->data) == 0) 9029f591fd7SArnaldo Carvalho de Melo return 0; 9039f591fd7SArnaldo Carvalho de Melo 90400dc8657SNamhyung Kim /* 90500dc8657SNamhyung Kim * During this process, it'll load kernel map and replace the 90600dc8657SNamhyung Kim * dso->long_name to a real pathname it found. In this case 90700dc8657SNamhyung Kim * we prefer the vmlinux path like 90800dc8657SNamhyung Kim * /lib/modules/3.16.4/build/vmlinux 90900dc8657SNamhyung Kim * 91000dc8657SNamhyung Kim * rather than build-id path (in debug directory). 91100dc8657SNamhyung Kim * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551 91200dc8657SNamhyung Kim */ 91300dc8657SNamhyung Kim symbol_conf.ignore_vmlinux_buildid = true; 91400dc8657SNamhyung Kim 9156156681bSNamhyung Kim /* 9166156681bSNamhyung Kim * If --buildid-all is given, it marks all DSO regardless of hits, 91768588bafSJin Yao * so no need to process samples. But if timestamp_boundary is enabled, 91868588bafSJin Yao * it still needs to walk on all samples to get the timestamps of 91968588bafSJin Yao * first/last samples. 9206156681bSNamhyung Kim */ 92168588bafSJin Yao if (rec->buildid_all && !rec->timestamp_boundary) 9226156681bSNamhyung Kim rec->tool.sample = NULL; 9236156681bSNamhyung Kim 924b7b61cbeSArnaldo Carvalho de Melo return perf_session__process_events(session); 9256122e4e4SArnaldo Carvalho de Melo } 9266122e4e4SArnaldo Carvalho de Melo 9278115d60cSArnaldo Carvalho de Melo static void perf_event__synthesize_guest_os(struct machine *machine, void *data) 928a1645ce1SZhang, Yanmin { 929a1645ce1SZhang, Yanmin int err; 93045694aa7SArnaldo Carvalho de Melo struct perf_tool *tool = data; 931a1645ce1SZhang, Yanmin /* 932a1645ce1SZhang, Yanmin *As for guest kernel when processing subcommand record&report, 933a1645ce1SZhang, Yanmin *we arrange module mmap prior to guest kernel mmap and trigger 934a1645ce1SZhang, Yanmin *a preload dso because default guest module symbols are loaded 935a1645ce1SZhang, Yanmin *from guest kallsyms instead of /lib/modules/XXX/XXX. This 936a1645ce1SZhang, Yanmin *method is used to avoid symbol missing when the first addr is 937a1645ce1SZhang, Yanmin *in module instead of in guest kernel. 938a1645ce1SZhang, Yanmin */ 93945694aa7SArnaldo Carvalho de Melo err = perf_event__synthesize_modules(tool, process_synthesized_event, 940743eb868SArnaldo Carvalho de Melo machine); 941a1645ce1SZhang, Yanmin if (err < 0) 942a1645ce1SZhang, Yanmin pr_err("Couldn't record guest kernel [%d]'s reference" 94323346f21SArnaldo Carvalho de Melo " relocation symbol.\n", machine->pid); 944a1645ce1SZhang, Yanmin 945a1645ce1SZhang, Yanmin /* 946a1645ce1SZhang, Yanmin * We use _stext for guest kernel because guest kernel's /proc/kallsyms 947a1645ce1SZhang, Yanmin * have no _text sometimes. 948a1645ce1SZhang, Yanmin */ 94945694aa7SArnaldo Carvalho de Melo err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, 9500ae617beSAdrian Hunter machine); 951a1645ce1SZhang, Yanmin if (err < 0) 952a1645ce1SZhang, Yanmin pr_err("Couldn't record guest kernel [%d]'s reference" 95323346f21SArnaldo Carvalho de Melo " relocation symbol.\n", machine->pid); 954a1645ce1SZhang, Yanmin } 955a1645ce1SZhang, Yanmin 95698402807SFrederic Weisbecker static struct perf_event_header finished_round_event = { 95798402807SFrederic Weisbecker .size = sizeof(struct perf_event_header), 95898402807SFrederic Weisbecker .type = PERF_RECORD_FINISHED_ROUND, 95998402807SFrederic Weisbecker }; 96098402807SFrederic Weisbecker 961a5830532SJiri Olsa static void record__adjust_affinity(struct record *rec, struct mmap *map) 962f13de660SAlexey Budankov { 963f13de660SAlexey Budankov if (rec->opts.affinity != PERF_AFFINITY_SYS && 964f13de660SAlexey Budankov !CPU_EQUAL(&rec->affinity_mask, &map->affinity_mask)) { 965f13de660SAlexey Budankov CPU_ZERO(&rec->affinity_mask); 966f13de660SAlexey Budankov CPU_OR(&rec->affinity_mask, &rec->affinity_mask, &map->affinity_mask); 967f13de660SAlexey Budankov sched_setaffinity(0, sizeof(rec->affinity_mask), &rec->affinity_mask); 968f13de660SAlexey Budankov } 969f13de660SAlexey Budankov } 970f13de660SAlexey Budankov 9715d7f4116SAlexey Budankov static size_t process_comp_header(void *record, size_t increment) 9725d7f4116SAlexey Budankov { 97372932371SJiri Olsa struct perf_record_compressed *event = record; 9745d7f4116SAlexey Budankov size_t size = sizeof(*event); 9755d7f4116SAlexey Budankov 9765d7f4116SAlexey Budankov if (increment) { 9775d7f4116SAlexey Budankov event->header.size += increment; 9785d7f4116SAlexey Budankov return increment; 9795d7f4116SAlexey Budankov } 9805d7f4116SAlexey Budankov 9815d7f4116SAlexey Budankov event->header.type = PERF_RECORD_COMPRESSED; 9825d7f4116SAlexey Budankov event->header.size = size; 9835d7f4116SAlexey Budankov 9845d7f4116SAlexey Budankov return size; 9855d7f4116SAlexey Budankov } 9865d7f4116SAlexey Budankov 9875d7f4116SAlexey Budankov static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_size, 9885d7f4116SAlexey Budankov void *src, size_t src_size) 9895d7f4116SAlexey Budankov { 9905d7f4116SAlexey Budankov size_t compressed; 99172932371SJiri Olsa size_t max_record_size = PERF_SAMPLE_MAX_SIZE - sizeof(struct perf_record_compressed) - 1; 9925d7f4116SAlexey Budankov 9935d7f4116SAlexey Budankov compressed = zstd_compress_stream_to_records(&session->zstd_data, dst, dst_size, src, src_size, 9945d7f4116SAlexey Budankov max_record_size, process_comp_header); 9955d7f4116SAlexey Budankov 9965d7f4116SAlexey Budankov session->bytes_transferred += src_size; 9975d7f4116SAlexey Budankov session->bytes_compressed += compressed; 9985d7f4116SAlexey Budankov 9995d7f4116SAlexey Budankov return compressed; 10005d7f4116SAlexey Budankov } 10015d7f4116SAlexey Budankov 100263503dbaSJiri Olsa static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, 1003470530bbSAlexey Budankov bool overwrite, bool synch) 100498402807SFrederic Weisbecker { 1005dcabb507SJiri Olsa u64 bytes_written = rec->bytes_written; 10060e2e63ddSPeter Zijlstra int i; 10078d3eca20SDavid Ahern int rc = 0; 1008a5830532SJiri Olsa struct mmap *maps; 1009d3d1af6fSAlexey Budankov int trace_fd = rec->data.file.fd; 1010ef781128SAlexey Budankov off_t off = 0; 101198402807SFrederic Weisbecker 1012cb21686bSWang Nan if (!evlist) 1013cb21686bSWang Nan return 0; 1014ef149c25SAdrian Hunter 10150b72d69aSWang Nan maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; 1016a4ea0ec4SWang Nan if (!maps) 1017a4ea0ec4SWang Nan return 0; 1018cb21686bSWang Nan 10190b72d69aSWang Nan if (overwrite && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) 102054cc54deSWang Nan return 0; 102154cc54deSWang Nan 1022d3d1af6fSAlexey Budankov if (record__aio_enabled(rec)) 1023d3d1af6fSAlexey Budankov off = record__aio_get_pos(trace_fd); 1024d3d1af6fSAlexey Budankov 1025c976ee11SJiri Olsa for (i = 0; i < evlist->core.nr_mmaps; i++) { 1026470530bbSAlexey Budankov u64 flush = 0; 1027a5830532SJiri Olsa struct mmap *map = &maps[i]; 1028a4ea0ec4SWang Nan 1029547740f7SJiri Olsa if (map->core.base) { 1030f13de660SAlexey Budankov record__adjust_affinity(rec, map); 1031470530bbSAlexey Budankov if (synch) { 103265aa2e6bSJiri Olsa flush = map->core.flush; 103365aa2e6bSJiri Olsa map->core.flush = 1; 1034470530bbSAlexey Budankov } 1035d3d1af6fSAlexey Budankov if (!record__aio_enabled(rec)) { 1036ef781128SAlexey Budankov if (perf_mmap__push(map, rec, record__pushfn) < 0) { 1037470530bbSAlexey Budankov if (synch) 103865aa2e6bSJiri Olsa map->core.flush = flush; 10398d3eca20SDavid Ahern rc = -1; 10408d3eca20SDavid Ahern goto out; 10418d3eca20SDavid Ahern } 1042d3d1af6fSAlexey Budankov } else { 1043ef781128SAlexey Budankov if (record__aio_push(rec, map, &off) < 0) { 1044d3d1af6fSAlexey Budankov record__aio_set_pos(trace_fd, off); 1045470530bbSAlexey Budankov if (synch) 104665aa2e6bSJiri Olsa map->core.flush = flush; 1047d3d1af6fSAlexey Budankov rc = -1; 1048d3d1af6fSAlexey Budankov goto out; 1049d3d1af6fSAlexey Budankov } 1050d3d1af6fSAlexey Budankov } 1051470530bbSAlexey Budankov if (synch) 105265aa2e6bSJiri Olsa map->core.flush = flush; 10538d3eca20SDavid Ahern } 1054ef149c25SAdrian Hunter 1055e035f4caSJiri Olsa if (map->auxtrace_mmap.base && !rec->opts.auxtrace_snapshot_mode && 1056c0a6de06SAdrian Hunter !rec->opts.auxtrace_sample_mode && 1057e035f4caSJiri Olsa record__auxtrace_mmap_read(rec, map) != 0) { 1058ef149c25SAdrian Hunter rc = -1; 1059ef149c25SAdrian Hunter goto out; 1060ef149c25SAdrian Hunter } 106198402807SFrederic Weisbecker } 106298402807SFrederic Weisbecker 1063d3d1af6fSAlexey Budankov if (record__aio_enabled(rec)) 1064d3d1af6fSAlexey Budankov record__aio_set_pos(trace_fd, off); 1065d3d1af6fSAlexey Budankov 1066dcabb507SJiri Olsa /* 1067dcabb507SJiri Olsa * Mark the round finished in case we wrote 1068dcabb507SJiri Olsa * at least one event. 1069dcabb507SJiri Olsa */ 1070dcabb507SJiri Olsa if (bytes_written != rec->bytes_written) 1071ded2b8feSJiri Olsa rc = record__write(rec, NULL, &finished_round_event, sizeof(finished_round_event)); 10728d3eca20SDavid Ahern 10730b72d69aSWang Nan if (overwrite) 107454cc54deSWang Nan perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY); 10758d3eca20SDavid Ahern out: 10768d3eca20SDavid Ahern return rc; 107798402807SFrederic Weisbecker } 107898402807SFrederic Weisbecker 1079470530bbSAlexey Budankov static int record__mmap_read_all(struct record *rec, bool synch) 1080cb21686bSWang Nan { 1081cb21686bSWang Nan int err; 1082cb21686bSWang Nan 1083470530bbSAlexey Budankov err = record__mmap_read_evlist(rec, rec->evlist, false, synch); 1084cb21686bSWang Nan if (err) 1085cb21686bSWang Nan return err; 1086cb21686bSWang Nan 1087470530bbSAlexey Budankov return record__mmap_read_evlist(rec, rec->evlist, true, synch); 1088cb21686bSWang Nan } 1089cb21686bSWang Nan 10908c6f45a7SArnaldo Carvalho de Melo static void record__init_features(struct record *rec) 109157706abcSDavid Ahern { 109257706abcSDavid Ahern struct perf_session *session = rec->session; 109357706abcSDavid Ahern int feat; 109457706abcSDavid Ahern 109557706abcSDavid Ahern for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++) 109657706abcSDavid Ahern perf_header__set_feat(&session->header, feat); 109757706abcSDavid Ahern 109857706abcSDavid Ahern if (rec->no_buildid) 109957706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_BUILD_ID); 110057706abcSDavid Ahern 1101ce9036a6SJiri Olsa if (!have_tracepoints(&rec->evlist->core.entries)) 110257706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); 110357706abcSDavid Ahern 110457706abcSDavid Ahern if (!rec->opts.branch_stack) 110557706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 1106ef149c25SAdrian Hunter 1107ef149c25SAdrian Hunter if (!rec->opts.full_auxtrace) 1108ef149c25SAdrian Hunter perf_header__clear_feat(&session->header, HEADER_AUXTRACE); 1109ffa517adSJiri Olsa 1110cf790516SAlexey Budankov if (!(rec->opts.use_clockid && rec->opts.clockid_res_ns)) 1111cf790516SAlexey Budankov perf_header__clear_feat(&session->header, HEADER_CLOCKID); 1112cf790516SAlexey Budankov 1113258031c0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT); 111442e1fd80SAlexey Budankov if (!record__comp_enabled(rec)) 111542e1fd80SAlexey Budankov perf_header__clear_feat(&session->header, HEADER_COMPRESSED); 1116258031c0SJiri Olsa 1117ffa517adSJiri Olsa perf_header__clear_feat(&session->header, HEADER_STAT); 111857706abcSDavid Ahern } 111957706abcSDavid Ahern 1120e1ab48baSWang Nan static void 1121e1ab48baSWang Nan record__finish_output(struct record *rec) 1122e1ab48baSWang Nan { 11238ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 11248ceb41d7SJiri Olsa int fd = perf_data__fd(data); 1125e1ab48baSWang Nan 11268ceb41d7SJiri Olsa if (data->is_pipe) 1127e1ab48baSWang Nan return; 1128e1ab48baSWang Nan 1129e1ab48baSWang Nan rec->session->header.data_size += rec->bytes_written; 113045112e89SJiri Olsa data->file.size = lseek(perf_data__fd(data), 0, SEEK_CUR); 1131e1ab48baSWang Nan 1132e1ab48baSWang Nan if (!rec->no_buildid) { 1133e1ab48baSWang Nan process_buildids(rec); 1134e1ab48baSWang Nan 1135e1ab48baSWang Nan if (rec->buildid_all) 1136e1ab48baSWang Nan dsos__hit_all(rec->session); 1137e1ab48baSWang Nan } 1138e1ab48baSWang Nan perf_session__write_header(rec->session, rec->evlist, fd, true); 1139e1ab48baSWang Nan 1140e1ab48baSWang Nan return; 1141e1ab48baSWang Nan } 1142e1ab48baSWang Nan 11434ea648aeSWang Nan static int record__synthesize_workload(struct record *rec, bool tail) 1144be7b0c9eSWang Nan { 11459d6aae72SArnaldo Carvalho de Melo int err; 11469749b90eSJiri Olsa struct perf_thread_map *thread_map; 1147be7b0c9eSWang Nan 11484ea648aeSWang Nan if (rec->opts.tail_synthesize != tail) 11494ea648aeSWang Nan return 0; 11504ea648aeSWang Nan 11519d6aae72SArnaldo Carvalho de Melo thread_map = thread_map__new_by_tid(rec->evlist->workload.pid); 11529d6aae72SArnaldo Carvalho de Melo if (thread_map == NULL) 11539d6aae72SArnaldo Carvalho de Melo return -1; 11549d6aae72SArnaldo Carvalho de Melo 11559d6aae72SArnaldo Carvalho de Melo err = perf_event__synthesize_thread_map(&rec->tool, thread_map, 1156be7b0c9eSWang Nan process_synthesized_event, 1157be7b0c9eSWang Nan &rec->session->machines.host, 11583fcb10e4SMark Drayton rec->opts.sample_address); 11597836e52eSJiri Olsa perf_thread_map__put(thread_map); 11609d6aae72SArnaldo Carvalho de Melo return err; 1161be7b0c9eSWang Nan } 1162be7b0c9eSWang Nan 11634ea648aeSWang Nan static int record__synthesize(struct record *rec, bool tail); 11643c1cb7e3SWang Nan 1165ecfd7a9cSWang Nan static int 1166ecfd7a9cSWang Nan record__switch_output(struct record *rec, bool at_exit) 1167ecfd7a9cSWang Nan { 11688ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 1169ecfd7a9cSWang Nan int fd, err; 117003724b2eSAndi Kleen char *new_filename; 1171ecfd7a9cSWang Nan 1172ecfd7a9cSWang Nan /* Same Size: "2015122520103046"*/ 1173ecfd7a9cSWang Nan char timestamp[] = "InvalidTimestamp"; 1174ecfd7a9cSWang Nan 1175d3d1af6fSAlexey Budankov record__aio_mmap_read_sync(rec); 1176d3d1af6fSAlexey Budankov 11774ea648aeSWang Nan record__synthesize(rec, true); 11784ea648aeSWang Nan if (target__none(&rec->opts.target)) 11794ea648aeSWang Nan record__synthesize_workload(rec, true); 11804ea648aeSWang Nan 1181ecfd7a9cSWang Nan rec->samples = 0; 1182ecfd7a9cSWang Nan record__finish_output(rec); 1183ecfd7a9cSWang Nan err = fetch_current_timestamp(timestamp, sizeof(timestamp)); 1184ecfd7a9cSWang Nan if (err) { 1185ecfd7a9cSWang Nan pr_err("Failed to get current timestamp\n"); 1186ecfd7a9cSWang Nan return -EINVAL; 1187ecfd7a9cSWang Nan } 1188ecfd7a9cSWang Nan 11898ceb41d7SJiri Olsa fd = perf_data__switch(data, timestamp, 1190ecfd7a9cSWang Nan rec->session->header.data_offset, 119103724b2eSAndi Kleen at_exit, &new_filename); 1192ecfd7a9cSWang Nan if (fd >= 0 && !at_exit) { 1193ecfd7a9cSWang Nan rec->bytes_written = 0; 1194ecfd7a9cSWang Nan rec->session->header.data_size = 0; 1195ecfd7a9cSWang Nan } 1196ecfd7a9cSWang Nan 1197ecfd7a9cSWang Nan if (!quiet) 1198ecfd7a9cSWang Nan fprintf(stderr, "[ perf record: Dump %s.%s ]\n", 11992d4f2799SJiri Olsa data->path, timestamp); 12003c1cb7e3SWang Nan 120103724b2eSAndi Kleen if (rec->switch_output.num_files) { 120203724b2eSAndi Kleen int n = rec->switch_output.cur_file + 1; 120303724b2eSAndi Kleen 120403724b2eSAndi Kleen if (n >= rec->switch_output.num_files) 120503724b2eSAndi Kleen n = 0; 120603724b2eSAndi Kleen rec->switch_output.cur_file = n; 120703724b2eSAndi Kleen if (rec->switch_output.filenames[n]) { 120803724b2eSAndi Kleen remove(rec->switch_output.filenames[n]); 1209d8f9da24SArnaldo Carvalho de Melo zfree(&rec->switch_output.filenames[n]); 121003724b2eSAndi Kleen } 121103724b2eSAndi Kleen rec->switch_output.filenames[n] = new_filename; 121203724b2eSAndi Kleen } else { 121303724b2eSAndi Kleen free(new_filename); 121403724b2eSAndi Kleen } 121503724b2eSAndi Kleen 12163c1cb7e3SWang Nan /* Output tracking events */ 1217be7b0c9eSWang Nan if (!at_exit) { 12184ea648aeSWang Nan record__synthesize(rec, false); 12193c1cb7e3SWang Nan 1220be7b0c9eSWang Nan /* 1221be7b0c9eSWang Nan * In 'perf record --switch-output' without -a, 1222be7b0c9eSWang Nan * record__synthesize() in record__switch_output() won't 1223be7b0c9eSWang Nan * generate tracking events because there's no thread_map 1224be7b0c9eSWang Nan * in evlist. Which causes newly created perf.data doesn't 1225be7b0c9eSWang Nan * contain map and comm information. 1226be7b0c9eSWang Nan * Create a fake thread_map and directly call 1227be7b0c9eSWang Nan * perf_event__synthesize_thread_map() for those events. 1228be7b0c9eSWang Nan */ 1229be7b0c9eSWang Nan if (target__none(&rec->opts.target)) 12304ea648aeSWang Nan record__synthesize_workload(rec, false); 1231be7b0c9eSWang Nan } 1232ecfd7a9cSWang Nan return fd; 1233ecfd7a9cSWang Nan } 1234ecfd7a9cSWang Nan 1235f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno; 1236f33cbe72SArnaldo Carvalho de Melo 1237f33cbe72SArnaldo Carvalho de Melo /* 1238f33cbe72SArnaldo Carvalho de Melo * perf_evlist__prepare_workload will send a SIGUSR1 1239f33cbe72SArnaldo Carvalho de Melo * if the fork fails, since we asked by setting its 1240f33cbe72SArnaldo Carvalho de Melo * want_signal to true. 1241f33cbe72SArnaldo Carvalho de Melo */ 124245604710SNamhyung Kim static void workload_exec_failed_signal(int signo __maybe_unused, 124345604710SNamhyung Kim siginfo_t *info, 1244f33cbe72SArnaldo Carvalho de Melo void *ucontext __maybe_unused) 1245f33cbe72SArnaldo Carvalho de Melo { 1246f33cbe72SArnaldo Carvalho de Melo workload_exec_errno = info->si_value.sival_int; 1247f33cbe72SArnaldo Carvalho de Melo done = 1; 1248f33cbe72SArnaldo Carvalho de Melo child_finished = 1; 1249f33cbe72SArnaldo Carvalho de Melo } 1250f33cbe72SArnaldo Carvalho de Melo 12512dd6d8a1SAdrian Hunter static void snapshot_sig_handler(int sig); 1252bfacbe3bSJiri Olsa static void alarm_sig_handler(int sig); 12532dd6d8a1SAdrian Hunter 1254ee667f94SWang Nan static const struct perf_event_mmap_page * 125563503dbaSJiri Olsa perf_evlist__pick_pc(struct evlist *evlist) 1256ee667f94SWang Nan { 1257b2cb615dSWang Nan if (evlist) { 1258547740f7SJiri Olsa if (evlist->mmap && evlist->mmap[0].core.base) 1259547740f7SJiri Olsa return evlist->mmap[0].core.base; 1260547740f7SJiri Olsa if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].core.base) 1261547740f7SJiri Olsa return evlist->overwrite_mmap[0].core.base; 1262b2cb615dSWang Nan } 1263ee667f94SWang Nan return NULL; 1264ee667f94SWang Nan } 1265ee667f94SWang Nan 1266c45628b0SWang Nan static const struct perf_event_mmap_page *record__pick_pc(struct record *rec) 1267c45628b0SWang Nan { 1268ee667f94SWang Nan const struct perf_event_mmap_page *pc; 1269ee667f94SWang Nan 1270ee667f94SWang Nan pc = perf_evlist__pick_pc(rec->evlist); 1271ee667f94SWang Nan if (pc) 1272ee667f94SWang Nan return pc; 1273c45628b0SWang Nan return NULL; 1274c45628b0SWang Nan } 1275c45628b0SWang Nan 12764ea648aeSWang Nan static int record__synthesize(struct record *rec, bool tail) 1277c45c86ebSWang Nan { 1278c45c86ebSWang Nan struct perf_session *session = rec->session; 1279c45c86ebSWang Nan struct machine *machine = &session->machines.host; 12808ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 1281c45c86ebSWang Nan struct record_opts *opts = &rec->opts; 1282c45c86ebSWang Nan struct perf_tool *tool = &rec->tool; 12838ceb41d7SJiri Olsa int fd = perf_data__fd(data); 1284c45c86ebSWang Nan int err = 0; 1285c45c86ebSWang Nan 12864ea648aeSWang Nan if (rec->opts.tail_synthesize != tail) 12874ea648aeSWang Nan return 0; 12884ea648aeSWang Nan 12898ceb41d7SJiri Olsa if (data->is_pipe) { 1290a2015516SJiri Olsa /* 1291a2015516SJiri Olsa * We need to synthesize events first, because some 1292a2015516SJiri Olsa * features works on top of them (on report side). 1293a2015516SJiri Olsa */ 1294318ec184SJiri Olsa err = perf_event__synthesize_attrs(tool, rec->evlist, 1295c45c86ebSWang Nan process_synthesized_event); 1296c45c86ebSWang Nan if (err < 0) { 1297c45c86ebSWang Nan pr_err("Couldn't synthesize attrs.\n"); 1298c45c86ebSWang Nan goto out; 1299c45c86ebSWang Nan } 1300c45c86ebSWang Nan 1301a2015516SJiri Olsa err = perf_event__synthesize_features(tool, session, rec->evlist, 1302a2015516SJiri Olsa process_synthesized_event); 1303a2015516SJiri Olsa if (err < 0) { 1304a2015516SJiri Olsa pr_err("Couldn't synthesize features.\n"); 1305a2015516SJiri Olsa return err; 1306a2015516SJiri Olsa } 1307a2015516SJiri Olsa 1308ce9036a6SJiri Olsa if (have_tracepoints(&rec->evlist->core.entries)) { 1309c45c86ebSWang Nan /* 1310c45c86ebSWang Nan * FIXME err <= 0 here actually means that 1311c45c86ebSWang Nan * there were no tracepoints so its not really 1312c45c86ebSWang Nan * an error, just that we don't need to 1313c45c86ebSWang Nan * synthesize anything. We really have to 1314c45c86ebSWang Nan * return this more properly and also 1315c45c86ebSWang Nan * propagate errors that now are calling die() 1316c45c86ebSWang Nan */ 1317c45c86ebSWang Nan err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist, 1318c45c86ebSWang Nan process_synthesized_event); 1319c45c86ebSWang Nan if (err <= 0) { 1320c45c86ebSWang Nan pr_err("Couldn't record tracing data.\n"); 1321c45c86ebSWang Nan goto out; 1322c45c86ebSWang Nan } 1323c45c86ebSWang Nan rec->bytes_written += err; 1324c45c86ebSWang Nan } 1325c45c86ebSWang Nan } 1326c45c86ebSWang Nan 1327c45628b0SWang Nan err = perf_event__synth_time_conv(record__pick_pc(rec), tool, 132846bc29b9SAdrian Hunter process_synthesized_event, machine); 132946bc29b9SAdrian Hunter if (err) 133046bc29b9SAdrian Hunter goto out; 133146bc29b9SAdrian Hunter 1332c0a6de06SAdrian Hunter /* Synthesize id_index before auxtrace_info */ 1333c0a6de06SAdrian Hunter if (rec->opts.auxtrace_sample_mode) { 1334c0a6de06SAdrian Hunter err = perf_event__synthesize_id_index(tool, 1335c0a6de06SAdrian Hunter process_synthesized_event, 1336c0a6de06SAdrian Hunter session->evlist, machine); 1337c0a6de06SAdrian Hunter if (err) 1338c0a6de06SAdrian Hunter goto out; 1339c0a6de06SAdrian Hunter } 1340c0a6de06SAdrian Hunter 1341c45c86ebSWang Nan if (rec->opts.full_auxtrace) { 1342c45c86ebSWang Nan err = perf_event__synthesize_auxtrace_info(rec->itr, tool, 1343c45c86ebSWang Nan session, process_synthesized_event); 1344c45c86ebSWang Nan if (err) 1345c45c86ebSWang Nan goto out; 1346c45c86ebSWang Nan } 1347c45c86ebSWang Nan 13486c443954SArnaldo Carvalho de Melo if (!perf_evlist__exclude_kernel(rec->evlist)) { 1349c45c86ebSWang Nan err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, 1350c45c86ebSWang Nan machine); 1351c45c86ebSWang Nan WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n" 1352c45c86ebSWang Nan "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 1353c45c86ebSWang Nan "Check /proc/kallsyms permission or run as root.\n"); 1354c45c86ebSWang Nan 1355c45c86ebSWang Nan err = perf_event__synthesize_modules(tool, process_synthesized_event, 1356c45c86ebSWang Nan machine); 1357c45c86ebSWang Nan WARN_ONCE(err < 0, "Couldn't record kernel module information.\n" 1358c45c86ebSWang Nan "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 1359c45c86ebSWang Nan "Check /proc/modules permission or run as root.\n"); 13606c443954SArnaldo Carvalho de Melo } 1361c45c86ebSWang Nan 1362c45c86ebSWang Nan if (perf_guest) { 1363c45c86ebSWang Nan machines__process_guests(&session->machines, 1364c45c86ebSWang Nan perf_event__synthesize_guest_os, tool); 1365c45c86ebSWang Nan } 1366c45c86ebSWang Nan 1367bfd8f72cSAndi Kleen err = perf_event__synthesize_extra_attr(&rec->tool, 1368bfd8f72cSAndi Kleen rec->evlist, 1369bfd8f72cSAndi Kleen process_synthesized_event, 1370bfd8f72cSAndi Kleen data->is_pipe); 1371bfd8f72cSAndi Kleen if (err) 1372bfd8f72cSAndi Kleen goto out; 1373bfd8f72cSAndi Kleen 137403617c22SJiri Olsa err = perf_event__synthesize_thread_map2(&rec->tool, rec->evlist->core.threads, 1375373565d2SAndi Kleen process_synthesized_event, 1376373565d2SAndi Kleen NULL); 1377373565d2SAndi Kleen if (err < 0) { 1378373565d2SAndi Kleen pr_err("Couldn't synthesize thread map.\n"); 1379373565d2SAndi Kleen return err; 1380373565d2SAndi Kleen } 1381373565d2SAndi Kleen 1382f72f901dSJiri Olsa err = perf_event__synthesize_cpu_map(&rec->tool, rec->evlist->core.cpus, 1383373565d2SAndi Kleen process_synthesized_event, NULL); 1384373565d2SAndi Kleen if (err < 0) { 1385373565d2SAndi Kleen pr_err("Couldn't synthesize cpu map.\n"); 1386373565d2SAndi Kleen return err; 1387373565d2SAndi Kleen } 1388373565d2SAndi Kleen 1389e5416950SSong Liu err = perf_event__synthesize_bpf_events(session, process_synthesized_event, 13907b612e29SSong Liu machine, opts); 13917b612e29SSong Liu if (err < 0) 13927b612e29SSong Liu pr_warning("Couldn't synthesize bpf events.\n"); 13937b612e29SSong Liu 139403617c22SJiri Olsa err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->core.threads, 1395c45c86ebSWang Nan process_synthesized_event, opts->sample_address, 13963fcb10e4SMark Drayton 1); 1397c45c86ebSWang Nan out: 1398c45c86ebSWang Nan return err; 1399c45c86ebSWang Nan } 1400c45c86ebSWang Nan 14018c6f45a7SArnaldo Carvalho de Melo static int __cmd_record(struct record *rec, int argc, const char **argv) 140286470930SIngo Molnar { 140357706abcSDavid Ahern int err; 140445604710SNamhyung Kim int status = 0; 14058b412664SPeter Zijlstra unsigned long waking = 0; 140646be604bSZhang, Yanmin const bool forks = argc > 0; 140745694aa7SArnaldo Carvalho de Melo struct perf_tool *tool = &rec->tool; 1408b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &rec->opts; 14098ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 1410d20deb64SArnaldo Carvalho de Melo struct perf_session *session; 14116dcf45efSArnaldo Carvalho de Melo bool disabled = false, draining = false; 141263503dbaSJiri Olsa struct evlist *sb_evlist = NULL; 141342aa276fSNamhyung Kim int fd; 1414d3c8c08eSAlexey Budankov float ratio = 0; 141586470930SIngo Molnar 141645604710SNamhyung Kim atexit(record__sig_exit); 1417f5970550SPeter Zijlstra signal(SIGCHLD, sig_handler); 1418f5970550SPeter Zijlstra signal(SIGINT, sig_handler); 1419804f7ac7SDavid Ahern signal(SIGTERM, sig_handler); 1420a074865eSWang Nan signal(SIGSEGV, sigsegv_handler); 1421c0bdc1c4SWang Nan 1422f3b3614aSHari Bathini if (rec->opts.record_namespaces) 1423f3b3614aSHari Bathini tool->namespace_events = true; 1424f3b3614aSHari Bathini 1425dc0c6127SJiri Olsa if (rec->opts.auxtrace_snapshot_mode || rec->switch_output.enabled) { 14262dd6d8a1SAdrian Hunter signal(SIGUSR2, snapshot_sig_handler); 14273c1cb7e3SWang Nan if (rec->opts.auxtrace_snapshot_mode) 14285f9cf599SWang Nan trigger_on(&auxtrace_snapshot_trigger); 1429dc0c6127SJiri Olsa if (rec->switch_output.enabled) 14303c1cb7e3SWang Nan trigger_on(&switch_output_trigger); 1431c0bdc1c4SWang Nan } else { 14322dd6d8a1SAdrian Hunter signal(SIGUSR2, SIG_IGN); 1433c0bdc1c4SWang Nan } 1434f5970550SPeter Zijlstra 14358ceb41d7SJiri Olsa session = perf_session__new(data, false, tool); 14366ef81c55SMamatha Inamdar if (IS_ERR(session)) { 1437ffa91880SAdrien BAK pr_err("Perf session creation failed.\n"); 14386ef81c55SMamatha Inamdar return PTR_ERR(session); 1439a9a70bbcSArnaldo Carvalho de Melo } 1440a9a70bbcSArnaldo Carvalho de Melo 14418ceb41d7SJiri Olsa fd = perf_data__fd(data); 1442d20deb64SArnaldo Carvalho de Melo rec->session = session; 1443d20deb64SArnaldo Carvalho de Melo 14445d7f4116SAlexey Budankov if (zstd_init(&session->zstd_data, rec->opts.comp_level) < 0) { 14455d7f4116SAlexey Budankov pr_err("Compression initialization failed.\n"); 14465d7f4116SAlexey Budankov return -1; 14475d7f4116SAlexey Budankov } 14485d7f4116SAlexey Budankov 14495d7f4116SAlexey Budankov session->header.env.comp_type = PERF_COMP_ZSTD; 14505d7f4116SAlexey Budankov session->header.env.comp_level = rec->opts.comp_level; 14515d7f4116SAlexey Budankov 1452eeb399b5SAdrian Hunter if (rec->opts.kcore && 1453eeb399b5SAdrian Hunter !record__kcore_readable(&session->machines.host)) { 1454eeb399b5SAdrian Hunter pr_err("ERROR: kcore is not readable.\n"); 1455eeb399b5SAdrian Hunter return -1; 1456eeb399b5SAdrian Hunter } 1457eeb399b5SAdrian Hunter 14588c6f45a7SArnaldo Carvalho de Melo record__init_features(rec); 1459330aa675SStephane Eranian 1460cf790516SAlexey Budankov if (rec->opts.use_clockid && rec->opts.clockid_res_ns) 1461cf790516SAlexey Budankov session->header.env.clockid_res_ns = rec->opts.clockid_res_ns; 1462cf790516SAlexey Budankov 1463d4db3f16SArnaldo Carvalho de Melo if (forks) { 14643e2be2daSArnaldo Carvalho de Melo err = perf_evlist__prepare_workload(rec->evlist, &opts->target, 14658ceb41d7SJiri Olsa argv, data->is_pipe, 1466735f7e0bSArnaldo Carvalho de Melo workload_exec_failed_signal); 146735b9d88eSArnaldo Carvalho de Melo if (err < 0) { 146835b9d88eSArnaldo Carvalho de Melo pr_err("Couldn't run the workload!\n"); 146945604710SNamhyung Kim status = err; 147035b9d88eSArnaldo Carvalho de Melo goto out_delete_session; 1471856e9660SPeter Zijlstra } 1472856e9660SPeter Zijlstra } 1473856e9660SPeter Zijlstra 1474ad46e48cSJiri Olsa /* 1475ad46e48cSJiri Olsa * If we have just single event and are sending data 1476ad46e48cSJiri Olsa * through pipe, we need to force the ids allocation, 1477ad46e48cSJiri Olsa * because we synthesize event name through the pipe 1478ad46e48cSJiri Olsa * and need the id for that. 1479ad46e48cSJiri Olsa */ 14806484d2f9SJiri Olsa if (data->is_pipe && rec->evlist->core.nr_entries == 1) 1481ad46e48cSJiri Olsa rec->opts.sample_id = true; 1482ad46e48cSJiri Olsa 14838c6f45a7SArnaldo Carvalho de Melo if (record__open(rec) != 0) { 14848d3eca20SDavid Ahern err = -1; 148545604710SNamhyung Kim goto out_child; 14868d3eca20SDavid Ahern } 1487f6fa4375SJiri Olsa session->header.env.comp_mmap_len = session->evlist->core.mmap_len; 148886470930SIngo Molnar 1489eeb399b5SAdrian Hunter if (rec->opts.kcore) { 1490eeb399b5SAdrian Hunter err = record__kcore_copy(&session->machines.host, data); 1491eeb399b5SAdrian Hunter if (err) { 1492eeb399b5SAdrian Hunter pr_err("ERROR: Failed to copy kcore\n"); 1493eeb399b5SAdrian Hunter goto out_child; 1494eeb399b5SAdrian Hunter } 1495eeb399b5SAdrian Hunter } 1496eeb399b5SAdrian Hunter 14978690a2a7SWang Nan err = bpf__apply_obj_config(); 14988690a2a7SWang Nan if (err) { 14998690a2a7SWang Nan char errbuf[BUFSIZ]; 15008690a2a7SWang Nan 15018690a2a7SWang Nan bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf)); 15028690a2a7SWang Nan pr_err("ERROR: Apply config to BPF failed: %s\n", 15038690a2a7SWang Nan errbuf); 15048690a2a7SWang Nan goto out_child; 15058690a2a7SWang Nan } 15068690a2a7SWang Nan 1507cca8482cSAdrian Hunter /* 1508cca8482cSAdrian Hunter * Normally perf_session__new would do this, but it doesn't have the 1509cca8482cSAdrian Hunter * evlist. 1510cca8482cSAdrian Hunter */ 1511cca8482cSAdrian Hunter if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) { 1512cca8482cSAdrian Hunter pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n"); 1513cca8482cSAdrian Hunter rec->tool.ordered_events = false; 1514cca8482cSAdrian Hunter } 1515cca8482cSAdrian Hunter 15163e2be2daSArnaldo Carvalho de Melo if (!rec->evlist->nr_groups) 1517a8bb559bSNamhyung Kim perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); 1518a8bb559bSNamhyung Kim 15198ceb41d7SJiri Olsa if (data->is_pipe) { 152042aa276fSNamhyung Kim err = perf_header__write_pipe(fd); 1521529870e3STom Zanussi if (err < 0) 152245604710SNamhyung Kim goto out_child; 1523563aecb2SJiri Olsa } else { 152442aa276fSNamhyung Kim err = perf_session__write_header(session, rec->evlist, fd, false); 1525d5eed904SArnaldo Carvalho de Melo if (err < 0) 152645604710SNamhyung Kim goto out_child; 1527d5eed904SArnaldo Carvalho de Melo } 15287c6a1c65SPeter Zijlstra 1529d3665498SDavid Ahern if (!rec->no_buildid 1530e20960c0SRobert Richter && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) { 1531d3665498SDavid Ahern pr_err("Couldn't generate buildids. " 1532e20960c0SRobert Richter "Use --no-buildid to profile anyway.\n"); 15338d3eca20SDavid Ahern err = -1; 153445604710SNamhyung Kim goto out_child; 1535e20960c0SRobert Richter } 1536e20960c0SRobert Richter 1537d56354dcSSong Liu if (!opts->no_bpf_event) 1538d56354dcSSong Liu bpf_event__add_sb_event(&sb_evlist, &session->header.env); 1539d56354dcSSong Liu 1540657ee553SSong Liu if (perf_evlist__start_sb_thread(sb_evlist, &rec->opts.target)) { 1541657ee553SSong Liu pr_debug("Couldn't start the BPF side band thread:\nBPF programs starting from now on won't be annotatable\n"); 1542657ee553SSong Liu opts->no_bpf_event = true; 1543657ee553SSong Liu } 1544657ee553SSong Liu 15454ea648aeSWang Nan err = record__synthesize(rec, false); 1546c45c86ebSWang Nan if (err < 0) 154745604710SNamhyung Kim goto out_child; 15488d3eca20SDavid Ahern 1549d20deb64SArnaldo Carvalho de Melo if (rec->realtime_prio) { 155086470930SIngo Molnar struct sched_param param; 155186470930SIngo Molnar 1552d20deb64SArnaldo Carvalho de Melo param.sched_priority = rec->realtime_prio; 155386470930SIngo Molnar if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { 15546beba7adSArnaldo Carvalho de Melo pr_err("Could not set realtime priority.\n"); 15558d3eca20SDavid Ahern err = -1; 155645604710SNamhyung Kim goto out_child; 155786470930SIngo Molnar } 155886470930SIngo Molnar } 155986470930SIngo Molnar 1560774cb499SJiri Olsa /* 1561774cb499SJiri Olsa * When perf is starting the traced process, all the events 1562774cb499SJiri Olsa * (apart from group members) have enable_on_exec=1 set, 1563774cb499SJiri Olsa * so don't spoil it by prematurely enabling them. 1564774cb499SJiri Olsa */ 15656619a53eSAndi Kleen if (!target__none(&opts->target) && !opts->initial_delay) 15661c87f165SJiri Olsa evlist__enable(rec->evlist); 1567764e16a3SDavid Ahern 1568856e9660SPeter Zijlstra /* 1569856e9660SPeter Zijlstra * Let the child rip 1570856e9660SPeter Zijlstra */ 1571e803cf97SNamhyung Kim if (forks) { 157220a8a3cfSJiri Olsa struct machine *machine = &session->machines.host; 1573e5bed564SNamhyung Kim union perf_event *event; 1574e907caf3SHari Bathini pid_t tgid; 1575e5bed564SNamhyung Kim 1576e5bed564SNamhyung Kim event = malloc(sizeof(event->comm) + machine->id_hdr_size); 1577e5bed564SNamhyung Kim if (event == NULL) { 1578e5bed564SNamhyung Kim err = -ENOMEM; 1579e5bed564SNamhyung Kim goto out_child; 1580e5bed564SNamhyung Kim } 1581e5bed564SNamhyung Kim 1582e803cf97SNamhyung Kim /* 1583e803cf97SNamhyung Kim * Some H/W events are generated before COMM event 1584e803cf97SNamhyung Kim * which is emitted during exec(), so perf script 1585e803cf97SNamhyung Kim * cannot see a correct process name for those events. 1586e803cf97SNamhyung Kim * Synthesize COMM event to prevent it. 1587e803cf97SNamhyung Kim */ 1588e907caf3SHari Bathini tgid = perf_event__synthesize_comm(tool, event, 1589e803cf97SNamhyung Kim rec->evlist->workload.pid, 1590e803cf97SNamhyung Kim process_synthesized_event, 1591e803cf97SNamhyung Kim machine); 1592e5bed564SNamhyung Kim free(event); 1593e803cf97SNamhyung Kim 1594e907caf3SHari Bathini if (tgid == -1) 1595e907caf3SHari Bathini goto out_child; 1596e907caf3SHari Bathini 1597e907caf3SHari Bathini event = malloc(sizeof(event->namespaces) + 1598e907caf3SHari Bathini (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + 1599e907caf3SHari Bathini machine->id_hdr_size); 1600e907caf3SHari Bathini if (event == NULL) { 1601e907caf3SHari Bathini err = -ENOMEM; 1602e907caf3SHari Bathini goto out_child; 1603e907caf3SHari Bathini } 1604e907caf3SHari Bathini 1605e907caf3SHari Bathini /* 1606e907caf3SHari Bathini * Synthesize NAMESPACES event for the command specified. 1607e907caf3SHari Bathini */ 1608e907caf3SHari Bathini perf_event__synthesize_namespaces(tool, event, 1609e907caf3SHari Bathini rec->evlist->workload.pid, 1610e907caf3SHari Bathini tgid, process_synthesized_event, 1611e907caf3SHari Bathini machine); 1612e907caf3SHari Bathini free(event); 1613e907caf3SHari Bathini 16143e2be2daSArnaldo Carvalho de Melo perf_evlist__start_workload(rec->evlist); 1615e803cf97SNamhyung Kim } 1616856e9660SPeter Zijlstra 16176619a53eSAndi Kleen if (opts->initial_delay) { 16180693e680SArnaldo Carvalho de Melo usleep(opts->initial_delay * USEC_PER_MSEC); 16191c87f165SJiri Olsa evlist__enable(rec->evlist); 16206619a53eSAndi Kleen } 16216619a53eSAndi Kleen 16225f9cf599SWang Nan trigger_ready(&auxtrace_snapshot_trigger); 16233c1cb7e3SWang Nan trigger_ready(&switch_output_trigger); 1624a074865eSWang Nan perf_hooks__invoke_record_start(); 1625649c48a9SPeter Zijlstra for (;;) { 16269f065194SYang Shi unsigned long long hits = rec->samples; 162786470930SIngo Molnar 162805737464SWang Nan /* 162905737464SWang Nan * rec->evlist->bkw_mmap_state is possible to be 163005737464SWang Nan * BKW_MMAP_EMPTY here: when done == true and 163105737464SWang Nan * hits != rec->samples in previous round. 163205737464SWang Nan * 163305737464SWang Nan * perf_evlist__toggle_bkw_mmap ensure we never 163405737464SWang Nan * convert BKW_MMAP_EMPTY to BKW_MMAP_DATA_PENDING. 163505737464SWang Nan */ 163605737464SWang Nan if (trigger_is_hit(&switch_output_trigger) || done || draining) 163705737464SWang Nan perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_DATA_PENDING); 163805737464SWang Nan 1639470530bbSAlexey Budankov if (record__mmap_read_all(rec, false) < 0) { 16405f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 16413c1cb7e3SWang Nan trigger_error(&switch_output_trigger); 16428d3eca20SDavid Ahern err = -1; 164345604710SNamhyung Kim goto out_child; 16448d3eca20SDavid Ahern } 164586470930SIngo Molnar 16462dd6d8a1SAdrian Hunter if (auxtrace_record__snapshot_started) { 16472dd6d8a1SAdrian Hunter auxtrace_record__snapshot_started = 0; 16485f9cf599SWang Nan if (!trigger_is_error(&auxtrace_snapshot_trigger)) 1649ce7b0e42SAlexander Shishkin record__read_auxtrace_snapshot(rec, false); 16505f9cf599SWang Nan if (trigger_is_error(&auxtrace_snapshot_trigger)) { 16512dd6d8a1SAdrian Hunter pr_err("AUX area tracing snapshot failed\n"); 16522dd6d8a1SAdrian Hunter err = -1; 16532dd6d8a1SAdrian Hunter goto out_child; 16542dd6d8a1SAdrian Hunter } 16552dd6d8a1SAdrian Hunter } 16562dd6d8a1SAdrian Hunter 16573c1cb7e3SWang Nan if (trigger_is_hit(&switch_output_trigger)) { 165805737464SWang Nan /* 165905737464SWang Nan * If switch_output_trigger is hit, the data in 166005737464SWang Nan * overwritable ring buffer should have been collected, 166105737464SWang Nan * so bkw_mmap_state should be set to BKW_MMAP_EMPTY. 166205737464SWang Nan * 166305737464SWang Nan * If SIGUSR2 raise after or during record__mmap_read_all(), 166405737464SWang Nan * record__mmap_read_all() didn't collect data from 166505737464SWang Nan * overwritable ring buffer. Read again. 166605737464SWang Nan */ 166705737464SWang Nan if (rec->evlist->bkw_mmap_state == BKW_MMAP_RUNNING) 166805737464SWang Nan continue; 16693c1cb7e3SWang Nan trigger_ready(&switch_output_trigger); 16703c1cb7e3SWang Nan 167105737464SWang Nan /* 167205737464SWang Nan * Reenable events in overwrite ring buffer after 167305737464SWang Nan * record__mmap_read_all(): we should have collected 167405737464SWang Nan * data from it. 167505737464SWang Nan */ 167605737464SWang Nan perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_RUNNING); 167705737464SWang Nan 16783c1cb7e3SWang Nan if (!quiet) 16793c1cb7e3SWang Nan fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n", 16803c1cb7e3SWang Nan waking); 16813c1cb7e3SWang Nan waking = 0; 16823c1cb7e3SWang Nan fd = record__switch_output(rec, false); 16833c1cb7e3SWang Nan if (fd < 0) { 16843c1cb7e3SWang Nan pr_err("Failed to switch to new file\n"); 16853c1cb7e3SWang Nan trigger_error(&switch_output_trigger); 16863c1cb7e3SWang Nan err = fd; 16873c1cb7e3SWang Nan goto out_child; 16883c1cb7e3SWang Nan } 1689bfacbe3bSJiri Olsa 1690bfacbe3bSJiri Olsa /* re-arm the alarm */ 1691bfacbe3bSJiri Olsa if (rec->switch_output.time) 1692bfacbe3bSJiri Olsa alarm(rec->switch_output.time); 16933c1cb7e3SWang Nan } 16943c1cb7e3SWang Nan 1695d20deb64SArnaldo Carvalho de Melo if (hits == rec->samples) { 16966dcf45efSArnaldo Carvalho de Melo if (done || draining) 1697649c48a9SPeter Zijlstra break; 169880ab2987SJiri Olsa err = evlist__poll(rec->evlist, -1); 1699a515114fSJiri Olsa /* 1700a515114fSJiri Olsa * Propagate error, only if there's any. Ignore positive 1701a515114fSJiri Olsa * number of returned events and interrupt error. 1702a515114fSJiri Olsa */ 1703a515114fSJiri Olsa if (err > 0 || (err < 0 && errno == EINTR)) 170445604710SNamhyung Kim err = 0; 17058b412664SPeter Zijlstra waking++; 17066dcf45efSArnaldo Carvalho de Melo 1707f4009e7bSJiri Olsa if (evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0) 17086dcf45efSArnaldo Carvalho de Melo draining = true; 17098b412664SPeter Zijlstra } 17108b412664SPeter Zijlstra 1711774cb499SJiri Olsa /* 1712774cb499SJiri Olsa * When perf is starting the traced process, at the end events 1713774cb499SJiri Olsa * die with the process and we wait for that. Thus no need to 1714774cb499SJiri Olsa * disable events in this case. 1715774cb499SJiri Olsa */ 1716602ad878SArnaldo Carvalho de Melo if (done && !disabled && !target__none(&opts->target)) { 17175f9cf599SWang Nan trigger_off(&auxtrace_snapshot_trigger); 1718e74676deSJiri Olsa evlist__disable(rec->evlist); 17192711926aSJiri Olsa disabled = true; 17202711926aSJiri Olsa } 17218b412664SPeter Zijlstra } 1722ce7b0e42SAlexander Shishkin 17235f9cf599SWang Nan trigger_off(&auxtrace_snapshot_trigger); 17243c1cb7e3SWang Nan trigger_off(&switch_output_trigger); 17258b412664SPeter Zijlstra 1726ce7b0e42SAlexander Shishkin if (opts->auxtrace_snapshot_on_exit) 1727ce7b0e42SAlexander Shishkin record__auxtrace_snapshot_exit(rec); 1728ce7b0e42SAlexander Shishkin 1729f33cbe72SArnaldo Carvalho de Melo if (forks && workload_exec_errno) { 173035550da3SMasami Hiramatsu char msg[STRERR_BUFSIZE]; 1731c8b5f2c9SArnaldo Carvalho de Melo const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); 1732f33cbe72SArnaldo Carvalho de Melo pr_err("Workload failed: %s\n", emsg); 1733f33cbe72SArnaldo Carvalho de Melo err = -1; 173445604710SNamhyung Kim goto out_child; 1735f33cbe72SArnaldo Carvalho de Melo } 1736f33cbe72SArnaldo Carvalho de Melo 1737e3d59112SNamhyung Kim if (!quiet) 17388b412664SPeter Zijlstra fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); 173986470930SIngo Molnar 17404ea648aeSWang Nan if (target__none(&rec->opts.target)) 17414ea648aeSWang Nan record__synthesize_workload(rec, true); 17424ea648aeSWang Nan 174345604710SNamhyung Kim out_child: 1744470530bbSAlexey Budankov record__mmap_read_all(rec, true); 1745d3d1af6fSAlexey Budankov record__aio_mmap_read_sync(rec); 1746d3d1af6fSAlexey Budankov 1747d3c8c08eSAlexey Budankov if (rec->session->bytes_transferred && rec->session->bytes_compressed) { 1748d3c8c08eSAlexey Budankov ratio = (float)rec->session->bytes_transferred/(float)rec->session->bytes_compressed; 1749d3c8c08eSAlexey Budankov session->header.env.comp_ratio = ratio + 0.5; 1750d3c8c08eSAlexey Budankov } 1751d3c8c08eSAlexey Budankov 175245604710SNamhyung Kim if (forks) { 175345604710SNamhyung Kim int exit_status; 175445604710SNamhyung Kim 175545604710SNamhyung Kim if (!child_finished) 175645604710SNamhyung Kim kill(rec->evlist->workload.pid, SIGTERM); 175745604710SNamhyung Kim 175845604710SNamhyung Kim wait(&exit_status); 175945604710SNamhyung Kim 176045604710SNamhyung Kim if (err < 0) 176145604710SNamhyung Kim status = err; 176245604710SNamhyung Kim else if (WIFEXITED(exit_status)) 176345604710SNamhyung Kim status = WEXITSTATUS(exit_status); 176445604710SNamhyung Kim else if (WIFSIGNALED(exit_status)) 176545604710SNamhyung Kim signr = WTERMSIG(exit_status); 176645604710SNamhyung Kim } else 176745604710SNamhyung Kim status = err; 176845604710SNamhyung Kim 17694ea648aeSWang Nan record__synthesize(rec, true); 1770e3d59112SNamhyung Kim /* this will be recalculated during process_buildids() */ 1771e3d59112SNamhyung Kim rec->samples = 0; 1772e3d59112SNamhyung Kim 1773ecfd7a9cSWang Nan if (!err) { 1774ecfd7a9cSWang Nan if (!rec->timestamp_filename) { 1775e1ab48baSWang Nan record__finish_output(rec); 1776ecfd7a9cSWang Nan } else { 1777ecfd7a9cSWang Nan fd = record__switch_output(rec, true); 1778ecfd7a9cSWang Nan if (fd < 0) { 1779ecfd7a9cSWang Nan status = fd; 1780ecfd7a9cSWang Nan goto out_delete_session; 1781ecfd7a9cSWang Nan } 1782ecfd7a9cSWang Nan } 1783ecfd7a9cSWang Nan } 178439d17dacSArnaldo Carvalho de Melo 1785a074865eSWang Nan perf_hooks__invoke_record_end(); 1786a074865eSWang Nan 1787e3d59112SNamhyung Kim if (!err && !quiet) { 1788e3d59112SNamhyung Kim char samples[128]; 1789ecfd7a9cSWang Nan const char *postfix = rec->timestamp_filename ? 1790ecfd7a9cSWang Nan ".<timestamp>" : ""; 1791e3d59112SNamhyung Kim 1792ef149c25SAdrian Hunter if (rec->samples && !rec->opts.full_auxtrace) 1793e3d59112SNamhyung Kim scnprintf(samples, sizeof(samples), 1794e3d59112SNamhyung Kim " (%" PRIu64 " samples)", rec->samples); 1795e3d59112SNamhyung Kim else 1796e3d59112SNamhyung Kim samples[0] = '\0'; 1797e3d59112SNamhyung Kim 1798d3c8c08eSAlexey Budankov fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s", 17998ceb41d7SJiri Olsa perf_data__size(data) / 1024.0 / 1024.0, 18002d4f2799SJiri Olsa data->path, postfix, samples); 1801d3c8c08eSAlexey Budankov if (ratio) { 1802d3c8c08eSAlexey Budankov fprintf(stderr, ", compressed (original %.3f MB, ratio is %.3f)", 1803d3c8c08eSAlexey Budankov rec->session->bytes_transferred / 1024.0 / 1024.0, 1804d3c8c08eSAlexey Budankov ratio); 1805d3c8c08eSAlexey Budankov } 1806d3c8c08eSAlexey Budankov fprintf(stderr, " ]\n"); 1807e3d59112SNamhyung Kim } 1808e3d59112SNamhyung Kim 180939d17dacSArnaldo Carvalho de Melo out_delete_session: 18105d7f4116SAlexey Budankov zstd_fini(&session->zstd_data); 181139d17dacSArnaldo Carvalho de Melo perf_session__delete(session); 1812657ee553SSong Liu 1813657ee553SSong Liu if (!opts->no_bpf_event) 1814657ee553SSong Liu perf_evlist__stop_sb_thread(sb_evlist); 181545604710SNamhyung Kim return status; 181686470930SIngo Molnar } 181786470930SIngo Molnar 18180883e820SArnaldo Carvalho de Melo static void callchain_debug(struct callchain_param *callchain) 181909b0fd45SJiri Olsa { 1820aad2b21cSKan Liang static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" }; 1821a601fdffSJiri Olsa 18220883e820SArnaldo Carvalho de Melo pr_debug("callchain: type %s\n", str[callchain->record_mode]); 182326d33022SJiri Olsa 18240883e820SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_DWARF) 182509b0fd45SJiri Olsa pr_debug("callchain: stack dump size %d\n", 18260883e820SArnaldo Carvalho de Melo callchain->dump_size); 18270883e820SArnaldo Carvalho de Melo } 18280883e820SArnaldo Carvalho de Melo 18290883e820SArnaldo Carvalho de Melo int record_opts__parse_callchain(struct record_opts *record, 18300883e820SArnaldo Carvalho de Melo struct callchain_param *callchain, 18310883e820SArnaldo Carvalho de Melo const char *arg, bool unset) 18320883e820SArnaldo Carvalho de Melo { 18330883e820SArnaldo Carvalho de Melo int ret; 18340883e820SArnaldo Carvalho de Melo callchain->enabled = !unset; 18350883e820SArnaldo Carvalho de Melo 18360883e820SArnaldo Carvalho de Melo /* --no-call-graph */ 18370883e820SArnaldo Carvalho de Melo if (unset) { 18380883e820SArnaldo Carvalho de Melo callchain->record_mode = CALLCHAIN_NONE; 18390883e820SArnaldo Carvalho de Melo pr_debug("callchain: disabled\n"); 18400883e820SArnaldo Carvalho de Melo return 0; 18410883e820SArnaldo Carvalho de Melo } 18420883e820SArnaldo Carvalho de Melo 18430883e820SArnaldo Carvalho de Melo ret = parse_callchain_record_opt(arg, callchain); 18440883e820SArnaldo Carvalho de Melo if (!ret) { 18450883e820SArnaldo Carvalho de Melo /* Enable data address sampling for DWARF unwind. */ 18460883e820SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_DWARF) 18470883e820SArnaldo Carvalho de Melo record->sample_address = true; 18480883e820SArnaldo Carvalho de Melo callchain_debug(callchain); 18490883e820SArnaldo Carvalho de Melo } 18500883e820SArnaldo Carvalho de Melo 18510883e820SArnaldo Carvalho de Melo return ret; 185209b0fd45SJiri Olsa } 185309b0fd45SJiri Olsa 1854c421e80bSKan Liang int record_parse_callchain_opt(const struct option *opt, 185509b0fd45SJiri Olsa const char *arg, 185609b0fd45SJiri Olsa int unset) 185709b0fd45SJiri Olsa { 18580883e820SArnaldo Carvalho de Melo return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset); 185926d33022SJiri Olsa } 186026d33022SJiri Olsa 1861c421e80bSKan Liang int record_callchain_opt(const struct option *opt, 186209b0fd45SJiri Olsa const char *arg __maybe_unused, 186309b0fd45SJiri Olsa int unset __maybe_unused) 186409b0fd45SJiri Olsa { 18652ddd5c04SArnaldo Carvalho de Melo struct callchain_param *callchain = opt->value; 1866c421e80bSKan Liang 18672ddd5c04SArnaldo Carvalho de Melo callchain->enabled = true; 186809b0fd45SJiri Olsa 18692ddd5c04SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_NONE) 18702ddd5c04SArnaldo Carvalho de Melo callchain->record_mode = CALLCHAIN_FP; 1871eb853e80SJiri Olsa 18722ddd5c04SArnaldo Carvalho de Melo callchain_debug(callchain); 187309b0fd45SJiri Olsa return 0; 187409b0fd45SJiri Olsa } 187509b0fd45SJiri Olsa 1876eb853e80SJiri Olsa static int perf_record_config(const char *var, const char *value, void *cb) 1877eb853e80SJiri Olsa { 18787a29c087SNamhyung Kim struct record *rec = cb; 18797a29c087SNamhyung Kim 18807a29c087SNamhyung Kim if (!strcmp(var, "record.build-id")) { 18817a29c087SNamhyung Kim if (!strcmp(value, "cache")) 18827a29c087SNamhyung Kim rec->no_buildid_cache = false; 18837a29c087SNamhyung Kim else if (!strcmp(value, "no-cache")) 18847a29c087SNamhyung Kim rec->no_buildid_cache = true; 18857a29c087SNamhyung Kim else if (!strcmp(value, "skip")) 18867a29c087SNamhyung Kim rec->no_buildid = true; 18877a29c087SNamhyung Kim else 18887a29c087SNamhyung Kim return -1; 18897a29c087SNamhyung Kim return 0; 18907a29c087SNamhyung Kim } 1891cff17205SYisheng Xie if (!strcmp(var, "record.call-graph")) { 1892cff17205SYisheng Xie var = "call-graph.record-mode"; 1893eb853e80SJiri Olsa return perf_default_config(var, value, cb); 1894eb853e80SJiri Olsa } 189593f20c0fSAlexey Budankov #ifdef HAVE_AIO_SUPPORT 189693f20c0fSAlexey Budankov if (!strcmp(var, "record.aio")) { 189793f20c0fSAlexey Budankov rec->opts.nr_cblocks = strtol(value, NULL, 0); 189893f20c0fSAlexey Budankov if (!rec->opts.nr_cblocks) 189993f20c0fSAlexey Budankov rec->opts.nr_cblocks = nr_cblocks_default; 190093f20c0fSAlexey Budankov } 190193f20c0fSAlexey Budankov #endif 1902eb853e80SJiri Olsa 1903cff17205SYisheng Xie return 0; 1904cff17205SYisheng Xie } 1905cff17205SYisheng Xie 1906814c8c38SPeter Zijlstra struct clockid_map { 1907814c8c38SPeter Zijlstra const char *name; 1908814c8c38SPeter Zijlstra int clockid; 1909814c8c38SPeter Zijlstra }; 1910814c8c38SPeter Zijlstra 1911814c8c38SPeter Zijlstra #define CLOCKID_MAP(n, c) \ 1912814c8c38SPeter Zijlstra { .name = n, .clockid = (c), } 1913814c8c38SPeter Zijlstra 1914814c8c38SPeter Zijlstra #define CLOCKID_END { .name = NULL, } 1915814c8c38SPeter Zijlstra 1916814c8c38SPeter Zijlstra 1917814c8c38SPeter Zijlstra /* 1918814c8c38SPeter Zijlstra * Add the missing ones, we need to build on many distros... 1919814c8c38SPeter Zijlstra */ 1920814c8c38SPeter Zijlstra #ifndef CLOCK_MONOTONIC_RAW 1921814c8c38SPeter Zijlstra #define CLOCK_MONOTONIC_RAW 4 1922814c8c38SPeter Zijlstra #endif 1923814c8c38SPeter Zijlstra #ifndef CLOCK_BOOTTIME 1924814c8c38SPeter Zijlstra #define CLOCK_BOOTTIME 7 1925814c8c38SPeter Zijlstra #endif 1926814c8c38SPeter Zijlstra #ifndef CLOCK_TAI 1927814c8c38SPeter Zijlstra #define CLOCK_TAI 11 1928814c8c38SPeter Zijlstra #endif 1929814c8c38SPeter Zijlstra 1930814c8c38SPeter Zijlstra static const struct clockid_map clockids[] = { 1931814c8c38SPeter Zijlstra /* available for all events, NMI safe */ 1932814c8c38SPeter Zijlstra CLOCKID_MAP("monotonic", CLOCK_MONOTONIC), 1933814c8c38SPeter Zijlstra CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW), 1934814c8c38SPeter Zijlstra 1935814c8c38SPeter Zijlstra /* available for some events */ 1936814c8c38SPeter Zijlstra CLOCKID_MAP("realtime", CLOCK_REALTIME), 1937814c8c38SPeter Zijlstra CLOCKID_MAP("boottime", CLOCK_BOOTTIME), 1938814c8c38SPeter Zijlstra CLOCKID_MAP("tai", CLOCK_TAI), 1939814c8c38SPeter Zijlstra 1940814c8c38SPeter Zijlstra /* available for the lazy */ 1941814c8c38SPeter Zijlstra CLOCKID_MAP("mono", CLOCK_MONOTONIC), 1942814c8c38SPeter Zijlstra CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW), 1943814c8c38SPeter Zijlstra CLOCKID_MAP("real", CLOCK_REALTIME), 1944814c8c38SPeter Zijlstra CLOCKID_MAP("boot", CLOCK_BOOTTIME), 1945814c8c38SPeter Zijlstra 1946814c8c38SPeter Zijlstra CLOCKID_END, 1947814c8c38SPeter Zijlstra }; 1948814c8c38SPeter Zijlstra 1949cf790516SAlexey Budankov static int get_clockid_res(clockid_t clk_id, u64 *res_ns) 1950cf790516SAlexey Budankov { 1951cf790516SAlexey Budankov struct timespec res; 1952cf790516SAlexey Budankov 1953cf790516SAlexey Budankov *res_ns = 0; 1954cf790516SAlexey Budankov if (!clock_getres(clk_id, &res)) 1955cf790516SAlexey Budankov *res_ns = res.tv_nsec + res.tv_sec * NSEC_PER_SEC; 1956cf790516SAlexey Budankov else 1957cf790516SAlexey Budankov pr_warning("WARNING: Failed to determine specified clock resolution.\n"); 1958cf790516SAlexey Budankov 1959cf790516SAlexey Budankov return 0; 1960cf790516SAlexey Budankov } 1961cf790516SAlexey Budankov 1962814c8c38SPeter Zijlstra static int parse_clockid(const struct option *opt, const char *str, int unset) 1963814c8c38SPeter Zijlstra { 1964814c8c38SPeter Zijlstra struct record_opts *opts = (struct record_opts *)opt->value; 1965814c8c38SPeter Zijlstra const struct clockid_map *cm; 1966814c8c38SPeter Zijlstra const char *ostr = str; 1967814c8c38SPeter Zijlstra 1968814c8c38SPeter Zijlstra if (unset) { 1969814c8c38SPeter Zijlstra opts->use_clockid = 0; 1970814c8c38SPeter Zijlstra return 0; 1971814c8c38SPeter Zijlstra } 1972814c8c38SPeter Zijlstra 1973814c8c38SPeter Zijlstra /* no arg passed */ 1974814c8c38SPeter Zijlstra if (!str) 1975814c8c38SPeter Zijlstra return 0; 1976814c8c38SPeter Zijlstra 1977814c8c38SPeter Zijlstra /* no setting it twice */ 1978814c8c38SPeter Zijlstra if (opts->use_clockid) 1979814c8c38SPeter Zijlstra return -1; 1980814c8c38SPeter Zijlstra 1981814c8c38SPeter Zijlstra opts->use_clockid = true; 1982814c8c38SPeter Zijlstra 1983814c8c38SPeter Zijlstra /* if its a number, we're done */ 1984814c8c38SPeter Zijlstra if (sscanf(str, "%d", &opts->clockid) == 1) 1985cf790516SAlexey Budankov return get_clockid_res(opts->clockid, &opts->clockid_res_ns); 1986814c8c38SPeter Zijlstra 1987814c8c38SPeter Zijlstra /* allow a "CLOCK_" prefix to the name */ 1988814c8c38SPeter Zijlstra if (!strncasecmp(str, "CLOCK_", 6)) 1989814c8c38SPeter Zijlstra str += 6; 1990814c8c38SPeter Zijlstra 1991814c8c38SPeter Zijlstra for (cm = clockids; cm->name; cm++) { 1992814c8c38SPeter Zijlstra if (!strcasecmp(str, cm->name)) { 1993814c8c38SPeter Zijlstra opts->clockid = cm->clockid; 1994cf790516SAlexey Budankov return get_clockid_res(opts->clockid, 1995cf790516SAlexey Budankov &opts->clockid_res_ns); 1996814c8c38SPeter Zijlstra } 1997814c8c38SPeter Zijlstra } 1998814c8c38SPeter Zijlstra 1999814c8c38SPeter Zijlstra opts->use_clockid = false; 2000814c8c38SPeter Zijlstra ui__warning("unknown clockid %s, check man page\n", ostr); 2001814c8c38SPeter Zijlstra return -1; 2002814c8c38SPeter Zijlstra } 2003814c8c38SPeter Zijlstra 2004f4fe11b7SAlexey Budankov static int record__parse_affinity(const struct option *opt, const char *str, int unset) 2005f4fe11b7SAlexey Budankov { 2006f4fe11b7SAlexey Budankov struct record_opts *opts = (struct record_opts *)opt->value; 2007f4fe11b7SAlexey Budankov 2008f4fe11b7SAlexey Budankov if (unset || !str) 2009f4fe11b7SAlexey Budankov return 0; 2010f4fe11b7SAlexey Budankov 2011f4fe11b7SAlexey Budankov if (!strcasecmp(str, "node")) 2012f4fe11b7SAlexey Budankov opts->affinity = PERF_AFFINITY_NODE; 2013f4fe11b7SAlexey Budankov else if (!strcasecmp(str, "cpu")) 2014f4fe11b7SAlexey Budankov opts->affinity = PERF_AFFINITY_CPU; 2015f4fe11b7SAlexey Budankov 2016f4fe11b7SAlexey Budankov return 0; 2017f4fe11b7SAlexey Budankov } 2018f4fe11b7SAlexey Budankov 20196d575816SJiwei Sun static int parse_output_max_size(const struct option *opt, 20206d575816SJiwei Sun const char *str, int unset) 20216d575816SJiwei Sun { 20226d575816SJiwei Sun unsigned long *s = (unsigned long *)opt->value; 20236d575816SJiwei Sun static struct parse_tag tags_size[] = { 20246d575816SJiwei Sun { .tag = 'B', .mult = 1 }, 20256d575816SJiwei Sun { .tag = 'K', .mult = 1 << 10 }, 20266d575816SJiwei Sun { .tag = 'M', .mult = 1 << 20 }, 20276d575816SJiwei Sun { .tag = 'G', .mult = 1 << 30 }, 20286d575816SJiwei Sun { .tag = 0 }, 20296d575816SJiwei Sun }; 20306d575816SJiwei Sun unsigned long val; 20316d575816SJiwei Sun 20326d575816SJiwei Sun if (unset) { 20336d575816SJiwei Sun *s = 0; 20346d575816SJiwei Sun return 0; 20356d575816SJiwei Sun } 20366d575816SJiwei Sun 20376d575816SJiwei Sun val = parse_tag_value(str, tags_size); 20386d575816SJiwei Sun if (val != (unsigned long) -1) { 20396d575816SJiwei Sun *s = val; 20406d575816SJiwei Sun return 0; 20416d575816SJiwei Sun } 20426d575816SJiwei Sun 20436d575816SJiwei Sun return -1; 20446d575816SJiwei Sun } 20456d575816SJiwei Sun 2046e9db1310SAdrian Hunter static int record__parse_mmap_pages(const struct option *opt, 2047e9db1310SAdrian Hunter const char *str, 2048e9db1310SAdrian Hunter int unset __maybe_unused) 2049e9db1310SAdrian Hunter { 2050e9db1310SAdrian Hunter struct record_opts *opts = opt->value; 2051e9db1310SAdrian Hunter char *s, *p; 2052e9db1310SAdrian Hunter unsigned int mmap_pages; 2053e9db1310SAdrian Hunter int ret; 2054e9db1310SAdrian Hunter 2055e9db1310SAdrian Hunter if (!str) 2056e9db1310SAdrian Hunter return -EINVAL; 2057e9db1310SAdrian Hunter 2058e9db1310SAdrian Hunter s = strdup(str); 2059e9db1310SAdrian Hunter if (!s) 2060e9db1310SAdrian Hunter return -ENOMEM; 2061e9db1310SAdrian Hunter 2062e9db1310SAdrian Hunter p = strchr(s, ','); 2063e9db1310SAdrian Hunter if (p) 2064e9db1310SAdrian Hunter *p = '\0'; 2065e9db1310SAdrian Hunter 2066e9db1310SAdrian Hunter if (*s) { 2067e9db1310SAdrian Hunter ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s); 2068e9db1310SAdrian Hunter if (ret) 2069e9db1310SAdrian Hunter goto out_free; 2070e9db1310SAdrian Hunter opts->mmap_pages = mmap_pages; 2071e9db1310SAdrian Hunter } 2072e9db1310SAdrian Hunter 2073e9db1310SAdrian Hunter if (!p) { 2074e9db1310SAdrian Hunter ret = 0; 2075e9db1310SAdrian Hunter goto out_free; 2076e9db1310SAdrian Hunter } 2077e9db1310SAdrian Hunter 2078e9db1310SAdrian Hunter ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1); 2079e9db1310SAdrian Hunter if (ret) 2080e9db1310SAdrian Hunter goto out_free; 2081e9db1310SAdrian Hunter 2082e9db1310SAdrian Hunter opts->auxtrace_mmap_pages = mmap_pages; 2083e9db1310SAdrian Hunter 2084e9db1310SAdrian Hunter out_free: 2085e9db1310SAdrian Hunter free(s); 2086e9db1310SAdrian Hunter return ret; 2087e9db1310SAdrian Hunter } 2088e9db1310SAdrian Hunter 20890c582449SJiri Olsa static void switch_output_size_warn(struct record *rec) 20900c582449SJiri Olsa { 20919521b5f2SJiri Olsa u64 wakeup_size = evlist__mmap_size(rec->opts.mmap_pages); 20920c582449SJiri Olsa struct switch_output *s = &rec->switch_output; 20930c582449SJiri Olsa 20940c582449SJiri Olsa wakeup_size /= 2; 20950c582449SJiri Olsa 20960c582449SJiri Olsa if (s->size < wakeup_size) { 20970c582449SJiri Olsa char buf[100]; 20980c582449SJiri Olsa 20990c582449SJiri Olsa unit_number__scnprintf(buf, sizeof(buf), wakeup_size); 21000c582449SJiri Olsa pr_warning("WARNING: switch-output data size lower than " 21010c582449SJiri Olsa "wakeup kernel buffer size (%s) " 21020c582449SJiri Olsa "expect bigger perf.data sizes\n", buf); 21030c582449SJiri Olsa } 21040c582449SJiri Olsa } 21050c582449SJiri Olsa 2106cb4e1ebbSJiri Olsa static int switch_output_setup(struct record *rec) 2107cb4e1ebbSJiri Olsa { 2108cb4e1ebbSJiri Olsa struct switch_output *s = &rec->switch_output; 2109dc0c6127SJiri Olsa static struct parse_tag tags_size[] = { 2110dc0c6127SJiri Olsa { .tag = 'B', .mult = 1 }, 2111dc0c6127SJiri Olsa { .tag = 'K', .mult = 1 << 10 }, 2112dc0c6127SJiri Olsa { .tag = 'M', .mult = 1 << 20 }, 2113dc0c6127SJiri Olsa { .tag = 'G', .mult = 1 << 30 }, 2114dc0c6127SJiri Olsa { .tag = 0 }, 2115dc0c6127SJiri Olsa }; 2116bfacbe3bSJiri Olsa static struct parse_tag tags_time[] = { 2117bfacbe3bSJiri Olsa { .tag = 's', .mult = 1 }, 2118bfacbe3bSJiri Olsa { .tag = 'm', .mult = 60 }, 2119bfacbe3bSJiri Olsa { .tag = 'h', .mult = 60*60 }, 2120bfacbe3bSJiri Olsa { .tag = 'd', .mult = 60*60*24 }, 2121bfacbe3bSJiri Olsa { .tag = 0 }, 2122bfacbe3bSJiri Olsa }; 2123dc0c6127SJiri Olsa unsigned long val; 2124cb4e1ebbSJiri Olsa 2125cb4e1ebbSJiri Olsa if (!s->set) 2126cb4e1ebbSJiri Olsa return 0; 2127cb4e1ebbSJiri Olsa 2128cb4e1ebbSJiri Olsa if (!strcmp(s->str, "signal")) { 2129cb4e1ebbSJiri Olsa s->signal = true; 2130cb4e1ebbSJiri Olsa pr_debug("switch-output with SIGUSR2 signal\n"); 2131dc0c6127SJiri Olsa goto enabled; 2132dc0c6127SJiri Olsa } 2133dc0c6127SJiri Olsa 2134dc0c6127SJiri Olsa val = parse_tag_value(s->str, tags_size); 2135dc0c6127SJiri Olsa if (val != (unsigned long) -1) { 2136dc0c6127SJiri Olsa s->size = val; 2137dc0c6127SJiri Olsa pr_debug("switch-output with %s size threshold\n", s->str); 2138dc0c6127SJiri Olsa goto enabled; 2139cb4e1ebbSJiri Olsa } 2140cb4e1ebbSJiri Olsa 2141bfacbe3bSJiri Olsa val = parse_tag_value(s->str, tags_time); 2142bfacbe3bSJiri Olsa if (val != (unsigned long) -1) { 2143bfacbe3bSJiri Olsa s->time = val; 2144bfacbe3bSJiri Olsa pr_debug("switch-output with %s time threshold (%lu seconds)\n", 2145bfacbe3bSJiri Olsa s->str, s->time); 2146bfacbe3bSJiri Olsa goto enabled; 2147bfacbe3bSJiri Olsa } 2148bfacbe3bSJiri Olsa 2149cb4e1ebbSJiri Olsa return -1; 2150dc0c6127SJiri Olsa 2151dc0c6127SJiri Olsa enabled: 2152dc0c6127SJiri Olsa rec->timestamp_filename = true; 2153dc0c6127SJiri Olsa s->enabled = true; 21540c582449SJiri Olsa 21550c582449SJiri Olsa if (s->size && !rec->opts.no_buffering) 21560c582449SJiri Olsa switch_output_size_warn(rec); 21570c582449SJiri Olsa 2158dc0c6127SJiri Olsa return 0; 2159cb4e1ebbSJiri Olsa } 2160cb4e1ebbSJiri Olsa 2161e5b2c207SNamhyung Kim static const char * const __record_usage[] = { 216286470930SIngo Molnar "perf record [<options>] [<command>]", 216386470930SIngo Molnar "perf record [<options>] -- <command> [<options>]", 216486470930SIngo Molnar NULL 216586470930SIngo Molnar }; 2166e5b2c207SNamhyung Kim const char * const *record_usage = __record_usage; 216786470930SIngo Molnar 21686e0a9b3dSArnaldo Carvalho de Melo static int build_id__process_mmap(struct perf_tool *tool, union perf_event *event, 21696e0a9b3dSArnaldo Carvalho de Melo struct perf_sample *sample, struct machine *machine) 21706e0a9b3dSArnaldo Carvalho de Melo { 21716e0a9b3dSArnaldo Carvalho de Melo /* 21726e0a9b3dSArnaldo Carvalho de Melo * We already have the kernel maps, put in place via perf_session__create_kernel_maps() 21736e0a9b3dSArnaldo Carvalho de Melo * no need to add them twice. 21746e0a9b3dSArnaldo Carvalho de Melo */ 21756e0a9b3dSArnaldo Carvalho de Melo if (!(event->header.misc & PERF_RECORD_MISC_USER)) 21766e0a9b3dSArnaldo Carvalho de Melo return 0; 21776e0a9b3dSArnaldo Carvalho de Melo return perf_event__process_mmap(tool, event, sample, machine); 21786e0a9b3dSArnaldo Carvalho de Melo } 21796e0a9b3dSArnaldo Carvalho de Melo 21806e0a9b3dSArnaldo Carvalho de Melo static int build_id__process_mmap2(struct perf_tool *tool, union perf_event *event, 21816e0a9b3dSArnaldo Carvalho de Melo struct perf_sample *sample, struct machine *machine) 21826e0a9b3dSArnaldo Carvalho de Melo { 21836e0a9b3dSArnaldo Carvalho de Melo /* 21846e0a9b3dSArnaldo Carvalho de Melo * We already have the kernel maps, put in place via perf_session__create_kernel_maps() 21856e0a9b3dSArnaldo Carvalho de Melo * no need to add them twice. 21866e0a9b3dSArnaldo Carvalho de Melo */ 21876e0a9b3dSArnaldo Carvalho de Melo if (!(event->header.misc & PERF_RECORD_MISC_USER)) 21886e0a9b3dSArnaldo Carvalho de Melo return 0; 21896e0a9b3dSArnaldo Carvalho de Melo 21906e0a9b3dSArnaldo Carvalho de Melo return perf_event__process_mmap2(tool, event, sample, machine); 21916e0a9b3dSArnaldo Carvalho de Melo } 21926e0a9b3dSArnaldo Carvalho de Melo 2193d20deb64SArnaldo Carvalho de Melo /* 21948c6f45a7SArnaldo Carvalho de Melo * XXX Ideally would be local to cmd_record() and passed to a record__new 21958c6f45a7SArnaldo Carvalho de Melo * because we need to have access to it in record__exit, that is called 2196d20deb64SArnaldo Carvalho de Melo * after cmd_record() exits, but since record_options need to be accessible to 2197d20deb64SArnaldo Carvalho de Melo * builtin-script, leave it here. 2198d20deb64SArnaldo Carvalho de Melo * 2199d20deb64SArnaldo Carvalho de Melo * At least we don't ouch it in all the other functions here directly. 2200d20deb64SArnaldo Carvalho de Melo * 2201d20deb64SArnaldo Carvalho de Melo * Just say no to tons of global variables, sigh. 2202d20deb64SArnaldo Carvalho de Melo */ 22038c6f45a7SArnaldo Carvalho de Melo static struct record record = { 2204d20deb64SArnaldo Carvalho de Melo .opts = { 22058affc2b8SAndi Kleen .sample_time = true, 2206d20deb64SArnaldo Carvalho de Melo .mmap_pages = UINT_MAX, 2207d20deb64SArnaldo Carvalho de Melo .user_freq = UINT_MAX, 2208d20deb64SArnaldo Carvalho de Melo .user_interval = ULLONG_MAX, 2209447a6013SArnaldo Carvalho de Melo .freq = 4000, 2210d1cb9fceSNamhyung Kim .target = { 2211d1cb9fceSNamhyung Kim .uses_mmap = true, 22123aa5939dSAdrian Hunter .default_per_cpu = true, 2213d1cb9fceSNamhyung Kim }, 2214470530bbSAlexey Budankov .mmap_flush = MMAP_FLUSH_DEFAULT, 2215d20deb64SArnaldo Carvalho de Melo }, 2216e3d59112SNamhyung Kim .tool = { 2217e3d59112SNamhyung Kim .sample = process_sample_event, 2218e3d59112SNamhyung Kim .fork = perf_event__process_fork, 2219cca8482cSAdrian Hunter .exit = perf_event__process_exit, 2220e3d59112SNamhyung Kim .comm = perf_event__process_comm, 2221f3b3614aSHari Bathini .namespaces = perf_event__process_namespaces, 22226e0a9b3dSArnaldo Carvalho de Melo .mmap = build_id__process_mmap, 22236e0a9b3dSArnaldo Carvalho de Melo .mmap2 = build_id__process_mmap2, 2224cca8482cSAdrian Hunter .ordered_events = true, 2225e3d59112SNamhyung Kim }, 2226d20deb64SArnaldo Carvalho de Melo }; 22277865e817SFrederic Weisbecker 222876a26549SNamhyung Kim const char record_callchain_help[] = CALLCHAIN_RECORD_HELP 222976a26549SNamhyung Kim "\n\t\t\t\tDefault: fp"; 223061eaa3beSArnaldo Carvalho de Melo 22310aab2136SWang Nan static bool dry_run; 22320aab2136SWang Nan 2233d20deb64SArnaldo Carvalho de Melo /* 2234d20deb64SArnaldo Carvalho de Melo * XXX Will stay a global variable till we fix builtin-script.c to stop messing 2235d20deb64SArnaldo Carvalho de Melo * with it and switch to use the library functions in perf_evlist that came 2236b4006796SArnaldo Carvalho de Melo * from builtin-record.c, i.e. use record_opts, 2237d20deb64SArnaldo Carvalho de Melo * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record', 2238d20deb64SArnaldo Carvalho de Melo * using pipes, etc. 2239d20deb64SArnaldo Carvalho de Melo */ 2240efd21307SJiri Olsa static struct option __record_options[] = { 2241d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &record.evlist, "event", 224286470930SIngo Molnar "event selector. use 'perf list' to list available events", 2243f120f9d5SJiri Olsa parse_events_option), 2244d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK(0, "filter", &record.evlist, "filter", 2245c171b552SLi Zefan "event filter", parse_filter), 22464ba1faa1SWang Nan OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist, 22474ba1faa1SWang Nan NULL, "don't record events from perf itself", 22484ba1faa1SWang Nan exclude_perf), 2249bea03405SNamhyung Kim OPT_STRING('p', "pid", &record.opts.target.pid, "pid", 2250d6d901c2SZhang, Yanmin "record events on existing process id"), 2251bea03405SNamhyung Kim OPT_STRING('t', "tid", &record.opts.target.tid, "tid", 2252d6d901c2SZhang, Yanmin "record events on existing thread id"), 2253d20deb64SArnaldo Carvalho de Melo OPT_INTEGER('r', "realtime", &record.realtime_prio, 225486470930SIngo Molnar "collect data with this RT SCHED_FIFO priority"), 2255509051eaSArnaldo Carvalho de Melo OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering, 2256acac03faSKirill Smelkov "collect data without buffering"), 2257d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples, 2258daac07b2SFrederic Weisbecker "collect raw sample records from all opened counters"), 2259bea03405SNamhyung Kim OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide, 226086470930SIngo Molnar "system-wide collection from all CPUs"), 2261bea03405SNamhyung Kim OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", 2262c45c6ea2SStephane Eranian "list of cpus to monitor"), 2263d20deb64SArnaldo Carvalho de Melo OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"), 22642d4f2799SJiri Olsa OPT_STRING('o', "output", &record.data.path, "file", 226586470930SIngo Molnar "output file name"), 226669e7e5b0SAdrian Hunter OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit, 226769e7e5b0SAdrian Hunter &record.opts.no_inherit_set, 22682e6cdf99SStephane Eranian "child tasks do not inherit counters"), 22694ea648aeSWang Nan OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize, 22704ea648aeSWang Nan "synthesize non-sample events at the end of output"), 2271626a6b78SWang Nan OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"), 227271184c6aSSong Liu OPT_BOOLEAN(0, "no-bpf-event", &record.opts.no_bpf_event, "record bpf events"), 2273b09c2364SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "strict-freq", &record.opts.strict_freq, 2274b09c2364SArnaldo Carvalho de Melo "Fail if the specified frequency can't be used"), 227567230479SArnaldo Carvalho de Melo OPT_CALLBACK('F', "freq", &record.opts, "freq or 'max'", 227667230479SArnaldo Carvalho de Melo "profile at this frequency", 227767230479SArnaldo Carvalho de Melo record__parse_freq), 2278e9db1310SAdrian Hunter OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]", 2279e9db1310SAdrian Hunter "number of mmap data pages and AUX area tracing mmap pages", 2280e9db1310SAdrian Hunter record__parse_mmap_pages), 2281470530bbSAlexey Budankov OPT_CALLBACK(0, "mmap-flush", &record.opts, "number", 2282470530bbSAlexey Budankov "Minimal number of bytes that is extracted from mmap data pages (default: 1)", 2283470530bbSAlexey Budankov record__mmap_flush_parse), 2284d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "group", &record.opts.group, 228543bece79SLin Ming "put the counters into a counter group"), 22862ddd5c04SArnaldo Carvalho de Melo OPT_CALLBACK_NOOPT('g', NULL, &callchain_param, 228709b0fd45SJiri Olsa NULL, "enables call-graph recording" , 228809b0fd45SJiri Olsa &record_callchain_opt), 228909b0fd45SJiri Olsa OPT_CALLBACK(0, "call-graph", &record.opts, 229076a26549SNamhyung Kim "record_mode[,record_size]", record_callchain_help, 229109b0fd45SJiri Olsa &record_parse_callchain_opt), 2292c0555642SIan Munsie OPT_INCR('v', "verbose", &verbose, 22933da297a6SIngo Molnar "be more verbose (show counter open errors, etc)"), 2294b44308f5SArnaldo Carvalho de Melo OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"), 2295d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat, 2296649c48a9SPeter Zijlstra "per thread counts"), 229756100321SPeter Zijlstra OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"), 22983b0a5daaSKan Liang OPT_BOOLEAN(0, "phys-data", &record.opts.sample_phys_addr, 22993b0a5daaSKan Liang "Record the sample physical addresses"), 2300b6f35ed7SJiri Olsa OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"), 23013abebc55SAdrian Hunter OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time, 23023abebc55SAdrian Hunter &record.opts.sample_time_set, 23033abebc55SAdrian Hunter "Record the sample timestamps"), 2304f290aa1fSJiri Olsa OPT_BOOLEAN_SET('P', "period", &record.opts.period, &record.opts.period_set, 2305f290aa1fSJiri Olsa "Record the sample period"), 2306d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples, 2307649c48a9SPeter Zijlstra "don't sample"), 2308d2db9a98SWang Nan OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache, 2309d2db9a98SWang Nan &record.no_buildid_cache_set, 2310a1ac1d3cSStephane Eranian "do not update the buildid cache"), 2311d2db9a98SWang Nan OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid, 2312d2db9a98SWang Nan &record.no_buildid_set, 2313baa2f6ceSArnaldo Carvalho de Melo "do not collect buildids in perf.data"), 2314d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK('G', "cgroup", &record.evlist, "name", 2315023695d9SStephane Eranian "monitor event in cgroup name only", 2316023695d9SStephane Eranian parse_cgroups), 2317a6205a35SArnaldo Carvalho de Melo OPT_UINTEGER('D', "delay", &record.opts.initial_delay, 23186619a53eSAndi Kleen "ms to wait before starting measurement after program start"), 2319eeb399b5SAdrian Hunter OPT_BOOLEAN(0, "kcore", &record.opts.kcore, "copy /proc/kcore"), 2320bea03405SNamhyung Kim OPT_STRING('u', "uid", &record.opts.target.uid_str, "user", 2321bea03405SNamhyung Kim "user to profile"), 2322a5aabdacSStephane Eranian 2323a5aabdacSStephane Eranian OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack, 2324a5aabdacSStephane Eranian "branch any", "sample any taken branches", 2325a5aabdacSStephane Eranian parse_branch_stack), 2326a5aabdacSStephane Eranian 2327a5aabdacSStephane Eranian OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack, 2328a5aabdacSStephane Eranian "branch filter mask", "branch stack filter modes", 2329bdfebd84SRoberto Agostino Vitillo parse_branch_stack), 233005484298SAndi Kleen OPT_BOOLEAN('W', "weight", &record.opts.sample_weight, 233105484298SAndi Kleen "sample by weight (on special events only)"), 2332475eeab9SAndi Kleen OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction, 2333475eeab9SAndi Kleen "sample transaction flags (special events only)"), 23343aa5939dSAdrian Hunter OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread, 23353aa5939dSAdrian Hunter "use per-thread mmaps"), 2336bcc84ec6SStephane Eranian OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register", 2337bcc84ec6SStephane Eranian "sample selected machine registers on interrupt," 2338aeea9062SKan Liang " use '-I?' to list register names", parse_intr_regs), 233984c41742SAndi Kleen OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register", 234084c41742SAndi Kleen "sample selected machine registers on interrupt," 2341aeea9062SKan Liang " use '--user-regs=?' to list register names", parse_user_regs), 234285c273d2SAndi Kleen OPT_BOOLEAN(0, "running-time", &record.opts.running_time, 234385c273d2SAndi Kleen "Record running/enabled time of read (:S) events"), 2344814c8c38SPeter Zijlstra OPT_CALLBACK('k', "clockid", &record.opts, 2345814c8c38SPeter Zijlstra "clockid", "clockid to use for events, see clock_gettime()", 2346814c8c38SPeter Zijlstra parse_clockid), 23472dd6d8a1SAdrian Hunter OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts, 23482dd6d8a1SAdrian Hunter "opts", "AUX area tracing Snapshot Mode", ""), 2349c0a6de06SAdrian Hunter OPT_STRING_OPTARG(0, "aux-sample", &record.opts.auxtrace_sample_opts, 2350c0a6de06SAdrian Hunter "opts", "sample AUX area", ""), 23513fcb10e4SMark Drayton OPT_UINTEGER(0, "proc-map-timeout", &proc_map_timeout, 23529d9cad76SKan Liang "per thread proc mmap processing timeout in ms"), 2353f3b3614aSHari Bathini OPT_BOOLEAN(0, "namespaces", &record.opts.record_namespaces, 2354f3b3614aSHari Bathini "Record namespaces events"), 2355b757bb09SAdrian Hunter OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events, 2356b757bb09SAdrian Hunter "Record context switch events"), 235785723885SJiri Olsa OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel, 235885723885SJiri Olsa "Configure all used events to run in kernel space.", 235985723885SJiri Olsa PARSE_OPT_EXCLUSIVE), 236085723885SJiri Olsa OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user, 236185723885SJiri Olsa "Configure all used events to run in user space.", 236285723885SJiri Olsa PARSE_OPT_EXCLUSIVE), 236353651b28Syuzhoujian OPT_BOOLEAN(0, "kernel-callchains", &record.opts.kernel_callchains, 236453651b28Syuzhoujian "collect kernel callchains"), 236553651b28Syuzhoujian OPT_BOOLEAN(0, "user-callchains", &record.opts.user_callchains, 236653651b28Syuzhoujian "collect user callchains"), 236771dc2326SWang Nan OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", 236871dc2326SWang Nan "clang binary to use for compiling BPF scriptlets"), 236971dc2326SWang Nan OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", 237071dc2326SWang Nan "options passed to clang when compiling BPF scriptlets"), 23717efe0e03SHe Kuang OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, 23727efe0e03SHe Kuang "file", "vmlinux pathname"), 23736156681bSNamhyung Kim OPT_BOOLEAN(0, "buildid-all", &record.buildid_all, 23746156681bSNamhyung Kim "Record build-id of all DSOs regardless of hits"), 2375ecfd7a9cSWang Nan OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename, 2376ecfd7a9cSWang Nan "append timestamp to output filename"), 237768588bafSJin Yao OPT_BOOLEAN(0, "timestamp-boundary", &record.timestamp_boundary, 237868588bafSJin Yao "Record timestamp boundary (time of first/last samples)"), 2379cb4e1ebbSJiri Olsa OPT_STRING_OPTARG_SET(0, "switch-output", &record.switch_output.str, 2380c38dab7dSAndi Kleen &record.switch_output.set, "signal or size[BKMG] or time[smhd]", 2381c38dab7dSAndi Kleen "Switch output when receiving SIGUSR2 (signal) or cross a size or time threshold", 2382dc0c6127SJiri Olsa "signal"), 238303724b2eSAndi Kleen OPT_INTEGER(0, "switch-max-files", &record.switch_output.num_files, 238403724b2eSAndi Kleen "Limit number of switch output generated files"), 23850aab2136SWang Nan OPT_BOOLEAN(0, "dry-run", &dry_run, 23860aab2136SWang Nan "Parse options then exit"), 2387d3d1af6fSAlexey Budankov #ifdef HAVE_AIO_SUPPORT 238893f20c0fSAlexey Budankov OPT_CALLBACK_OPTARG(0, "aio", &record.opts, 238993f20c0fSAlexey Budankov &nr_cblocks_default, "n", "Use <n> control blocks in asynchronous trace writing mode (default: 1, max: 4)", 2390d3d1af6fSAlexey Budankov record__aio_parse), 2391d3d1af6fSAlexey Budankov #endif 2392f4fe11b7SAlexey Budankov OPT_CALLBACK(0, "affinity", &record.opts, "node|cpu", 2393f4fe11b7SAlexey Budankov "Set affinity mask of trace reading thread to NUMA node cpu mask or cpu of processed mmap buffer", 2394f4fe11b7SAlexey Budankov record__parse_affinity), 2395504c1ad1SAlexey Budankov #ifdef HAVE_ZSTD_SUPPORT 2396504c1ad1SAlexey Budankov OPT_CALLBACK_OPTARG('z', "compression-level", &record.opts, &comp_level_default, 2397504c1ad1SAlexey Budankov "n", "Compressed records using specified level (default: 1 - fastest compression, 22 - greatest compression)", 2398504c1ad1SAlexey Budankov record__parse_comp_level), 2399504c1ad1SAlexey Budankov #endif 24006d575816SJiwei Sun OPT_CALLBACK(0, "max-size", &record.output_max_size, 24016d575816SJiwei Sun "size", "Limit the maximum size of the output file", parse_output_max_size), 240286470930SIngo Molnar OPT_END() 240386470930SIngo Molnar }; 240486470930SIngo Molnar 2405e5b2c207SNamhyung Kim struct option *record_options = __record_options; 2406e5b2c207SNamhyung Kim 2407b0ad8ea6SArnaldo Carvalho de Melo int cmd_record(int argc, const char **argv) 240886470930SIngo Molnar { 2409ef149c25SAdrian Hunter int err; 24108c6f45a7SArnaldo Carvalho de Melo struct record *rec = &record; 241116ad2ffbSNamhyung Kim char errbuf[BUFSIZ]; 241286470930SIngo Molnar 241367230479SArnaldo Carvalho de Melo setlocale(LC_ALL, ""); 241467230479SArnaldo Carvalho de Melo 241548e1cab1SWang Nan #ifndef HAVE_LIBBPF_SUPPORT 241648e1cab1SWang Nan # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c) 241748e1cab1SWang Nan set_nobuild('\0', "clang-path", true); 241848e1cab1SWang Nan set_nobuild('\0', "clang-opt", true); 241948e1cab1SWang Nan # undef set_nobuild 242048e1cab1SWang Nan #endif 242148e1cab1SWang Nan 24227efe0e03SHe Kuang #ifndef HAVE_BPF_PROLOGUE 24237efe0e03SHe Kuang # if !defined (HAVE_DWARF_SUPPORT) 24247efe0e03SHe Kuang # define REASON "NO_DWARF=1" 24257efe0e03SHe Kuang # elif !defined (HAVE_LIBBPF_SUPPORT) 24267efe0e03SHe Kuang # define REASON "NO_LIBBPF=1" 24277efe0e03SHe Kuang # else 24287efe0e03SHe Kuang # define REASON "this architecture doesn't support BPF prologue" 24297efe0e03SHe Kuang # endif 24307efe0e03SHe Kuang # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c) 24317efe0e03SHe Kuang set_nobuild('\0', "vmlinux", true); 24327efe0e03SHe Kuang # undef set_nobuild 24337efe0e03SHe Kuang # undef REASON 24347efe0e03SHe Kuang #endif 24357efe0e03SHe Kuang 24369d2ed645SAlexey Budankov CPU_ZERO(&rec->affinity_mask); 24379d2ed645SAlexey Budankov rec->opts.affinity = PERF_AFFINITY_SYS; 24389d2ed645SAlexey Budankov 24390f98b11cSJiri Olsa rec->evlist = evlist__new(); 24403e2be2daSArnaldo Carvalho de Melo if (rec->evlist == NULL) 2441361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 2442361c99a6SArnaldo Carvalho de Melo 2443ecc4c561SArnaldo Carvalho de Melo err = perf_config(perf_record_config, rec); 2444ecc4c561SArnaldo Carvalho de Melo if (err) 2445ecc4c561SArnaldo Carvalho de Melo return err; 2446eb853e80SJiri Olsa 2447bca647aaSTom Zanussi argc = parse_options(argc, argv, record_options, record_usage, 2448a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 244968ba3235SNamhyung Kim if (quiet) 245068ba3235SNamhyung Kim perf_quiet_option(); 2451483635a9SJiri Olsa 2452483635a9SJiri Olsa /* Make system wide (-a) the default target. */ 2453602ad878SArnaldo Carvalho de Melo if (!argc && target__none(&rec->opts.target)) 2454483635a9SJiri Olsa rec->opts.target.system_wide = true; 245586470930SIngo Molnar 2456bea03405SNamhyung Kim if (nr_cgroups && !rec->opts.target.system_wide) { 2457c7118369SNamhyung Kim usage_with_options_msg(record_usage, record_options, 2458c7118369SNamhyung Kim "cgroup monitoring only available in system-wide mode"); 2459c7118369SNamhyung Kim 2460023695d9SStephane Eranian } 2461504c1ad1SAlexey Budankov 2462eeb399b5SAdrian Hunter if (rec->opts.kcore) 2463eeb399b5SAdrian Hunter rec->data.is_dir = true; 2464eeb399b5SAdrian Hunter 2465504c1ad1SAlexey Budankov if (rec->opts.comp_level != 0) { 2466504c1ad1SAlexey Budankov pr_debug("Compression enabled, disabling build id collection at the end of the session.\n"); 2467504c1ad1SAlexey Budankov rec->no_buildid = true; 2468504c1ad1SAlexey Budankov } 2469504c1ad1SAlexey Budankov 2470b757bb09SAdrian Hunter if (rec->opts.record_switch_events && 2471b757bb09SAdrian Hunter !perf_can_record_switch_events()) { 2472c7118369SNamhyung Kim ui__error("kernel does not support recording context switch events\n"); 2473c7118369SNamhyung Kim parse_options_usage(record_usage, record_options, "switch-events", 0); 2474c7118369SNamhyung Kim return -EINVAL; 2475b757bb09SAdrian Hunter } 2476023695d9SStephane Eranian 2477cb4e1ebbSJiri Olsa if (switch_output_setup(rec)) { 2478cb4e1ebbSJiri Olsa parse_options_usage(record_usage, record_options, "switch-output", 0); 2479cb4e1ebbSJiri Olsa return -EINVAL; 2480cb4e1ebbSJiri Olsa } 2481cb4e1ebbSJiri Olsa 2482bfacbe3bSJiri Olsa if (rec->switch_output.time) { 2483bfacbe3bSJiri Olsa signal(SIGALRM, alarm_sig_handler); 2484bfacbe3bSJiri Olsa alarm(rec->switch_output.time); 2485bfacbe3bSJiri Olsa } 2486bfacbe3bSJiri Olsa 248703724b2eSAndi Kleen if (rec->switch_output.num_files) { 248803724b2eSAndi Kleen rec->switch_output.filenames = calloc(sizeof(char *), 248903724b2eSAndi Kleen rec->switch_output.num_files); 249003724b2eSAndi Kleen if (!rec->switch_output.filenames) 249103724b2eSAndi Kleen return -EINVAL; 249203724b2eSAndi Kleen } 249303724b2eSAndi Kleen 24941b36c03eSAdrian Hunter /* 24951b36c03eSAdrian Hunter * Allow aliases to facilitate the lookup of symbols for address 24961b36c03eSAdrian Hunter * filters. Refer to auxtrace_parse_filters(). 24971b36c03eSAdrian Hunter */ 24981b36c03eSAdrian Hunter symbol_conf.allow_aliases = true; 24991b36c03eSAdrian Hunter 25001b36c03eSAdrian Hunter symbol__init(NULL); 25011b36c03eSAdrian Hunter 25024b5ea3bdSAdrian Hunter err = record__auxtrace_init(rec); 25031b36c03eSAdrian Hunter if (err) 25041b36c03eSAdrian Hunter goto out; 25051b36c03eSAdrian Hunter 25060aab2136SWang Nan if (dry_run) 25075c01ad60SAdrian Hunter goto out; 25080aab2136SWang Nan 2509d7888573SWang Nan err = bpf__setup_stdout(rec->evlist); 2510d7888573SWang Nan if (err) { 2511d7888573SWang Nan bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf)); 2512d7888573SWang Nan pr_err("ERROR: Setup BPF stdout failed: %s\n", 2513d7888573SWang Nan errbuf); 25145c01ad60SAdrian Hunter goto out; 2515d7888573SWang Nan } 2516d7888573SWang Nan 2517ef149c25SAdrian Hunter err = -ENOMEM; 2518ef149c25SAdrian Hunter 25190c1d46a8SWang Nan if (rec->no_buildid_cache || rec->no_buildid) { 2520a1ac1d3cSStephane Eranian disable_buildid_cache(); 2521dc0c6127SJiri Olsa } else if (rec->switch_output.enabled) { 25220c1d46a8SWang Nan /* 25230c1d46a8SWang Nan * In 'perf record --switch-output', disable buildid 25240c1d46a8SWang Nan * generation by default to reduce data file switching 25250c1d46a8SWang Nan * overhead. Still generate buildid if they are required 25260c1d46a8SWang Nan * explicitly using 25270c1d46a8SWang Nan * 252860437ac0SJiri Olsa * perf record --switch-output --no-no-buildid \ 25290c1d46a8SWang Nan * --no-no-buildid-cache 25300c1d46a8SWang Nan * 25310c1d46a8SWang Nan * Following code equals to: 25320c1d46a8SWang Nan * 25330c1d46a8SWang Nan * if ((rec->no_buildid || !rec->no_buildid_set) && 25340c1d46a8SWang Nan * (rec->no_buildid_cache || !rec->no_buildid_cache_set)) 25350c1d46a8SWang Nan * disable_buildid_cache(); 25360c1d46a8SWang Nan */ 25370c1d46a8SWang Nan bool disable = true; 25380c1d46a8SWang Nan 25390c1d46a8SWang Nan if (rec->no_buildid_set && !rec->no_buildid) 25400c1d46a8SWang Nan disable = false; 25410c1d46a8SWang Nan if (rec->no_buildid_cache_set && !rec->no_buildid_cache) 25420c1d46a8SWang Nan disable = false; 25430c1d46a8SWang Nan if (disable) { 25440c1d46a8SWang Nan rec->no_buildid = true; 25450c1d46a8SWang Nan rec->no_buildid_cache = true; 25460c1d46a8SWang Nan disable_buildid_cache(); 25470c1d46a8SWang Nan } 25480c1d46a8SWang Nan } 2549655000e7SArnaldo Carvalho de Melo 25504ea648aeSWang Nan if (record.opts.overwrite) 25514ea648aeSWang Nan record.opts.tail_synthesize = true; 25524ea648aeSWang Nan 25536484d2f9SJiri Olsa if (rec->evlist->core.nr_entries == 0 && 25544b4cd503SArnaldo Carvalho de Melo __perf_evlist__add_default(rec->evlist, !record.opts.no_samples) < 0) { 255569aad6f1SArnaldo Carvalho de Melo pr_err("Not enough memory for event selector list\n"); 2556394c01edSAdrian Hunter goto out; 2557bbd36e5eSPeter Zijlstra } 255886470930SIngo Molnar 255969e7e5b0SAdrian Hunter if (rec->opts.target.tid && !rec->opts.no_inherit_set) 256069e7e5b0SAdrian Hunter rec->opts.no_inherit = true; 256169e7e5b0SAdrian Hunter 2562602ad878SArnaldo Carvalho de Melo err = target__validate(&rec->opts.target); 256316ad2ffbSNamhyung Kim if (err) { 2564602ad878SArnaldo Carvalho de Melo target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); 2565c3dec27bSJiri Olsa ui__warning("%s\n", errbuf); 256616ad2ffbSNamhyung Kim } 25674bd0f2d2SNamhyung Kim 2568602ad878SArnaldo Carvalho de Melo err = target__parse_uid(&rec->opts.target); 256916ad2ffbSNamhyung Kim if (err) { 257016ad2ffbSNamhyung Kim int saved_errno = errno; 257116ad2ffbSNamhyung Kim 2572602ad878SArnaldo Carvalho de Melo target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); 25733780f488SNamhyung Kim ui__error("%s", errbuf); 257416ad2ffbSNamhyung Kim 257516ad2ffbSNamhyung Kim err = -saved_errno; 2576394c01edSAdrian Hunter goto out; 257716ad2ffbSNamhyung Kim } 25780d37aa34SArnaldo Carvalho de Melo 2579ca800068SMengting Zhang /* Enable ignoring missing threads when -u/-p option is defined. */ 2580ca800068SMengting Zhang rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX || rec->opts.target.pid; 258123dc4f15SJiri Olsa 258216ad2ffbSNamhyung Kim err = -ENOMEM; 25833e2be2daSArnaldo Carvalho de Melo if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0) 2584dd7927f4SArnaldo Carvalho de Melo usage_with_options(record_usage, record_options); 258569aad6f1SArnaldo Carvalho de Melo 2586ef149c25SAdrian Hunter err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts); 2587ef149c25SAdrian Hunter if (err) 2588394c01edSAdrian Hunter goto out; 2589ef149c25SAdrian Hunter 25906156681bSNamhyung Kim /* 25916156681bSNamhyung Kim * We take all buildids when the file contains 25926156681bSNamhyung Kim * AUX area tracing data because we do not decode the 25936156681bSNamhyung Kim * trace because it would take too long. 25946156681bSNamhyung Kim */ 25956156681bSNamhyung Kim if (rec->opts.full_auxtrace) 25966156681bSNamhyung Kim rec->buildid_all = true; 25976156681bSNamhyung Kim 2598b4006796SArnaldo Carvalho de Melo if (record_opts__config(&rec->opts)) { 259939d17dacSArnaldo Carvalho de Melo err = -EINVAL; 2600394c01edSAdrian Hunter goto out; 26017e4ff9e3SMike Galbraith } 26027e4ff9e3SMike Galbraith 260393f20c0fSAlexey Budankov if (rec->opts.nr_cblocks > nr_cblocks_max) 260493f20c0fSAlexey Budankov rec->opts.nr_cblocks = nr_cblocks_max; 26055d7f4116SAlexey Budankov pr_debug("nr_cblocks: %d\n", rec->opts.nr_cblocks); 2606d3d1af6fSAlexey Budankov 26079d2ed645SAlexey Budankov pr_debug("affinity: %s\n", affinity_tags[rec->opts.affinity]); 2608470530bbSAlexey Budankov pr_debug("mmap flush: %d\n", rec->opts.mmap_flush); 26099d2ed645SAlexey Budankov 261051255a8aSAlexey Budankov if (rec->opts.comp_level > comp_level_max) 261151255a8aSAlexey Budankov rec->opts.comp_level = comp_level_max; 261251255a8aSAlexey Budankov pr_debug("comp level: %d\n", rec->opts.comp_level); 261351255a8aSAlexey Budankov 2614d20deb64SArnaldo Carvalho de Melo err = __cmd_record(&record, argc, argv); 2615394c01edSAdrian Hunter out: 2616c12995a5SJiri Olsa evlist__delete(rec->evlist); 2617d65a458bSArnaldo Carvalho de Melo symbol__exit(); 2618ef149c25SAdrian Hunter auxtrace_record__free(rec->itr); 261939d17dacSArnaldo Carvalho de Melo return err; 262086470930SIngo Molnar } 26212dd6d8a1SAdrian Hunter 26222dd6d8a1SAdrian Hunter static void snapshot_sig_handler(int sig __maybe_unused) 26232dd6d8a1SAdrian Hunter { 2624dc0c6127SJiri Olsa struct record *rec = &record; 2625dc0c6127SJiri Olsa 26265f9cf599SWang Nan if (trigger_is_ready(&auxtrace_snapshot_trigger)) { 26275f9cf599SWang Nan trigger_hit(&auxtrace_snapshot_trigger); 26282dd6d8a1SAdrian Hunter auxtrace_record__snapshot_started = 1; 26295f9cf599SWang Nan if (auxtrace_record__snapshot_start(record.itr)) 26305f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 26315f9cf599SWang Nan } 26323c1cb7e3SWang Nan 2633dc0c6127SJiri Olsa if (switch_output_signal(rec)) 26343c1cb7e3SWang Nan trigger_hit(&switch_output_trigger); 26352dd6d8a1SAdrian Hunter } 2636bfacbe3bSJiri Olsa 2637bfacbe3bSJiri Olsa static void alarm_sig_handler(int sig __maybe_unused) 2638bfacbe3bSJiri Olsa { 2639bfacbe3bSJiri Olsa struct record *rec = &record; 2640bfacbe3bSJiri Olsa 2641bfacbe3bSJiri Olsa if (switch_output_time(rec)) 2642bfacbe3bSJiri Olsa trigger_hit(&switch_output_trigger); 2643bfacbe3bSJiri Olsa } 2644