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 1186470930SIngo Molnar #include "perf.h" 1286470930SIngo Molnar 136122e4e4SArnaldo Carvalho de Melo #include "util/build-id.h" 1486470930SIngo Molnar #include "util/util.h" 154b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h> 1686470930SIngo Molnar #include "util/parse-events.h" 1741840d21STaeung Song #include "util/config.h" 1886470930SIngo Molnar 198f651eaeSArnaldo Carvalho de Melo #include "util/callchain.h" 20f14d5707SArnaldo Carvalho de Melo #include "util/cgroup.h" 217c6a1c65SPeter Zijlstra #include "util/header.h" 2266e274f3SFrederic Weisbecker #include "util/event.h" 23361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h" 2469aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h" 258f28827aSFrederic Weisbecker #include "util/debug.h" 265d8bb1ecSMathieu Poirier #include "util/drv_configs.h" 2794c744b6SArnaldo Carvalho de Melo #include "util/session.h" 2845694aa7SArnaldo Carvalho de Melo #include "util/tool.h" 298d06367fSArnaldo Carvalho de Melo #include "util/symbol.h" 30a12b51c4SPaul Mackerras #include "util/cpumap.h" 31fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 32f5fc1412SJiri Olsa #include "util/data.h" 33bcc84ec6SStephane Eranian #include "util/perf_regs.h" 34ef149c25SAdrian Hunter #include "util/auxtrace.h" 3546bc29b9SAdrian Hunter #include "util/tsc.h" 36f00898f4SAndi Kleen #include "util/parse-branch-options.h" 37bcc84ec6SStephane Eranian #include "util/parse-regs-options.h" 3871dc2326SWang Nan #include "util/llvm-utils.h" 398690a2a7SWang Nan #include "util/bpf-loader.h" 405f9cf599SWang Nan #include "util/trigger.h" 41a074865eSWang Nan #include "util/perf-hooks.h" 42c5e4027eSArnaldo Carvalho de Melo #include "util/time-utils.h" 4358db1d6eSArnaldo Carvalho de Melo #include "util/units.h" 44d8871ea7SWang Nan #include "asm/bug.h" 457c6a1c65SPeter Zijlstra 46a43783aeSArnaldo Carvalho de Melo #include <errno.h> 47fd20e811SArnaldo Carvalho de Melo #include <inttypes.h> 4867230479SArnaldo Carvalho de Melo #include <locale.h> 494208735dSArnaldo Carvalho de Melo #include <poll.h> 5086470930SIngo Molnar #include <unistd.h> 5186470930SIngo Molnar #include <sched.h> 529607ad3aSArnaldo Carvalho de Melo #include <signal.h> 53a41794cdSArnaldo Carvalho de Melo #include <sys/mman.h> 544208735dSArnaldo Carvalho de Melo #include <sys/wait.h> 550693e680SArnaldo Carvalho de Melo #include <linux/time64.h> 5678da39faSBernhard Rosenkraenzer 571b43b704SJiri Olsa struct switch_output { 58dc0c6127SJiri Olsa bool enabled; 591b43b704SJiri Olsa bool signal; 60dc0c6127SJiri Olsa unsigned long size; 61bfacbe3bSJiri Olsa unsigned long time; 62cb4e1ebbSJiri Olsa const char *str; 63cb4e1ebbSJiri Olsa bool set; 641b43b704SJiri Olsa }; 651b43b704SJiri Olsa 668c6f45a7SArnaldo Carvalho de Melo struct record { 6745694aa7SArnaldo Carvalho de Melo struct perf_tool tool; 68b4006796SArnaldo Carvalho de Melo struct record_opts opts; 69d20deb64SArnaldo Carvalho de Melo u64 bytes_written; 708ceb41d7SJiri Olsa struct perf_data data; 71ef149c25SAdrian Hunter struct auxtrace_record *itr; 72d20deb64SArnaldo Carvalho de Melo struct perf_evlist *evlist; 73d20deb64SArnaldo Carvalho de Melo struct perf_session *session; 74d20deb64SArnaldo Carvalho de Melo int realtime_prio; 75d20deb64SArnaldo Carvalho de Melo bool no_buildid; 76d2db9a98SWang Nan bool no_buildid_set; 77d20deb64SArnaldo Carvalho de Melo bool no_buildid_cache; 78d2db9a98SWang Nan bool no_buildid_cache_set; 796156681bSNamhyung Kim bool buildid_all; 80ecfd7a9cSWang Nan bool timestamp_filename; 8168588bafSJin Yao bool timestamp_boundary; 821b43b704SJiri Olsa struct switch_output switch_output; 839f065194SYang Shi unsigned long long samples; 840f82ebc4SArnaldo Carvalho de Melo }; 8586470930SIngo Molnar 86dc0c6127SJiri Olsa static volatile int auxtrace_record__snapshot_started; 87dc0c6127SJiri Olsa static DEFINE_TRIGGER(auxtrace_snapshot_trigger); 88dc0c6127SJiri Olsa static DEFINE_TRIGGER(switch_output_trigger); 89dc0c6127SJiri Olsa 90dc0c6127SJiri Olsa static bool switch_output_signal(struct record *rec) 91dc0c6127SJiri Olsa { 92dc0c6127SJiri Olsa return rec->switch_output.signal && 93dc0c6127SJiri Olsa trigger_is_ready(&switch_output_trigger); 94dc0c6127SJiri Olsa } 95dc0c6127SJiri Olsa 96dc0c6127SJiri Olsa static bool switch_output_size(struct record *rec) 97dc0c6127SJiri Olsa { 98dc0c6127SJiri Olsa return rec->switch_output.size && 99dc0c6127SJiri Olsa trigger_is_ready(&switch_output_trigger) && 100dc0c6127SJiri Olsa (rec->bytes_written >= rec->switch_output.size); 101dc0c6127SJiri Olsa } 102dc0c6127SJiri Olsa 103bfacbe3bSJiri Olsa static bool switch_output_time(struct record *rec) 104bfacbe3bSJiri Olsa { 105bfacbe3bSJiri Olsa return rec->switch_output.time && 106bfacbe3bSJiri Olsa trigger_is_ready(&switch_output_trigger); 107bfacbe3bSJiri Olsa } 108bfacbe3bSJiri Olsa 109ded2b8feSJiri Olsa static int record__write(struct record *rec, struct perf_mmap *map __maybe_unused, 110ded2b8feSJiri Olsa void *bf, size_t size) 111f5970550SPeter Zijlstra { 112ded2b8feSJiri Olsa struct perf_data_file *file = &rec->session->data->file; 113ded2b8feSJiri Olsa 114ded2b8feSJiri Olsa if (perf_data_file__write(file, bf, size) < 0) { 1154f624685SAdrian Hunter pr_err("failed to write perf data, error: %m\n"); 1168d3eca20SDavid Ahern return -1; 1178d3eca20SDavid Ahern } 118f5970550SPeter Zijlstra 119cf8b2e69SArnaldo Carvalho de Melo rec->bytes_written += size; 120dc0c6127SJiri Olsa 121dc0c6127SJiri Olsa if (switch_output_size(rec)) 122dc0c6127SJiri Olsa trigger_hit(&switch_output_trigger); 123dc0c6127SJiri Olsa 1248d3eca20SDavid Ahern return 0; 125f5970550SPeter Zijlstra } 126f5970550SPeter Zijlstra 127*d3d1af6fSAlexey Budankov #ifdef HAVE_AIO_SUPPORT 128*d3d1af6fSAlexey Budankov static int record__aio_write(struct aiocb *cblock, int trace_fd, 129*d3d1af6fSAlexey Budankov void *buf, size_t size, off_t off) 130*d3d1af6fSAlexey Budankov { 131*d3d1af6fSAlexey Budankov int rc; 132*d3d1af6fSAlexey Budankov 133*d3d1af6fSAlexey Budankov cblock->aio_fildes = trace_fd; 134*d3d1af6fSAlexey Budankov cblock->aio_buf = buf; 135*d3d1af6fSAlexey Budankov cblock->aio_nbytes = size; 136*d3d1af6fSAlexey Budankov cblock->aio_offset = off; 137*d3d1af6fSAlexey Budankov cblock->aio_sigevent.sigev_notify = SIGEV_NONE; 138*d3d1af6fSAlexey Budankov 139*d3d1af6fSAlexey Budankov do { 140*d3d1af6fSAlexey Budankov rc = aio_write(cblock); 141*d3d1af6fSAlexey Budankov if (rc == 0) { 142*d3d1af6fSAlexey Budankov break; 143*d3d1af6fSAlexey Budankov } else if (errno != EAGAIN) { 144*d3d1af6fSAlexey Budankov cblock->aio_fildes = -1; 145*d3d1af6fSAlexey Budankov pr_err("failed to queue perf data, error: %m\n"); 146*d3d1af6fSAlexey Budankov break; 147*d3d1af6fSAlexey Budankov } 148*d3d1af6fSAlexey Budankov } while (1); 149*d3d1af6fSAlexey Budankov 150*d3d1af6fSAlexey Budankov return rc; 151*d3d1af6fSAlexey Budankov } 152*d3d1af6fSAlexey Budankov 153*d3d1af6fSAlexey Budankov static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock) 154*d3d1af6fSAlexey Budankov { 155*d3d1af6fSAlexey Budankov void *rem_buf; 156*d3d1af6fSAlexey Budankov off_t rem_off; 157*d3d1af6fSAlexey Budankov size_t rem_size; 158*d3d1af6fSAlexey Budankov int rc, aio_errno; 159*d3d1af6fSAlexey Budankov ssize_t aio_ret, written; 160*d3d1af6fSAlexey Budankov 161*d3d1af6fSAlexey Budankov aio_errno = aio_error(cblock); 162*d3d1af6fSAlexey Budankov if (aio_errno == EINPROGRESS) 163*d3d1af6fSAlexey Budankov return 0; 164*d3d1af6fSAlexey Budankov 165*d3d1af6fSAlexey Budankov written = aio_ret = aio_return(cblock); 166*d3d1af6fSAlexey Budankov if (aio_ret < 0) { 167*d3d1af6fSAlexey Budankov if (aio_errno != EINTR) 168*d3d1af6fSAlexey Budankov pr_err("failed to write perf data, error: %m\n"); 169*d3d1af6fSAlexey Budankov written = 0; 170*d3d1af6fSAlexey Budankov } 171*d3d1af6fSAlexey Budankov 172*d3d1af6fSAlexey Budankov rem_size = cblock->aio_nbytes - written; 173*d3d1af6fSAlexey Budankov 174*d3d1af6fSAlexey Budankov if (rem_size == 0) { 175*d3d1af6fSAlexey Budankov cblock->aio_fildes = -1; 176*d3d1af6fSAlexey Budankov /* 177*d3d1af6fSAlexey Budankov * md->refcount is incremented in perf_mmap__push() for 178*d3d1af6fSAlexey Budankov * every enqueued aio write request so decrement it because 179*d3d1af6fSAlexey Budankov * the request is now complete. 180*d3d1af6fSAlexey Budankov */ 181*d3d1af6fSAlexey Budankov perf_mmap__put(md); 182*d3d1af6fSAlexey Budankov rc = 1; 183*d3d1af6fSAlexey Budankov } else { 184*d3d1af6fSAlexey Budankov /* 185*d3d1af6fSAlexey Budankov * aio write request may require restart with the 186*d3d1af6fSAlexey Budankov * reminder if the kernel didn't write whole 187*d3d1af6fSAlexey Budankov * chunk at once. 188*d3d1af6fSAlexey Budankov */ 189*d3d1af6fSAlexey Budankov rem_off = cblock->aio_offset + written; 190*d3d1af6fSAlexey Budankov rem_buf = (void *)(cblock->aio_buf + written); 191*d3d1af6fSAlexey Budankov record__aio_write(cblock, cblock->aio_fildes, 192*d3d1af6fSAlexey Budankov rem_buf, rem_size, rem_off); 193*d3d1af6fSAlexey Budankov rc = 0; 194*d3d1af6fSAlexey Budankov } 195*d3d1af6fSAlexey Budankov 196*d3d1af6fSAlexey Budankov return rc; 197*d3d1af6fSAlexey Budankov } 198*d3d1af6fSAlexey Budankov 199*d3d1af6fSAlexey Budankov static void record__aio_sync(struct perf_mmap *md) 200*d3d1af6fSAlexey Budankov { 201*d3d1af6fSAlexey Budankov struct aiocb *cblock = &md->aio.cblock; 202*d3d1af6fSAlexey Budankov struct timespec timeout = { 0, 1000 * 1000 * 1 }; /* 1ms */ 203*d3d1af6fSAlexey Budankov 204*d3d1af6fSAlexey Budankov do { 205*d3d1af6fSAlexey Budankov if (cblock->aio_fildes == -1 || record__aio_complete(md, cblock)) 206*d3d1af6fSAlexey Budankov return; 207*d3d1af6fSAlexey Budankov 208*d3d1af6fSAlexey Budankov while (aio_suspend((const struct aiocb**)&cblock, 1, &timeout)) { 209*d3d1af6fSAlexey Budankov if (!(errno == EAGAIN || errno == EINTR)) 210*d3d1af6fSAlexey Budankov pr_err("failed to sync perf data, error: %m\n"); 211*d3d1af6fSAlexey Budankov } 212*d3d1af6fSAlexey Budankov } while (1); 213*d3d1af6fSAlexey Budankov } 214*d3d1af6fSAlexey Budankov 215*d3d1af6fSAlexey Budankov static int record__aio_pushfn(void *to, struct aiocb *cblock, void *bf, size_t size, off_t off) 216*d3d1af6fSAlexey Budankov { 217*d3d1af6fSAlexey Budankov struct record *rec = to; 218*d3d1af6fSAlexey Budankov int ret, trace_fd = rec->session->data->file.fd; 219*d3d1af6fSAlexey Budankov 220*d3d1af6fSAlexey Budankov rec->samples++; 221*d3d1af6fSAlexey Budankov 222*d3d1af6fSAlexey Budankov ret = record__aio_write(cblock, trace_fd, bf, size, off); 223*d3d1af6fSAlexey Budankov if (!ret) { 224*d3d1af6fSAlexey Budankov rec->bytes_written += size; 225*d3d1af6fSAlexey Budankov if (switch_output_size(rec)) 226*d3d1af6fSAlexey Budankov trigger_hit(&switch_output_trigger); 227*d3d1af6fSAlexey Budankov } 228*d3d1af6fSAlexey Budankov 229*d3d1af6fSAlexey Budankov return ret; 230*d3d1af6fSAlexey Budankov } 231*d3d1af6fSAlexey Budankov 232*d3d1af6fSAlexey Budankov static off_t record__aio_get_pos(int trace_fd) 233*d3d1af6fSAlexey Budankov { 234*d3d1af6fSAlexey Budankov return lseek(trace_fd, 0, SEEK_CUR); 235*d3d1af6fSAlexey Budankov } 236*d3d1af6fSAlexey Budankov 237*d3d1af6fSAlexey Budankov static void record__aio_set_pos(int trace_fd, off_t pos) 238*d3d1af6fSAlexey Budankov { 239*d3d1af6fSAlexey Budankov lseek(trace_fd, pos, SEEK_SET); 240*d3d1af6fSAlexey Budankov } 241*d3d1af6fSAlexey Budankov 242*d3d1af6fSAlexey Budankov static void record__aio_mmap_read_sync(struct record *rec) 243*d3d1af6fSAlexey Budankov { 244*d3d1af6fSAlexey Budankov int i; 245*d3d1af6fSAlexey Budankov struct perf_evlist *evlist = rec->evlist; 246*d3d1af6fSAlexey Budankov struct perf_mmap *maps = evlist->mmap; 247*d3d1af6fSAlexey Budankov 248*d3d1af6fSAlexey Budankov if (!rec->opts.nr_cblocks) 249*d3d1af6fSAlexey Budankov return; 250*d3d1af6fSAlexey Budankov 251*d3d1af6fSAlexey Budankov for (i = 0; i < evlist->nr_mmaps; i++) { 252*d3d1af6fSAlexey Budankov struct perf_mmap *map = &maps[i]; 253*d3d1af6fSAlexey Budankov 254*d3d1af6fSAlexey Budankov if (map->base) 255*d3d1af6fSAlexey Budankov record__aio_sync(map); 256*d3d1af6fSAlexey Budankov } 257*d3d1af6fSAlexey Budankov } 258*d3d1af6fSAlexey Budankov 259*d3d1af6fSAlexey Budankov static int nr_cblocks_default = 1; 260*d3d1af6fSAlexey Budankov 261*d3d1af6fSAlexey Budankov static int record__aio_parse(const struct option *opt, 262*d3d1af6fSAlexey Budankov const char *str __maybe_unused, 263*d3d1af6fSAlexey Budankov int unset) 264*d3d1af6fSAlexey Budankov { 265*d3d1af6fSAlexey Budankov struct record_opts *opts = (struct record_opts *)opt->value; 266*d3d1af6fSAlexey Budankov 267*d3d1af6fSAlexey Budankov if (unset) 268*d3d1af6fSAlexey Budankov opts->nr_cblocks = 0; 269*d3d1af6fSAlexey Budankov else 270*d3d1af6fSAlexey Budankov opts->nr_cblocks = nr_cblocks_default; 271*d3d1af6fSAlexey Budankov 272*d3d1af6fSAlexey Budankov return 0; 273*d3d1af6fSAlexey Budankov } 274*d3d1af6fSAlexey Budankov #else /* HAVE_AIO_SUPPORT */ 275*d3d1af6fSAlexey Budankov static void record__aio_sync(struct perf_mmap *md __maybe_unused) 276*d3d1af6fSAlexey Budankov { 277*d3d1af6fSAlexey Budankov } 278*d3d1af6fSAlexey Budankov 279*d3d1af6fSAlexey Budankov static int record__aio_pushfn(void *to __maybe_unused, struct aiocb *cblock __maybe_unused, 280*d3d1af6fSAlexey Budankov void *bf __maybe_unused, size_t size __maybe_unused, off_t off __maybe_unused) 281*d3d1af6fSAlexey Budankov { 282*d3d1af6fSAlexey Budankov return -1; 283*d3d1af6fSAlexey Budankov } 284*d3d1af6fSAlexey Budankov 285*d3d1af6fSAlexey Budankov static off_t record__aio_get_pos(int trace_fd __maybe_unused) 286*d3d1af6fSAlexey Budankov { 287*d3d1af6fSAlexey Budankov return -1; 288*d3d1af6fSAlexey Budankov } 289*d3d1af6fSAlexey Budankov 290*d3d1af6fSAlexey Budankov static void record__aio_set_pos(int trace_fd __maybe_unused, off_t pos __maybe_unused) 291*d3d1af6fSAlexey Budankov { 292*d3d1af6fSAlexey Budankov } 293*d3d1af6fSAlexey Budankov 294*d3d1af6fSAlexey Budankov static void record__aio_mmap_read_sync(struct record *rec __maybe_unused) 295*d3d1af6fSAlexey Budankov { 296*d3d1af6fSAlexey Budankov } 297*d3d1af6fSAlexey Budankov #endif 298*d3d1af6fSAlexey Budankov 299*d3d1af6fSAlexey Budankov static int record__aio_enabled(struct record *rec) 300*d3d1af6fSAlexey Budankov { 301*d3d1af6fSAlexey Budankov return rec->opts.nr_cblocks > 0; 302*d3d1af6fSAlexey Budankov } 303*d3d1af6fSAlexey Budankov 30445694aa7SArnaldo Carvalho de Melo static int process_synthesized_event(struct perf_tool *tool, 305d20deb64SArnaldo Carvalho de Melo union perf_event *event, 3061d037ca1SIrina Tirdea struct perf_sample *sample __maybe_unused, 3071d037ca1SIrina Tirdea struct machine *machine __maybe_unused) 308234fbbf5SArnaldo Carvalho de Melo { 3098c6f45a7SArnaldo Carvalho de Melo struct record *rec = container_of(tool, struct record, tool); 310ded2b8feSJiri Olsa return record__write(rec, NULL, event, event->header.size); 311234fbbf5SArnaldo Carvalho de Melo } 312234fbbf5SArnaldo Carvalho de Melo 313ded2b8feSJiri Olsa static int record__pushfn(struct perf_mmap *map, void *to, void *bf, size_t size) 314d37f1586SArnaldo Carvalho de Melo { 315d37f1586SArnaldo Carvalho de Melo struct record *rec = to; 316d37f1586SArnaldo Carvalho de Melo 317d37f1586SArnaldo Carvalho de Melo rec->samples++; 318ded2b8feSJiri Olsa return record__write(rec, map, bf, size); 319d37f1586SArnaldo Carvalho de Melo } 320d37f1586SArnaldo Carvalho de Melo 3212dd6d8a1SAdrian Hunter static volatile int done; 3222dd6d8a1SAdrian Hunter static volatile int signr = -1; 3232dd6d8a1SAdrian Hunter static volatile int child_finished; 324c0bdc1c4SWang Nan 3252dd6d8a1SAdrian Hunter static void sig_handler(int sig) 3262dd6d8a1SAdrian Hunter { 3272dd6d8a1SAdrian Hunter if (sig == SIGCHLD) 3282dd6d8a1SAdrian Hunter child_finished = 1; 3292dd6d8a1SAdrian Hunter else 3302dd6d8a1SAdrian Hunter signr = sig; 3312dd6d8a1SAdrian Hunter 3322dd6d8a1SAdrian Hunter done = 1; 3332dd6d8a1SAdrian Hunter } 3342dd6d8a1SAdrian Hunter 335a074865eSWang Nan static void sigsegv_handler(int sig) 336a074865eSWang Nan { 337a074865eSWang Nan perf_hooks__recover(); 338a074865eSWang Nan sighandler_dump_stack(sig); 339a074865eSWang Nan } 340a074865eSWang Nan 3412dd6d8a1SAdrian Hunter static void record__sig_exit(void) 3422dd6d8a1SAdrian Hunter { 3432dd6d8a1SAdrian Hunter if (signr == -1) 3442dd6d8a1SAdrian Hunter return; 3452dd6d8a1SAdrian Hunter 3462dd6d8a1SAdrian Hunter signal(signr, SIG_DFL); 3472dd6d8a1SAdrian Hunter raise(signr); 3482dd6d8a1SAdrian Hunter } 3492dd6d8a1SAdrian Hunter 350e31f0d01SAdrian Hunter #ifdef HAVE_AUXTRACE_SUPPORT 351e31f0d01SAdrian Hunter 352ef149c25SAdrian Hunter static int record__process_auxtrace(struct perf_tool *tool, 353ded2b8feSJiri Olsa struct perf_mmap *map, 354ef149c25SAdrian Hunter union perf_event *event, void *data1, 355ef149c25SAdrian Hunter size_t len1, void *data2, size_t len2) 356ef149c25SAdrian Hunter { 357ef149c25SAdrian Hunter struct record *rec = container_of(tool, struct record, tool); 3588ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 359ef149c25SAdrian Hunter size_t padding; 360ef149c25SAdrian Hunter u8 pad[8] = {0}; 361ef149c25SAdrian Hunter 3628ceb41d7SJiri Olsa if (!perf_data__is_pipe(data)) { 36399fa2984SAdrian Hunter off_t file_offset; 3648ceb41d7SJiri Olsa int fd = perf_data__fd(data); 36599fa2984SAdrian Hunter int err; 36699fa2984SAdrian Hunter 36799fa2984SAdrian Hunter file_offset = lseek(fd, 0, SEEK_CUR); 36899fa2984SAdrian Hunter if (file_offset == -1) 36999fa2984SAdrian Hunter return -1; 37099fa2984SAdrian Hunter err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index, 37199fa2984SAdrian Hunter event, file_offset); 37299fa2984SAdrian Hunter if (err) 37399fa2984SAdrian Hunter return err; 37499fa2984SAdrian Hunter } 37599fa2984SAdrian Hunter 376ef149c25SAdrian Hunter /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */ 377ef149c25SAdrian Hunter padding = (len1 + len2) & 7; 378ef149c25SAdrian Hunter if (padding) 379ef149c25SAdrian Hunter padding = 8 - padding; 380ef149c25SAdrian Hunter 381ded2b8feSJiri Olsa record__write(rec, map, event, event->header.size); 382ded2b8feSJiri Olsa record__write(rec, map, data1, len1); 383ef149c25SAdrian Hunter if (len2) 384ded2b8feSJiri Olsa record__write(rec, map, data2, len2); 385ded2b8feSJiri Olsa record__write(rec, map, &pad, padding); 386ef149c25SAdrian Hunter 387ef149c25SAdrian Hunter return 0; 388ef149c25SAdrian Hunter } 389ef149c25SAdrian Hunter 390ef149c25SAdrian Hunter static int record__auxtrace_mmap_read(struct record *rec, 391e035f4caSJiri Olsa struct perf_mmap *map) 392ef149c25SAdrian Hunter { 393ef149c25SAdrian Hunter int ret; 394ef149c25SAdrian Hunter 395e035f4caSJiri Olsa ret = auxtrace_mmap__read(map, rec->itr, &rec->tool, 396ef149c25SAdrian Hunter record__process_auxtrace); 397ef149c25SAdrian Hunter if (ret < 0) 398ef149c25SAdrian Hunter return ret; 399ef149c25SAdrian Hunter 400ef149c25SAdrian Hunter if (ret) 401ef149c25SAdrian Hunter rec->samples++; 402ef149c25SAdrian Hunter 403ef149c25SAdrian Hunter return 0; 404ef149c25SAdrian Hunter } 405ef149c25SAdrian Hunter 4062dd6d8a1SAdrian Hunter static int record__auxtrace_mmap_read_snapshot(struct record *rec, 407e035f4caSJiri Olsa struct perf_mmap *map) 4082dd6d8a1SAdrian Hunter { 4092dd6d8a1SAdrian Hunter int ret; 4102dd6d8a1SAdrian Hunter 411e035f4caSJiri Olsa ret = auxtrace_mmap__read_snapshot(map, rec->itr, &rec->tool, 4122dd6d8a1SAdrian Hunter record__process_auxtrace, 4132dd6d8a1SAdrian Hunter rec->opts.auxtrace_snapshot_size); 4142dd6d8a1SAdrian Hunter if (ret < 0) 4152dd6d8a1SAdrian Hunter return ret; 4162dd6d8a1SAdrian Hunter 4172dd6d8a1SAdrian Hunter if (ret) 4182dd6d8a1SAdrian Hunter rec->samples++; 4192dd6d8a1SAdrian Hunter 4202dd6d8a1SAdrian Hunter return 0; 4212dd6d8a1SAdrian Hunter } 4222dd6d8a1SAdrian Hunter 4232dd6d8a1SAdrian Hunter static int record__auxtrace_read_snapshot_all(struct record *rec) 4242dd6d8a1SAdrian Hunter { 4252dd6d8a1SAdrian Hunter int i; 4262dd6d8a1SAdrian Hunter int rc = 0; 4272dd6d8a1SAdrian Hunter 4282dd6d8a1SAdrian Hunter for (i = 0; i < rec->evlist->nr_mmaps; i++) { 429e035f4caSJiri Olsa struct perf_mmap *map = &rec->evlist->mmap[i]; 4302dd6d8a1SAdrian Hunter 431e035f4caSJiri Olsa if (!map->auxtrace_mmap.base) 4322dd6d8a1SAdrian Hunter continue; 4332dd6d8a1SAdrian Hunter 434e035f4caSJiri Olsa if (record__auxtrace_mmap_read_snapshot(rec, map) != 0) { 4352dd6d8a1SAdrian Hunter rc = -1; 4362dd6d8a1SAdrian Hunter goto out; 4372dd6d8a1SAdrian Hunter } 4382dd6d8a1SAdrian Hunter } 4392dd6d8a1SAdrian Hunter out: 4402dd6d8a1SAdrian Hunter return rc; 4412dd6d8a1SAdrian Hunter } 4422dd6d8a1SAdrian Hunter 4432dd6d8a1SAdrian Hunter static void record__read_auxtrace_snapshot(struct record *rec) 4442dd6d8a1SAdrian Hunter { 4452dd6d8a1SAdrian Hunter pr_debug("Recording AUX area tracing snapshot\n"); 4462dd6d8a1SAdrian Hunter if (record__auxtrace_read_snapshot_all(rec) < 0) { 4475f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 4482dd6d8a1SAdrian Hunter } else { 4495f9cf599SWang Nan if (auxtrace_record__snapshot_finish(rec->itr)) 4505f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 4515f9cf599SWang Nan else 4525f9cf599SWang Nan trigger_ready(&auxtrace_snapshot_trigger); 4532dd6d8a1SAdrian Hunter } 4542dd6d8a1SAdrian Hunter } 4552dd6d8a1SAdrian Hunter 4564b5ea3bdSAdrian Hunter static int record__auxtrace_init(struct record *rec) 4574b5ea3bdSAdrian Hunter { 4584b5ea3bdSAdrian Hunter int err; 4594b5ea3bdSAdrian Hunter 4604b5ea3bdSAdrian Hunter if (!rec->itr) { 4614b5ea3bdSAdrian Hunter rec->itr = auxtrace_record__init(rec->evlist, &err); 4624b5ea3bdSAdrian Hunter if (err) 4634b5ea3bdSAdrian Hunter return err; 4644b5ea3bdSAdrian Hunter } 4654b5ea3bdSAdrian Hunter 4664b5ea3bdSAdrian Hunter err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts, 4674b5ea3bdSAdrian Hunter rec->opts.auxtrace_snapshot_opts); 4684b5ea3bdSAdrian Hunter if (err) 4694b5ea3bdSAdrian Hunter return err; 4704b5ea3bdSAdrian Hunter 4714b5ea3bdSAdrian Hunter return auxtrace_parse_filters(rec->evlist); 4724b5ea3bdSAdrian Hunter } 4734b5ea3bdSAdrian Hunter 474e31f0d01SAdrian Hunter #else 475e31f0d01SAdrian Hunter 476e31f0d01SAdrian Hunter static inline 477e31f0d01SAdrian Hunter int record__auxtrace_mmap_read(struct record *rec __maybe_unused, 478e035f4caSJiri Olsa struct perf_mmap *map __maybe_unused) 479e31f0d01SAdrian Hunter { 480e31f0d01SAdrian Hunter return 0; 481e31f0d01SAdrian Hunter } 482e31f0d01SAdrian Hunter 4832dd6d8a1SAdrian Hunter static inline 4842dd6d8a1SAdrian Hunter void record__read_auxtrace_snapshot(struct record *rec __maybe_unused) 4852dd6d8a1SAdrian Hunter { 4862dd6d8a1SAdrian Hunter } 4872dd6d8a1SAdrian Hunter 4882dd6d8a1SAdrian Hunter static inline 4892dd6d8a1SAdrian Hunter int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused) 4902dd6d8a1SAdrian Hunter { 4912dd6d8a1SAdrian Hunter return 0; 4922dd6d8a1SAdrian Hunter } 4932dd6d8a1SAdrian Hunter 4944b5ea3bdSAdrian Hunter static int record__auxtrace_init(struct record *rec __maybe_unused) 4954b5ea3bdSAdrian Hunter { 4964b5ea3bdSAdrian Hunter return 0; 4974b5ea3bdSAdrian Hunter } 4984b5ea3bdSAdrian Hunter 499e31f0d01SAdrian Hunter #endif 500e31f0d01SAdrian Hunter 501cda57a8cSWang Nan static int record__mmap_evlist(struct record *rec, 502cda57a8cSWang Nan struct perf_evlist *evlist) 503cda57a8cSWang Nan { 504cda57a8cSWang Nan struct record_opts *opts = &rec->opts; 505cda57a8cSWang Nan char msg[512]; 506cda57a8cSWang Nan 5077a276ff6SWang Nan if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, 508cda57a8cSWang Nan opts->auxtrace_mmap_pages, 509*d3d1af6fSAlexey Budankov opts->auxtrace_snapshot_mode, opts->nr_cblocks) < 0) { 510cda57a8cSWang Nan if (errno == EPERM) { 511cda57a8cSWang Nan pr_err("Permission error mapping pages.\n" 512cda57a8cSWang Nan "Consider increasing " 513cda57a8cSWang Nan "/proc/sys/kernel/perf_event_mlock_kb,\n" 514cda57a8cSWang Nan "or try again with a smaller value of -m/--mmap_pages.\n" 515cda57a8cSWang Nan "(current value: %u,%u)\n", 516cda57a8cSWang Nan opts->mmap_pages, opts->auxtrace_mmap_pages); 517cda57a8cSWang Nan return -errno; 518cda57a8cSWang Nan } else { 519cda57a8cSWang Nan pr_err("failed to mmap with %d (%s)\n", errno, 520c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, msg, sizeof(msg))); 521cda57a8cSWang Nan if (errno) 522cda57a8cSWang Nan return -errno; 523cda57a8cSWang Nan else 524cda57a8cSWang Nan return -EINVAL; 525cda57a8cSWang Nan } 526cda57a8cSWang Nan } 527cda57a8cSWang Nan return 0; 528cda57a8cSWang Nan } 529cda57a8cSWang Nan 530cda57a8cSWang Nan static int record__mmap(struct record *rec) 531cda57a8cSWang Nan { 532cda57a8cSWang Nan return record__mmap_evlist(rec, rec->evlist); 533cda57a8cSWang Nan } 534cda57a8cSWang Nan 5358c6f45a7SArnaldo Carvalho de Melo static int record__open(struct record *rec) 536dd7927f4SArnaldo Carvalho de Melo { 537d6195a6aSArnaldo Carvalho de Melo char msg[BUFSIZ]; 5386a4bb04cSJiri Olsa struct perf_evsel *pos; 539d20deb64SArnaldo Carvalho de Melo struct perf_evlist *evlist = rec->evlist; 540d20deb64SArnaldo Carvalho de Melo struct perf_session *session = rec->session; 541b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &rec->opts; 5425d8bb1ecSMathieu Poirier struct perf_evsel_config_term *err_term; 5438d3eca20SDavid Ahern int rc = 0; 544dd7927f4SArnaldo Carvalho de Melo 545d3dbf43cSArnaldo Carvalho de Melo /* 546d3dbf43cSArnaldo Carvalho de Melo * For initial_delay we need to add a dummy event so that we can track 547d3dbf43cSArnaldo Carvalho de Melo * PERF_RECORD_MMAP while we wait for the initial delay to enable the 548d3dbf43cSArnaldo Carvalho de Melo * real events, the ones asked by the user. 549d3dbf43cSArnaldo Carvalho de Melo */ 550d3dbf43cSArnaldo Carvalho de Melo if (opts->initial_delay) { 551d3dbf43cSArnaldo Carvalho de Melo if (perf_evlist__add_dummy(evlist)) 552d3dbf43cSArnaldo Carvalho de Melo return -ENOMEM; 553d3dbf43cSArnaldo Carvalho de Melo 554d3dbf43cSArnaldo Carvalho de Melo pos = perf_evlist__first(evlist); 555d3dbf43cSArnaldo Carvalho de Melo pos->tracking = 0; 556d3dbf43cSArnaldo Carvalho de Melo pos = perf_evlist__last(evlist); 557d3dbf43cSArnaldo Carvalho de Melo pos->tracking = 1; 558d3dbf43cSArnaldo Carvalho de Melo pos->attr.enable_on_exec = 1; 559d3dbf43cSArnaldo Carvalho de Melo } 560d3dbf43cSArnaldo Carvalho de Melo 561e68ae9cfSArnaldo Carvalho de Melo perf_evlist__config(evlist, opts, &callchain_param); 562cac21425SJiri Olsa 563e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 5643da297a6SIngo Molnar try_again: 565d988d5eeSKan Liang if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { 56656e52e85SArnaldo Carvalho de Melo if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { 567bb963e16SNamhyung Kim if (verbose > 0) 568c0a54341SArnaldo Carvalho de Melo ui__warning("%s\n", msg); 5693da297a6SIngo Molnar goto try_again; 5703da297a6SIngo Molnar } 571cf99ad14SAndi Kleen if ((errno == EINVAL || errno == EBADF) && 572cf99ad14SAndi Kleen pos->leader != pos && 573cf99ad14SAndi Kleen pos->weak_group) { 574cf99ad14SAndi Kleen pos = perf_evlist__reset_weak_group(evlist, pos); 575cf99ad14SAndi Kleen goto try_again; 576cf99ad14SAndi Kleen } 57756e52e85SArnaldo Carvalho de Melo rc = -errno; 57856e52e85SArnaldo Carvalho de Melo perf_evsel__open_strerror(pos, &opts->target, 57956e52e85SArnaldo Carvalho de Melo errno, msg, sizeof(msg)); 58056e52e85SArnaldo Carvalho de Melo ui__error("%s\n", msg); 5818d3eca20SDavid Ahern goto out; 5827c6a1c65SPeter Zijlstra } 583bfd8f72cSAndi Kleen 584bfd8f72cSAndi Kleen pos->supported = true; 5857c6a1c65SPeter Zijlstra } 5867c6a1c65SPeter Zijlstra 58723d4aad4SArnaldo Carvalho de Melo if (perf_evlist__apply_filters(evlist, &pos)) { 58862d94b00SArnaldo Carvalho de Melo pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n", 58923d4aad4SArnaldo Carvalho de Melo pos->filter, perf_evsel__name(pos), errno, 590c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, msg, sizeof(msg))); 5918d3eca20SDavid Ahern rc = -1; 5928d3eca20SDavid Ahern goto out; 5930a102479SFrederic Weisbecker } 5940a102479SFrederic Weisbecker 5955d8bb1ecSMathieu Poirier if (perf_evlist__apply_drv_configs(evlist, &pos, &err_term)) { 59662d94b00SArnaldo Carvalho de Melo pr_err("failed to set config \"%s\" on event %s with %d (%s)\n", 5975d8bb1ecSMathieu Poirier err_term->val.drv_cfg, perf_evsel__name(pos), errno, 5985d8bb1ecSMathieu Poirier str_error_r(errno, msg, sizeof(msg))); 5995d8bb1ecSMathieu Poirier rc = -1; 6005d8bb1ecSMathieu Poirier goto out; 6015d8bb1ecSMathieu Poirier } 6025d8bb1ecSMathieu Poirier 603cda57a8cSWang Nan rc = record__mmap(rec); 604cda57a8cSWang Nan if (rc) 6058d3eca20SDavid Ahern goto out; 6060a27d7f9SArnaldo Carvalho de Melo 607a91e5431SArnaldo Carvalho de Melo session->evlist = evlist; 6087b56cce2SArnaldo Carvalho de Melo perf_session__set_id_hdr_size(session); 6098d3eca20SDavid Ahern out: 6108d3eca20SDavid Ahern return rc; 611a91e5431SArnaldo Carvalho de Melo } 612a91e5431SArnaldo Carvalho de Melo 613e3d59112SNamhyung Kim static int process_sample_event(struct perf_tool *tool, 614e3d59112SNamhyung Kim union perf_event *event, 615e3d59112SNamhyung Kim struct perf_sample *sample, 616e3d59112SNamhyung Kim struct perf_evsel *evsel, 617e3d59112SNamhyung Kim struct machine *machine) 618e3d59112SNamhyung Kim { 619e3d59112SNamhyung Kim struct record *rec = container_of(tool, struct record, tool); 620e3d59112SNamhyung Kim 62168588bafSJin Yao if (rec->evlist->first_sample_time == 0) 62268588bafSJin Yao rec->evlist->first_sample_time = sample->time; 623e3d59112SNamhyung Kim 62468588bafSJin Yao rec->evlist->last_sample_time = sample->time; 62568588bafSJin Yao 62668588bafSJin Yao if (rec->buildid_all) 62768588bafSJin Yao return 0; 62868588bafSJin Yao 62968588bafSJin Yao rec->samples++; 630e3d59112SNamhyung Kim return build_id__mark_dso_hit(tool, event, sample, evsel, machine); 631e3d59112SNamhyung Kim } 632e3d59112SNamhyung Kim 6338c6f45a7SArnaldo Carvalho de Melo static int process_buildids(struct record *rec) 6346122e4e4SArnaldo Carvalho de Melo { 6358ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 636f5fc1412SJiri Olsa struct perf_session *session = rec->session; 6376122e4e4SArnaldo Carvalho de Melo 6388ceb41d7SJiri Olsa if (data->size == 0) 6399f591fd7SArnaldo Carvalho de Melo return 0; 6409f591fd7SArnaldo Carvalho de Melo 64100dc8657SNamhyung Kim /* 64200dc8657SNamhyung Kim * During this process, it'll load kernel map and replace the 64300dc8657SNamhyung Kim * dso->long_name to a real pathname it found. In this case 64400dc8657SNamhyung Kim * we prefer the vmlinux path like 64500dc8657SNamhyung Kim * /lib/modules/3.16.4/build/vmlinux 64600dc8657SNamhyung Kim * 64700dc8657SNamhyung Kim * rather than build-id path (in debug directory). 64800dc8657SNamhyung Kim * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551 64900dc8657SNamhyung Kim */ 65000dc8657SNamhyung Kim symbol_conf.ignore_vmlinux_buildid = true; 65100dc8657SNamhyung Kim 6526156681bSNamhyung Kim /* 6536156681bSNamhyung Kim * If --buildid-all is given, it marks all DSO regardless of hits, 65468588bafSJin Yao * so no need to process samples. But if timestamp_boundary is enabled, 65568588bafSJin Yao * it still needs to walk on all samples to get the timestamps of 65668588bafSJin Yao * first/last samples. 6576156681bSNamhyung Kim */ 65868588bafSJin Yao if (rec->buildid_all && !rec->timestamp_boundary) 6596156681bSNamhyung Kim rec->tool.sample = NULL; 6606156681bSNamhyung Kim 661b7b61cbeSArnaldo Carvalho de Melo return perf_session__process_events(session); 6626122e4e4SArnaldo Carvalho de Melo } 6636122e4e4SArnaldo Carvalho de Melo 6648115d60cSArnaldo Carvalho de Melo static void perf_event__synthesize_guest_os(struct machine *machine, void *data) 665a1645ce1SZhang, Yanmin { 666a1645ce1SZhang, Yanmin int err; 66745694aa7SArnaldo Carvalho de Melo struct perf_tool *tool = data; 668a1645ce1SZhang, Yanmin /* 669a1645ce1SZhang, Yanmin *As for guest kernel when processing subcommand record&report, 670a1645ce1SZhang, Yanmin *we arrange module mmap prior to guest kernel mmap and trigger 671a1645ce1SZhang, Yanmin *a preload dso because default guest module symbols are loaded 672a1645ce1SZhang, Yanmin *from guest kallsyms instead of /lib/modules/XXX/XXX. This 673a1645ce1SZhang, Yanmin *method is used to avoid symbol missing when the first addr is 674a1645ce1SZhang, Yanmin *in module instead of in guest kernel. 675a1645ce1SZhang, Yanmin */ 67645694aa7SArnaldo Carvalho de Melo err = perf_event__synthesize_modules(tool, process_synthesized_event, 677743eb868SArnaldo Carvalho de Melo machine); 678a1645ce1SZhang, Yanmin if (err < 0) 679a1645ce1SZhang, Yanmin pr_err("Couldn't record guest kernel [%d]'s reference" 68023346f21SArnaldo Carvalho de Melo " relocation symbol.\n", machine->pid); 681a1645ce1SZhang, Yanmin 682a1645ce1SZhang, Yanmin /* 683a1645ce1SZhang, Yanmin * We use _stext for guest kernel because guest kernel's /proc/kallsyms 684a1645ce1SZhang, Yanmin * have no _text sometimes. 685a1645ce1SZhang, Yanmin */ 68645694aa7SArnaldo Carvalho de Melo err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, 6870ae617beSAdrian Hunter machine); 688a1645ce1SZhang, Yanmin if (err < 0) 689a1645ce1SZhang, Yanmin pr_err("Couldn't record guest kernel [%d]'s reference" 69023346f21SArnaldo Carvalho de Melo " relocation symbol.\n", machine->pid); 691a1645ce1SZhang, Yanmin } 692a1645ce1SZhang, Yanmin 69398402807SFrederic Weisbecker static struct perf_event_header finished_round_event = { 69498402807SFrederic Weisbecker .size = sizeof(struct perf_event_header), 69598402807SFrederic Weisbecker .type = PERF_RECORD_FINISHED_ROUND, 69698402807SFrederic Weisbecker }; 69798402807SFrederic Weisbecker 698a4ea0ec4SWang Nan static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist, 6990b72d69aSWang Nan bool overwrite) 70098402807SFrederic Weisbecker { 701dcabb507SJiri Olsa u64 bytes_written = rec->bytes_written; 7020e2e63ddSPeter Zijlstra int i; 7038d3eca20SDavid Ahern int rc = 0; 704a4ea0ec4SWang Nan struct perf_mmap *maps; 705*d3d1af6fSAlexey Budankov int trace_fd = rec->data.file.fd; 706*d3d1af6fSAlexey Budankov off_t off; 70798402807SFrederic Weisbecker 708cb21686bSWang Nan if (!evlist) 709cb21686bSWang Nan return 0; 710ef149c25SAdrian Hunter 7110b72d69aSWang Nan maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; 712a4ea0ec4SWang Nan if (!maps) 713a4ea0ec4SWang Nan return 0; 714cb21686bSWang Nan 7150b72d69aSWang Nan if (overwrite && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING) 71654cc54deSWang Nan return 0; 71754cc54deSWang Nan 718*d3d1af6fSAlexey Budankov if (record__aio_enabled(rec)) 719*d3d1af6fSAlexey Budankov off = record__aio_get_pos(trace_fd); 720*d3d1af6fSAlexey Budankov 721a4ea0ec4SWang Nan for (i = 0; i < evlist->nr_mmaps; i++) { 722e035f4caSJiri Olsa struct perf_mmap *map = &maps[i]; 723a4ea0ec4SWang Nan 724e035f4caSJiri Olsa if (map->base) { 725*d3d1af6fSAlexey Budankov if (!record__aio_enabled(rec)) { 726e035f4caSJiri Olsa if (perf_mmap__push(map, rec, record__pushfn) != 0) { 7278d3eca20SDavid Ahern rc = -1; 7288d3eca20SDavid Ahern goto out; 7298d3eca20SDavid Ahern } 730*d3d1af6fSAlexey Budankov } else { 731*d3d1af6fSAlexey Budankov /* 732*d3d1af6fSAlexey Budankov * Call record__aio_sync() to wait till map->data buffer 733*d3d1af6fSAlexey Budankov * becomes available after previous aio write request. 734*d3d1af6fSAlexey Budankov */ 735*d3d1af6fSAlexey Budankov record__aio_sync(map); 736*d3d1af6fSAlexey Budankov if (perf_mmap__aio_push(map, rec, record__aio_pushfn, &off) != 0) { 737*d3d1af6fSAlexey Budankov record__aio_set_pos(trace_fd, off); 738*d3d1af6fSAlexey Budankov rc = -1; 739*d3d1af6fSAlexey Budankov goto out; 740*d3d1af6fSAlexey Budankov } 741*d3d1af6fSAlexey Budankov } 7428d3eca20SDavid Ahern } 743ef149c25SAdrian Hunter 744e035f4caSJiri Olsa if (map->auxtrace_mmap.base && !rec->opts.auxtrace_snapshot_mode && 745e035f4caSJiri Olsa record__auxtrace_mmap_read(rec, map) != 0) { 746ef149c25SAdrian Hunter rc = -1; 747ef149c25SAdrian Hunter goto out; 748ef149c25SAdrian Hunter } 74998402807SFrederic Weisbecker } 75098402807SFrederic Weisbecker 751*d3d1af6fSAlexey Budankov if (record__aio_enabled(rec)) 752*d3d1af6fSAlexey Budankov record__aio_set_pos(trace_fd, off); 753*d3d1af6fSAlexey Budankov 754dcabb507SJiri Olsa /* 755dcabb507SJiri Olsa * Mark the round finished in case we wrote 756dcabb507SJiri Olsa * at least one event. 757dcabb507SJiri Olsa */ 758dcabb507SJiri Olsa if (bytes_written != rec->bytes_written) 759ded2b8feSJiri Olsa rc = record__write(rec, NULL, &finished_round_event, sizeof(finished_round_event)); 7608d3eca20SDavid Ahern 7610b72d69aSWang Nan if (overwrite) 76254cc54deSWang Nan perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY); 7638d3eca20SDavid Ahern out: 7648d3eca20SDavid Ahern return rc; 76598402807SFrederic Weisbecker } 76698402807SFrederic Weisbecker 767cb21686bSWang Nan static int record__mmap_read_all(struct record *rec) 768cb21686bSWang Nan { 769cb21686bSWang Nan int err; 770cb21686bSWang Nan 771a4ea0ec4SWang Nan err = record__mmap_read_evlist(rec, rec->evlist, false); 772cb21686bSWang Nan if (err) 773cb21686bSWang Nan return err; 774cb21686bSWang Nan 77505737464SWang Nan return record__mmap_read_evlist(rec, rec->evlist, true); 776cb21686bSWang Nan } 777cb21686bSWang Nan 7788c6f45a7SArnaldo Carvalho de Melo static void record__init_features(struct record *rec) 77957706abcSDavid Ahern { 78057706abcSDavid Ahern struct perf_session *session = rec->session; 78157706abcSDavid Ahern int feat; 78257706abcSDavid Ahern 78357706abcSDavid Ahern for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++) 78457706abcSDavid Ahern perf_header__set_feat(&session->header, feat); 78557706abcSDavid Ahern 78657706abcSDavid Ahern if (rec->no_buildid) 78757706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_BUILD_ID); 78857706abcSDavid Ahern 7893e2be2daSArnaldo Carvalho de Melo if (!have_tracepoints(&rec->evlist->entries)) 79057706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); 79157706abcSDavid Ahern 79257706abcSDavid Ahern if (!rec->opts.branch_stack) 79357706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 794ef149c25SAdrian Hunter 795ef149c25SAdrian Hunter if (!rec->opts.full_auxtrace) 796ef149c25SAdrian Hunter perf_header__clear_feat(&session->header, HEADER_AUXTRACE); 797ffa517adSJiri Olsa 798cf790516SAlexey Budankov if (!(rec->opts.use_clockid && rec->opts.clockid_res_ns)) 799cf790516SAlexey Budankov perf_header__clear_feat(&session->header, HEADER_CLOCKID); 800cf790516SAlexey Budankov 801ffa517adSJiri Olsa perf_header__clear_feat(&session->header, HEADER_STAT); 80257706abcSDavid Ahern } 80357706abcSDavid Ahern 804e1ab48baSWang Nan static void 805e1ab48baSWang Nan record__finish_output(struct record *rec) 806e1ab48baSWang Nan { 8078ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 8088ceb41d7SJiri Olsa int fd = perf_data__fd(data); 809e1ab48baSWang Nan 8108ceb41d7SJiri Olsa if (data->is_pipe) 811e1ab48baSWang Nan return; 812e1ab48baSWang Nan 813e1ab48baSWang Nan rec->session->header.data_size += rec->bytes_written; 8148ceb41d7SJiri Olsa data->size = lseek(perf_data__fd(data), 0, SEEK_CUR); 815e1ab48baSWang Nan 816e1ab48baSWang Nan if (!rec->no_buildid) { 817e1ab48baSWang Nan process_buildids(rec); 818e1ab48baSWang Nan 819e1ab48baSWang Nan if (rec->buildid_all) 820e1ab48baSWang Nan dsos__hit_all(rec->session); 821e1ab48baSWang Nan } 822e1ab48baSWang Nan perf_session__write_header(rec->session, rec->evlist, fd, true); 823e1ab48baSWang Nan 824e1ab48baSWang Nan return; 825e1ab48baSWang Nan } 826e1ab48baSWang Nan 8274ea648aeSWang Nan static int record__synthesize_workload(struct record *rec, bool tail) 828be7b0c9eSWang Nan { 8299d6aae72SArnaldo Carvalho de Melo int err; 8309d6aae72SArnaldo Carvalho de Melo struct thread_map *thread_map; 831be7b0c9eSWang Nan 8324ea648aeSWang Nan if (rec->opts.tail_synthesize != tail) 8334ea648aeSWang Nan return 0; 8344ea648aeSWang Nan 8359d6aae72SArnaldo Carvalho de Melo thread_map = thread_map__new_by_tid(rec->evlist->workload.pid); 8369d6aae72SArnaldo Carvalho de Melo if (thread_map == NULL) 8379d6aae72SArnaldo Carvalho de Melo return -1; 8389d6aae72SArnaldo Carvalho de Melo 8399d6aae72SArnaldo Carvalho de Melo err = perf_event__synthesize_thread_map(&rec->tool, thread_map, 840be7b0c9eSWang Nan process_synthesized_event, 841be7b0c9eSWang Nan &rec->session->machines.host, 842be7b0c9eSWang Nan rec->opts.sample_address, 843be7b0c9eSWang Nan rec->opts.proc_map_timeout); 8449d6aae72SArnaldo Carvalho de Melo thread_map__put(thread_map); 8459d6aae72SArnaldo Carvalho de Melo return err; 846be7b0c9eSWang Nan } 847be7b0c9eSWang Nan 8484ea648aeSWang Nan static int record__synthesize(struct record *rec, bool tail); 8493c1cb7e3SWang Nan 850ecfd7a9cSWang Nan static int 851ecfd7a9cSWang Nan record__switch_output(struct record *rec, bool at_exit) 852ecfd7a9cSWang Nan { 8538ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 854ecfd7a9cSWang Nan int fd, err; 855ecfd7a9cSWang Nan 856ecfd7a9cSWang Nan /* Same Size: "2015122520103046"*/ 857ecfd7a9cSWang Nan char timestamp[] = "InvalidTimestamp"; 858ecfd7a9cSWang Nan 859*d3d1af6fSAlexey Budankov record__aio_mmap_read_sync(rec); 860*d3d1af6fSAlexey Budankov 8614ea648aeSWang Nan record__synthesize(rec, true); 8624ea648aeSWang Nan if (target__none(&rec->opts.target)) 8634ea648aeSWang Nan record__synthesize_workload(rec, true); 8644ea648aeSWang Nan 865ecfd7a9cSWang Nan rec->samples = 0; 866ecfd7a9cSWang Nan record__finish_output(rec); 867ecfd7a9cSWang Nan err = fetch_current_timestamp(timestamp, sizeof(timestamp)); 868ecfd7a9cSWang Nan if (err) { 869ecfd7a9cSWang Nan pr_err("Failed to get current timestamp\n"); 870ecfd7a9cSWang Nan return -EINVAL; 871ecfd7a9cSWang Nan } 872ecfd7a9cSWang Nan 8738ceb41d7SJiri Olsa fd = perf_data__switch(data, timestamp, 874ecfd7a9cSWang Nan rec->session->header.data_offset, 875ecfd7a9cSWang Nan at_exit); 876ecfd7a9cSWang Nan if (fd >= 0 && !at_exit) { 877ecfd7a9cSWang Nan rec->bytes_written = 0; 878ecfd7a9cSWang Nan rec->session->header.data_size = 0; 879ecfd7a9cSWang Nan } 880ecfd7a9cSWang Nan 881ecfd7a9cSWang Nan if (!quiet) 882ecfd7a9cSWang Nan fprintf(stderr, "[ perf record: Dump %s.%s ]\n", 883eae8ad80SJiri Olsa data->file.path, timestamp); 8843c1cb7e3SWang Nan 8853c1cb7e3SWang Nan /* Output tracking events */ 886be7b0c9eSWang Nan if (!at_exit) { 8874ea648aeSWang Nan record__synthesize(rec, false); 8883c1cb7e3SWang Nan 889be7b0c9eSWang Nan /* 890be7b0c9eSWang Nan * In 'perf record --switch-output' without -a, 891be7b0c9eSWang Nan * record__synthesize() in record__switch_output() won't 892be7b0c9eSWang Nan * generate tracking events because there's no thread_map 893be7b0c9eSWang Nan * in evlist. Which causes newly created perf.data doesn't 894be7b0c9eSWang Nan * contain map and comm information. 895be7b0c9eSWang Nan * Create a fake thread_map and directly call 896be7b0c9eSWang Nan * perf_event__synthesize_thread_map() for those events. 897be7b0c9eSWang Nan */ 898be7b0c9eSWang Nan if (target__none(&rec->opts.target)) 8994ea648aeSWang Nan record__synthesize_workload(rec, false); 900be7b0c9eSWang Nan } 901ecfd7a9cSWang Nan return fd; 902ecfd7a9cSWang Nan } 903ecfd7a9cSWang Nan 904f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno; 905f33cbe72SArnaldo Carvalho de Melo 906f33cbe72SArnaldo Carvalho de Melo /* 907f33cbe72SArnaldo Carvalho de Melo * perf_evlist__prepare_workload will send a SIGUSR1 908f33cbe72SArnaldo Carvalho de Melo * if the fork fails, since we asked by setting its 909f33cbe72SArnaldo Carvalho de Melo * want_signal to true. 910f33cbe72SArnaldo Carvalho de Melo */ 91145604710SNamhyung Kim static void workload_exec_failed_signal(int signo __maybe_unused, 91245604710SNamhyung Kim siginfo_t *info, 913f33cbe72SArnaldo Carvalho de Melo void *ucontext __maybe_unused) 914f33cbe72SArnaldo Carvalho de Melo { 915f33cbe72SArnaldo Carvalho de Melo workload_exec_errno = info->si_value.sival_int; 916f33cbe72SArnaldo Carvalho de Melo done = 1; 917f33cbe72SArnaldo Carvalho de Melo child_finished = 1; 918f33cbe72SArnaldo Carvalho de Melo } 919f33cbe72SArnaldo Carvalho de Melo 9202dd6d8a1SAdrian Hunter static void snapshot_sig_handler(int sig); 921bfacbe3bSJiri Olsa static void alarm_sig_handler(int sig); 9222dd6d8a1SAdrian Hunter 92346bc29b9SAdrian Hunter int __weak 92446bc29b9SAdrian Hunter perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused, 92546bc29b9SAdrian Hunter struct perf_tool *tool __maybe_unused, 92646bc29b9SAdrian Hunter perf_event__handler_t process __maybe_unused, 92746bc29b9SAdrian Hunter struct machine *machine __maybe_unused) 92846bc29b9SAdrian Hunter { 92946bc29b9SAdrian Hunter return 0; 93046bc29b9SAdrian Hunter } 93146bc29b9SAdrian Hunter 932ee667f94SWang Nan static const struct perf_event_mmap_page * 933ee667f94SWang Nan perf_evlist__pick_pc(struct perf_evlist *evlist) 934ee667f94SWang Nan { 935b2cb615dSWang Nan if (evlist) { 936b2cb615dSWang Nan if (evlist->mmap && evlist->mmap[0].base) 937ee667f94SWang Nan return evlist->mmap[0].base; 9380b72d69aSWang Nan if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base) 9390b72d69aSWang Nan return evlist->overwrite_mmap[0].base; 940b2cb615dSWang Nan } 941ee667f94SWang Nan return NULL; 942ee667f94SWang Nan } 943ee667f94SWang Nan 944c45628b0SWang Nan static const struct perf_event_mmap_page *record__pick_pc(struct record *rec) 945c45628b0SWang Nan { 946ee667f94SWang Nan const struct perf_event_mmap_page *pc; 947ee667f94SWang Nan 948ee667f94SWang Nan pc = perf_evlist__pick_pc(rec->evlist); 949ee667f94SWang Nan if (pc) 950ee667f94SWang Nan return pc; 951c45628b0SWang Nan return NULL; 952c45628b0SWang Nan } 953c45628b0SWang Nan 9544ea648aeSWang Nan static int record__synthesize(struct record *rec, bool tail) 955c45c86ebSWang Nan { 956c45c86ebSWang Nan struct perf_session *session = rec->session; 957c45c86ebSWang Nan struct machine *machine = &session->machines.host; 9588ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 959c45c86ebSWang Nan struct record_opts *opts = &rec->opts; 960c45c86ebSWang Nan struct perf_tool *tool = &rec->tool; 9618ceb41d7SJiri Olsa int fd = perf_data__fd(data); 962c45c86ebSWang Nan int err = 0; 963c45c86ebSWang Nan 9644ea648aeSWang Nan if (rec->opts.tail_synthesize != tail) 9654ea648aeSWang Nan return 0; 9664ea648aeSWang Nan 9678ceb41d7SJiri Olsa if (data->is_pipe) { 968a2015516SJiri Olsa /* 969a2015516SJiri Olsa * We need to synthesize events first, because some 970a2015516SJiri Olsa * features works on top of them (on report side). 971a2015516SJiri Olsa */ 972318ec184SJiri Olsa err = perf_event__synthesize_attrs(tool, rec->evlist, 973c45c86ebSWang Nan process_synthesized_event); 974c45c86ebSWang Nan if (err < 0) { 975c45c86ebSWang Nan pr_err("Couldn't synthesize attrs.\n"); 976c45c86ebSWang Nan goto out; 977c45c86ebSWang Nan } 978c45c86ebSWang Nan 979a2015516SJiri Olsa err = perf_event__synthesize_features(tool, session, rec->evlist, 980a2015516SJiri Olsa process_synthesized_event); 981a2015516SJiri Olsa if (err < 0) { 982a2015516SJiri Olsa pr_err("Couldn't synthesize features.\n"); 983a2015516SJiri Olsa return err; 984a2015516SJiri Olsa } 985a2015516SJiri Olsa 986c45c86ebSWang Nan if (have_tracepoints(&rec->evlist->entries)) { 987c45c86ebSWang Nan /* 988c45c86ebSWang Nan * FIXME err <= 0 here actually means that 989c45c86ebSWang Nan * there were no tracepoints so its not really 990c45c86ebSWang Nan * an error, just that we don't need to 991c45c86ebSWang Nan * synthesize anything. We really have to 992c45c86ebSWang Nan * return this more properly and also 993c45c86ebSWang Nan * propagate errors that now are calling die() 994c45c86ebSWang Nan */ 995c45c86ebSWang Nan err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist, 996c45c86ebSWang Nan process_synthesized_event); 997c45c86ebSWang Nan if (err <= 0) { 998c45c86ebSWang Nan pr_err("Couldn't record tracing data.\n"); 999c45c86ebSWang Nan goto out; 1000c45c86ebSWang Nan } 1001c45c86ebSWang Nan rec->bytes_written += err; 1002c45c86ebSWang Nan } 1003c45c86ebSWang Nan } 1004c45c86ebSWang Nan 1005c45628b0SWang Nan err = perf_event__synth_time_conv(record__pick_pc(rec), tool, 100646bc29b9SAdrian Hunter process_synthesized_event, machine); 100746bc29b9SAdrian Hunter if (err) 100846bc29b9SAdrian Hunter goto out; 100946bc29b9SAdrian Hunter 1010c45c86ebSWang Nan if (rec->opts.full_auxtrace) { 1011c45c86ebSWang Nan err = perf_event__synthesize_auxtrace_info(rec->itr, tool, 1012c45c86ebSWang Nan session, process_synthesized_event); 1013c45c86ebSWang Nan if (err) 1014c45c86ebSWang Nan goto out; 1015c45c86ebSWang Nan } 1016c45c86ebSWang Nan 10176c443954SArnaldo Carvalho de Melo if (!perf_evlist__exclude_kernel(rec->evlist)) { 1018c45c86ebSWang Nan err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, 1019c45c86ebSWang Nan machine); 1020c45c86ebSWang Nan WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n" 1021c45c86ebSWang Nan "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 1022c45c86ebSWang Nan "Check /proc/kallsyms permission or run as root.\n"); 1023c45c86ebSWang Nan 1024c45c86ebSWang Nan err = perf_event__synthesize_modules(tool, process_synthesized_event, 1025c45c86ebSWang Nan machine); 1026c45c86ebSWang Nan WARN_ONCE(err < 0, "Couldn't record kernel module information.\n" 1027c45c86ebSWang Nan "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 1028c45c86ebSWang Nan "Check /proc/modules permission or run as root.\n"); 10296c443954SArnaldo Carvalho de Melo } 1030c45c86ebSWang Nan 1031c45c86ebSWang Nan if (perf_guest) { 1032c45c86ebSWang Nan machines__process_guests(&session->machines, 1033c45c86ebSWang Nan perf_event__synthesize_guest_os, tool); 1034c45c86ebSWang Nan } 1035c45c86ebSWang Nan 1036bfd8f72cSAndi Kleen err = perf_event__synthesize_extra_attr(&rec->tool, 1037bfd8f72cSAndi Kleen rec->evlist, 1038bfd8f72cSAndi Kleen process_synthesized_event, 1039bfd8f72cSAndi Kleen data->is_pipe); 1040bfd8f72cSAndi Kleen if (err) 1041bfd8f72cSAndi Kleen goto out; 1042bfd8f72cSAndi Kleen 1043373565d2SAndi Kleen err = perf_event__synthesize_thread_map2(&rec->tool, rec->evlist->threads, 1044373565d2SAndi Kleen process_synthesized_event, 1045373565d2SAndi Kleen NULL); 1046373565d2SAndi Kleen if (err < 0) { 1047373565d2SAndi Kleen pr_err("Couldn't synthesize thread map.\n"); 1048373565d2SAndi Kleen return err; 1049373565d2SAndi Kleen } 1050373565d2SAndi Kleen 1051373565d2SAndi Kleen err = perf_event__synthesize_cpu_map(&rec->tool, rec->evlist->cpus, 1052373565d2SAndi Kleen process_synthesized_event, NULL); 1053373565d2SAndi Kleen if (err < 0) { 1054373565d2SAndi Kleen pr_err("Couldn't synthesize cpu map.\n"); 1055373565d2SAndi Kleen return err; 1056373565d2SAndi Kleen } 1057373565d2SAndi Kleen 1058c45c86ebSWang Nan err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads, 1059c45c86ebSWang Nan process_synthesized_event, opts->sample_address, 1060340b47f5SKan Liang opts->proc_map_timeout, 1); 1061c45c86ebSWang Nan out: 1062c45c86ebSWang Nan return err; 1063c45c86ebSWang Nan } 1064c45c86ebSWang Nan 10658c6f45a7SArnaldo Carvalho de Melo static int __cmd_record(struct record *rec, int argc, const char **argv) 106686470930SIngo Molnar { 106757706abcSDavid Ahern int err; 106845604710SNamhyung Kim int status = 0; 10698b412664SPeter Zijlstra unsigned long waking = 0; 107046be604bSZhang, Yanmin const bool forks = argc > 0; 107145694aa7SArnaldo Carvalho de Melo struct perf_tool *tool = &rec->tool; 1072b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &rec->opts; 10738ceb41d7SJiri Olsa struct perf_data *data = &rec->data; 1074d20deb64SArnaldo Carvalho de Melo struct perf_session *session; 10756dcf45efSArnaldo Carvalho de Melo bool disabled = false, draining = false; 107642aa276fSNamhyung Kim int fd; 107786470930SIngo Molnar 107845604710SNamhyung Kim atexit(record__sig_exit); 1079f5970550SPeter Zijlstra signal(SIGCHLD, sig_handler); 1080f5970550SPeter Zijlstra signal(SIGINT, sig_handler); 1081804f7ac7SDavid Ahern signal(SIGTERM, sig_handler); 1082a074865eSWang Nan signal(SIGSEGV, sigsegv_handler); 1083c0bdc1c4SWang Nan 1084f3b3614aSHari Bathini if (rec->opts.record_namespaces) 1085f3b3614aSHari Bathini tool->namespace_events = true; 1086f3b3614aSHari Bathini 1087dc0c6127SJiri Olsa if (rec->opts.auxtrace_snapshot_mode || rec->switch_output.enabled) { 10882dd6d8a1SAdrian Hunter signal(SIGUSR2, snapshot_sig_handler); 10893c1cb7e3SWang Nan if (rec->opts.auxtrace_snapshot_mode) 10905f9cf599SWang Nan trigger_on(&auxtrace_snapshot_trigger); 1091dc0c6127SJiri Olsa if (rec->switch_output.enabled) 10923c1cb7e3SWang Nan trigger_on(&switch_output_trigger); 1093c0bdc1c4SWang Nan } else { 10942dd6d8a1SAdrian Hunter signal(SIGUSR2, SIG_IGN); 1095c0bdc1c4SWang Nan } 1096f5970550SPeter Zijlstra 10978ceb41d7SJiri Olsa session = perf_session__new(data, false, tool); 109894c744b6SArnaldo Carvalho de Melo if (session == NULL) { 1099ffa91880SAdrien BAK pr_err("Perf session creation failed.\n"); 1100a9a70bbcSArnaldo Carvalho de Melo return -1; 1101a9a70bbcSArnaldo Carvalho de Melo } 1102a9a70bbcSArnaldo Carvalho de Melo 11038ceb41d7SJiri Olsa fd = perf_data__fd(data); 1104d20deb64SArnaldo Carvalho de Melo rec->session = session; 1105d20deb64SArnaldo Carvalho de Melo 11068c6f45a7SArnaldo Carvalho de Melo record__init_features(rec); 1107330aa675SStephane Eranian 1108cf790516SAlexey Budankov if (rec->opts.use_clockid && rec->opts.clockid_res_ns) 1109cf790516SAlexey Budankov session->header.env.clockid_res_ns = rec->opts.clockid_res_ns; 1110cf790516SAlexey Budankov 1111d4db3f16SArnaldo Carvalho de Melo if (forks) { 11123e2be2daSArnaldo Carvalho de Melo err = perf_evlist__prepare_workload(rec->evlist, &opts->target, 11138ceb41d7SJiri Olsa argv, data->is_pipe, 1114735f7e0bSArnaldo Carvalho de Melo workload_exec_failed_signal); 111535b9d88eSArnaldo Carvalho de Melo if (err < 0) { 111635b9d88eSArnaldo Carvalho de Melo pr_err("Couldn't run the workload!\n"); 111745604710SNamhyung Kim status = err; 111835b9d88eSArnaldo Carvalho de Melo goto out_delete_session; 1119856e9660SPeter Zijlstra } 1120856e9660SPeter Zijlstra } 1121856e9660SPeter Zijlstra 1122ad46e48cSJiri Olsa /* 1123ad46e48cSJiri Olsa * If we have just single event and are sending data 1124ad46e48cSJiri Olsa * through pipe, we need to force the ids allocation, 1125ad46e48cSJiri Olsa * because we synthesize event name through the pipe 1126ad46e48cSJiri Olsa * and need the id for that. 1127ad46e48cSJiri Olsa */ 1128ad46e48cSJiri Olsa if (data->is_pipe && rec->evlist->nr_entries == 1) 1129ad46e48cSJiri Olsa rec->opts.sample_id = true; 1130ad46e48cSJiri Olsa 11318c6f45a7SArnaldo Carvalho de Melo if (record__open(rec) != 0) { 11328d3eca20SDavid Ahern err = -1; 113345604710SNamhyung Kim goto out_child; 11348d3eca20SDavid Ahern } 113586470930SIngo Molnar 11368690a2a7SWang Nan err = bpf__apply_obj_config(); 11378690a2a7SWang Nan if (err) { 11388690a2a7SWang Nan char errbuf[BUFSIZ]; 11398690a2a7SWang Nan 11408690a2a7SWang Nan bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf)); 11418690a2a7SWang Nan pr_err("ERROR: Apply config to BPF failed: %s\n", 11428690a2a7SWang Nan errbuf); 11438690a2a7SWang Nan goto out_child; 11448690a2a7SWang Nan } 11458690a2a7SWang Nan 1146cca8482cSAdrian Hunter /* 1147cca8482cSAdrian Hunter * Normally perf_session__new would do this, but it doesn't have the 1148cca8482cSAdrian Hunter * evlist. 1149cca8482cSAdrian Hunter */ 1150cca8482cSAdrian Hunter if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) { 1151cca8482cSAdrian Hunter pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n"); 1152cca8482cSAdrian Hunter rec->tool.ordered_events = false; 1153cca8482cSAdrian Hunter } 1154cca8482cSAdrian Hunter 11553e2be2daSArnaldo Carvalho de Melo if (!rec->evlist->nr_groups) 1156a8bb559bSNamhyung Kim perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); 1157a8bb559bSNamhyung Kim 11588ceb41d7SJiri Olsa if (data->is_pipe) { 115942aa276fSNamhyung Kim err = perf_header__write_pipe(fd); 1160529870e3STom Zanussi if (err < 0) 116145604710SNamhyung Kim goto out_child; 1162563aecb2SJiri Olsa } else { 116342aa276fSNamhyung Kim err = perf_session__write_header(session, rec->evlist, fd, false); 1164d5eed904SArnaldo Carvalho de Melo if (err < 0) 116545604710SNamhyung Kim goto out_child; 1166d5eed904SArnaldo Carvalho de Melo } 11677c6a1c65SPeter Zijlstra 1168d3665498SDavid Ahern if (!rec->no_buildid 1169e20960c0SRobert Richter && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) { 1170d3665498SDavid Ahern pr_err("Couldn't generate buildids. " 1171e20960c0SRobert Richter "Use --no-buildid to profile anyway.\n"); 11728d3eca20SDavid Ahern err = -1; 117345604710SNamhyung Kim goto out_child; 1174e20960c0SRobert Richter } 1175e20960c0SRobert Richter 11764ea648aeSWang Nan err = record__synthesize(rec, false); 1177c45c86ebSWang Nan if (err < 0) 117845604710SNamhyung Kim goto out_child; 11798d3eca20SDavid Ahern 1180d20deb64SArnaldo Carvalho de Melo if (rec->realtime_prio) { 118186470930SIngo Molnar struct sched_param param; 118286470930SIngo Molnar 1183d20deb64SArnaldo Carvalho de Melo param.sched_priority = rec->realtime_prio; 118486470930SIngo Molnar if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { 11856beba7adSArnaldo Carvalho de Melo pr_err("Could not set realtime priority.\n"); 11868d3eca20SDavid Ahern err = -1; 118745604710SNamhyung Kim goto out_child; 118886470930SIngo Molnar } 118986470930SIngo Molnar } 119086470930SIngo Molnar 1191774cb499SJiri Olsa /* 1192774cb499SJiri Olsa * When perf is starting the traced process, all the events 1193774cb499SJiri Olsa * (apart from group members) have enable_on_exec=1 set, 1194774cb499SJiri Olsa * so don't spoil it by prematurely enabling them. 1195774cb499SJiri Olsa */ 11966619a53eSAndi Kleen if (!target__none(&opts->target) && !opts->initial_delay) 11973e2be2daSArnaldo Carvalho de Melo perf_evlist__enable(rec->evlist); 1198764e16a3SDavid Ahern 1199856e9660SPeter Zijlstra /* 1200856e9660SPeter Zijlstra * Let the child rip 1201856e9660SPeter Zijlstra */ 1202e803cf97SNamhyung Kim if (forks) { 120320a8a3cfSJiri Olsa struct machine *machine = &session->machines.host; 1204e5bed564SNamhyung Kim union perf_event *event; 1205e907caf3SHari Bathini pid_t tgid; 1206e5bed564SNamhyung Kim 1207e5bed564SNamhyung Kim event = malloc(sizeof(event->comm) + machine->id_hdr_size); 1208e5bed564SNamhyung Kim if (event == NULL) { 1209e5bed564SNamhyung Kim err = -ENOMEM; 1210e5bed564SNamhyung Kim goto out_child; 1211e5bed564SNamhyung Kim } 1212e5bed564SNamhyung Kim 1213e803cf97SNamhyung Kim /* 1214e803cf97SNamhyung Kim * Some H/W events are generated before COMM event 1215e803cf97SNamhyung Kim * which is emitted during exec(), so perf script 1216e803cf97SNamhyung Kim * cannot see a correct process name for those events. 1217e803cf97SNamhyung Kim * Synthesize COMM event to prevent it. 1218e803cf97SNamhyung Kim */ 1219e907caf3SHari Bathini tgid = perf_event__synthesize_comm(tool, event, 1220e803cf97SNamhyung Kim rec->evlist->workload.pid, 1221e803cf97SNamhyung Kim process_synthesized_event, 1222e803cf97SNamhyung Kim machine); 1223e5bed564SNamhyung Kim free(event); 1224e803cf97SNamhyung Kim 1225e907caf3SHari Bathini if (tgid == -1) 1226e907caf3SHari Bathini goto out_child; 1227e907caf3SHari Bathini 1228e907caf3SHari Bathini event = malloc(sizeof(event->namespaces) + 1229e907caf3SHari Bathini (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + 1230e907caf3SHari Bathini machine->id_hdr_size); 1231e907caf3SHari Bathini if (event == NULL) { 1232e907caf3SHari Bathini err = -ENOMEM; 1233e907caf3SHari Bathini goto out_child; 1234e907caf3SHari Bathini } 1235e907caf3SHari Bathini 1236e907caf3SHari Bathini /* 1237e907caf3SHari Bathini * Synthesize NAMESPACES event for the command specified. 1238e907caf3SHari Bathini */ 1239e907caf3SHari Bathini perf_event__synthesize_namespaces(tool, event, 1240e907caf3SHari Bathini rec->evlist->workload.pid, 1241e907caf3SHari Bathini tgid, process_synthesized_event, 1242e907caf3SHari Bathini machine); 1243e907caf3SHari Bathini free(event); 1244e907caf3SHari Bathini 12453e2be2daSArnaldo Carvalho de Melo perf_evlist__start_workload(rec->evlist); 1246e803cf97SNamhyung Kim } 1247856e9660SPeter Zijlstra 12486619a53eSAndi Kleen if (opts->initial_delay) { 12490693e680SArnaldo Carvalho de Melo usleep(opts->initial_delay * USEC_PER_MSEC); 12506619a53eSAndi Kleen perf_evlist__enable(rec->evlist); 12516619a53eSAndi Kleen } 12526619a53eSAndi Kleen 12535f9cf599SWang Nan trigger_ready(&auxtrace_snapshot_trigger); 12543c1cb7e3SWang Nan trigger_ready(&switch_output_trigger); 1255a074865eSWang Nan perf_hooks__invoke_record_start(); 1256649c48a9SPeter Zijlstra for (;;) { 12579f065194SYang Shi unsigned long long hits = rec->samples; 125886470930SIngo Molnar 125905737464SWang Nan /* 126005737464SWang Nan * rec->evlist->bkw_mmap_state is possible to be 126105737464SWang Nan * BKW_MMAP_EMPTY here: when done == true and 126205737464SWang Nan * hits != rec->samples in previous round. 126305737464SWang Nan * 126405737464SWang Nan * perf_evlist__toggle_bkw_mmap ensure we never 126505737464SWang Nan * convert BKW_MMAP_EMPTY to BKW_MMAP_DATA_PENDING. 126605737464SWang Nan */ 126705737464SWang Nan if (trigger_is_hit(&switch_output_trigger) || done || draining) 126805737464SWang Nan perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_DATA_PENDING); 126905737464SWang Nan 12708c6f45a7SArnaldo Carvalho de Melo if (record__mmap_read_all(rec) < 0) { 12715f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 12723c1cb7e3SWang Nan trigger_error(&switch_output_trigger); 12738d3eca20SDavid Ahern err = -1; 127445604710SNamhyung Kim goto out_child; 12758d3eca20SDavid Ahern } 127686470930SIngo Molnar 12772dd6d8a1SAdrian Hunter if (auxtrace_record__snapshot_started) { 12782dd6d8a1SAdrian Hunter auxtrace_record__snapshot_started = 0; 12795f9cf599SWang Nan if (!trigger_is_error(&auxtrace_snapshot_trigger)) 12802dd6d8a1SAdrian Hunter record__read_auxtrace_snapshot(rec); 12815f9cf599SWang Nan if (trigger_is_error(&auxtrace_snapshot_trigger)) { 12822dd6d8a1SAdrian Hunter pr_err("AUX area tracing snapshot failed\n"); 12832dd6d8a1SAdrian Hunter err = -1; 12842dd6d8a1SAdrian Hunter goto out_child; 12852dd6d8a1SAdrian Hunter } 12862dd6d8a1SAdrian Hunter } 12872dd6d8a1SAdrian Hunter 12883c1cb7e3SWang Nan if (trigger_is_hit(&switch_output_trigger)) { 128905737464SWang Nan /* 129005737464SWang Nan * If switch_output_trigger is hit, the data in 129105737464SWang Nan * overwritable ring buffer should have been collected, 129205737464SWang Nan * so bkw_mmap_state should be set to BKW_MMAP_EMPTY. 129305737464SWang Nan * 129405737464SWang Nan * If SIGUSR2 raise after or during record__mmap_read_all(), 129505737464SWang Nan * record__mmap_read_all() didn't collect data from 129605737464SWang Nan * overwritable ring buffer. Read again. 129705737464SWang Nan */ 129805737464SWang Nan if (rec->evlist->bkw_mmap_state == BKW_MMAP_RUNNING) 129905737464SWang Nan continue; 13003c1cb7e3SWang Nan trigger_ready(&switch_output_trigger); 13013c1cb7e3SWang Nan 130205737464SWang Nan /* 130305737464SWang Nan * Reenable events in overwrite ring buffer after 130405737464SWang Nan * record__mmap_read_all(): we should have collected 130505737464SWang Nan * data from it. 130605737464SWang Nan */ 130705737464SWang Nan perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_RUNNING); 130805737464SWang Nan 13093c1cb7e3SWang Nan if (!quiet) 13103c1cb7e3SWang Nan fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n", 13113c1cb7e3SWang Nan waking); 13123c1cb7e3SWang Nan waking = 0; 13133c1cb7e3SWang Nan fd = record__switch_output(rec, false); 13143c1cb7e3SWang Nan if (fd < 0) { 13153c1cb7e3SWang Nan pr_err("Failed to switch to new file\n"); 13163c1cb7e3SWang Nan trigger_error(&switch_output_trigger); 13173c1cb7e3SWang Nan err = fd; 13183c1cb7e3SWang Nan goto out_child; 13193c1cb7e3SWang Nan } 1320bfacbe3bSJiri Olsa 1321bfacbe3bSJiri Olsa /* re-arm the alarm */ 1322bfacbe3bSJiri Olsa if (rec->switch_output.time) 1323bfacbe3bSJiri Olsa alarm(rec->switch_output.time); 13243c1cb7e3SWang Nan } 13253c1cb7e3SWang Nan 1326d20deb64SArnaldo Carvalho de Melo if (hits == rec->samples) { 13276dcf45efSArnaldo Carvalho de Melo if (done || draining) 1328649c48a9SPeter Zijlstra break; 1329f66a889dSArnaldo Carvalho de Melo err = perf_evlist__poll(rec->evlist, -1); 1330a515114fSJiri Olsa /* 1331a515114fSJiri Olsa * Propagate error, only if there's any. Ignore positive 1332a515114fSJiri Olsa * number of returned events and interrupt error. 1333a515114fSJiri Olsa */ 1334a515114fSJiri Olsa if (err > 0 || (err < 0 && errno == EINTR)) 133545604710SNamhyung Kim err = 0; 13368b412664SPeter Zijlstra waking++; 13376dcf45efSArnaldo Carvalho de Melo 13386dcf45efSArnaldo Carvalho de Melo if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0) 13396dcf45efSArnaldo Carvalho de Melo draining = true; 13408b412664SPeter Zijlstra } 13418b412664SPeter Zijlstra 1342774cb499SJiri Olsa /* 1343774cb499SJiri Olsa * When perf is starting the traced process, at the end events 1344774cb499SJiri Olsa * die with the process and we wait for that. Thus no need to 1345774cb499SJiri Olsa * disable events in this case. 1346774cb499SJiri Olsa */ 1347602ad878SArnaldo Carvalho de Melo if (done && !disabled && !target__none(&opts->target)) { 13485f9cf599SWang Nan trigger_off(&auxtrace_snapshot_trigger); 13493e2be2daSArnaldo Carvalho de Melo perf_evlist__disable(rec->evlist); 13502711926aSJiri Olsa disabled = true; 13512711926aSJiri Olsa } 13528b412664SPeter Zijlstra } 13535f9cf599SWang Nan trigger_off(&auxtrace_snapshot_trigger); 13543c1cb7e3SWang Nan trigger_off(&switch_output_trigger); 13558b412664SPeter Zijlstra 1356f33cbe72SArnaldo Carvalho de Melo if (forks && workload_exec_errno) { 135735550da3SMasami Hiramatsu char msg[STRERR_BUFSIZE]; 1358c8b5f2c9SArnaldo Carvalho de Melo const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); 1359f33cbe72SArnaldo Carvalho de Melo pr_err("Workload failed: %s\n", emsg); 1360f33cbe72SArnaldo Carvalho de Melo err = -1; 136145604710SNamhyung Kim goto out_child; 1362f33cbe72SArnaldo Carvalho de Melo } 1363f33cbe72SArnaldo Carvalho de Melo 1364e3d59112SNamhyung Kim if (!quiet) 13658b412664SPeter Zijlstra fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); 136686470930SIngo Molnar 13674ea648aeSWang Nan if (target__none(&rec->opts.target)) 13684ea648aeSWang Nan record__synthesize_workload(rec, true); 13694ea648aeSWang Nan 137045604710SNamhyung Kim out_child: 1371*d3d1af6fSAlexey Budankov record__aio_mmap_read_sync(rec); 1372*d3d1af6fSAlexey Budankov 137345604710SNamhyung Kim if (forks) { 137445604710SNamhyung Kim int exit_status; 137545604710SNamhyung Kim 137645604710SNamhyung Kim if (!child_finished) 137745604710SNamhyung Kim kill(rec->evlist->workload.pid, SIGTERM); 137845604710SNamhyung Kim 137945604710SNamhyung Kim wait(&exit_status); 138045604710SNamhyung Kim 138145604710SNamhyung Kim if (err < 0) 138245604710SNamhyung Kim status = err; 138345604710SNamhyung Kim else if (WIFEXITED(exit_status)) 138445604710SNamhyung Kim status = WEXITSTATUS(exit_status); 138545604710SNamhyung Kim else if (WIFSIGNALED(exit_status)) 138645604710SNamhyung Kim signr = WTERMSIG(exit_status); 138745604710SNamhyung Kim } else 138845604710SNamhyung Kim status = err; 138945604710SNamhyung Kim 13904ea648aeSWang Nan record__synthesize(rec, true); 1391e3d59112SNamhyung Kim /* this will be recalculated during process_buildids() */ 1392e3d59112SNamhyung Kim rec->samples = 0; 1393e3d59112SNamhyung Kim 1394ecfd7a9cSWang Nan if (!err) { 1395ecfd7a9cSWang Nan if (!rec->timestamp_filename) { 1396e1ab48baSWang Nan record__finish_output(rec); 1397ecfd7a9cSWang Nan } else { 1398ecfd7a9cSWang Nan fd = record__switch_output(rec, true); 1399ecfd7a9cSWang Nan if (fd < 0) { 1400ecfd7a9cSWang Nan status = fd; 1401ecfd7a9cSWang Nan goto out_delete_session; 1402ecfd7a9cSWang Nan } 1403ecfd7a9cSWang Nan } 1404ecfd7a9cSWang Nan } 140539d17dacSArnaldo Carvalho de Melo 1406a074865eSWang Nan perf_hooks__invoke_record_end(); 1407a074865eSWang Nan 1408e3d59112SNamhyung Kim if (!err && !quiet) { 1409e3d59112SNamhyung Kim char samples[128]; 1410ecfd7a9cSWang Nan const char *postfix = rec->timestamp_filename ? 1411ecfd7a9cSWang Nan ".<timestamp>" : ""; 1412e3d59112SNamhyung Kim 1413ef149c25SAdrian Hunter if (rec->samples && !rec->opts.full_auxtrace) 1414e3d59112SNamhyung Kim scnprintf(samples, sizeof(samples), 1415e3d59112SNamhyung Kim " (%" PRIu64 " samples)", rec->samples); 1416e3d59112SNamhyung Kim else 1417e3d59112SNamhyung Kim samples[0] = '\0'; 1418e3d59112SNamhyung Kim 1419ecfd7a9cSWang Nan fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n", 14208ceb41d7SJiri Olsa perf_data__size(data) / 1024.0 / 1024.0, 1421eae8ad80SJiri Olsa data->file.path, postfix, samples); 1422e3d59112SNamhyung Kim } 1423e3d59112SNamhyung Kim 142439d17dacSArnaldo Carvalho de Melo out_delete_session: 142539d17dacSArnaldo Carvalho de Melo perf_session__delete(session); 142645604710SNamhyung Kim return status; 142786470930SIngo Molnar } 142886470930SIngo Molnar 14290883e820SArnaldo Carvalho de Melo static void callchain_debug(struct callchain_param *callchain) 143009b0fd45SJiri Olsa { 1431aad2b21cSKan Liang static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" }; 1432a601fdffSJiri Olsa 14330883e820SArnaldo Carvalho de Melo pr_debug("callchain: type %s\n", str[callchain->record_mode]); 143426d33022SJiri Olsa 14350883e820SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_DWARF) 143609b0fd45SJiri Olsa pr_debug("callchain: stack dump size %d\n", 14370883e820SArnaldo Carvalho de Melo callchain->dump_size); 14380883e820SArnaldo Carvalho de Melo } 14390883e820SArnaldo Carvalho de Melo 14400883e820SArnaldo Carvalho de Melo int record_opts__parse_callchain(struct record_opts *record, 14410883e820SArnaldo Carvalho de Melo struct callchain_param *callchain, 14420883e820SArnaldo Carvalho de Melo const char *arg, bool unset) 14430883e820SArnaldo Carvalho de Melo { 14440883e820SArnaldo Carvalho de Melo int ret; 14450883e820SArnaldo Carvalho de Melo callchain->enabled = !unset; 14460883e820SArnaldo Carvalho de Melo 14470883e820SArnaldo Carvalho de Melo /* --no-call-graph */ 14480883e820SArnaldo Carvalho de Melo if (unset) { 14490883e820SArnaldo Carvalho de Melo callchain->record_mode = CALLCHAIN_NONE; 14500883e820SArnaldo Carvalho de Melo pr_debug("callchain: disabled\n"); 14510883e820SArnaldo Carvalho de Melo return 0; 14520883e820SArnaldo Carvalho de Melo } 14530883e820SArnaldo Carvalho de Melo 14540883e820SArnaldo Carvalho de Melo ret = parse_callchain_record_opt(arg, callchain); 14550883e820SArnaldo Carvalho de Melo if (!ret) { 14560883e820SArnaldo Carvalho de Melo /* Enable data address sampling for DWARF unwind. */ 14570883e820SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_DWARF) 14580883e820SArnaldo Carvalho de Melo record->sample_address = true; 14590883e820SArnaldo Carvalho de Melo callchain_debug(callchain); 14600883e820SArnaldo Carvalho de Melo } 14610883e820SArnaldo Carvalho de Melo 14620883e820SArnaldo Carvalho de Melo return ret; 146309b0fd45SJiri Olsa } 146409b0fd45SJiri Olsa 1465c421e80bSKan Liang int record_parse_callchain_opt(const struct option *opt, 146609b0fd45SJiri Olsa const char *arg, 146709b0fd45SJiri Olsa int unset) 146809b0fd45SJiri Olsa { 14690883e820SArnaldo Carvalho de Melo return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset); 147026d33022SJiri Olsa } 147126d33022SJiri Olsa 1472c421e80bSKan Liang int record_callchain_opt(const struct option *opt, 147309b0fd45SJiri Olsa const char *arg __maybe_unused, 147409b0fd45SJiri Olsa int unset __maybe_unused) 147509b0fd45SJiri Olsa { 14762ddd5c04SArnaldo Carvalho de Melo struct callchain_param *callchain = opt->value; 1477c421e80bSKan Liang 14782ddd5c04SArnaldo Carvalho de Melo callchain->enabled = true; 147909b0fd45SJiri Olsa 14802ddd5c04SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_NONE) 14812ddd5c04SArnaldo Carvalho de Melo callchain->record_mode = CALLCHAIN_FP; 1482eb853e80SJiri Olsa 14832ddd5c04SArnaldo Carvalho de Melo callchain_debug(callchain); 148409b0fd45SJiri Olsa return 0; 148509b0fd45SJiri Olsa } 148609b0fd45SJiri Olsa 1487eb853e80SJiri Olsa static int perf_record_config(const char *var, const char *value, void *cb) 1488eb853e80SJiri Olsa { 14897a29c087SNamhyung Kim struct record *rec = cb; 14907a29c087SNamhyung Kim 14917a29c087SNamhyung Kim if (!strcmp(var, "record.build-id")) { 14927a29c087SNamhyung Kim if (!strcmp(value, "cache")) 14937a29c087SNamhyung Kim rec->no_buildid_cache = false; 14947a29c087SNamhyung Kim else if (!strcmp(value, "no-cache")) 14957a29c087SNamhyung Kim rec->no_buildid_cache = true; 14967a29c087SNamhyung Kim else if (!strcmp(value, "skip")) 14977a29c087SNamhyung Kim rec->no_buildid = true; 14987a29c087SNamhyung Kim else 14997a29c087SNamhyung Kim return -1; 15007a29c087SNamhyung Kim return 0; 15017a29c087SNamhyung Kim } 1502cff17205SYisheng Xie if (!strcmp(var, "record.call-graph")) { 1503cff17205SYisheng Xie var = "call-graph.record-mode"; 1504eb853e80SJiri Olsa return perf_default_config(var, value, cb); 1505eb853e80SJiri Olsa } 1506eb853e80SJiri Olsa 1507cff17205SYisheng Xie return 0; 1508cff17205SYisheng Xie } 1509cff17205SYisheng Xie 1510814c8c38SPeter Zijlstra struct clockid_map { 1511814c8c38SPeter Zijlstra const char *name; 1512814c8c38SPeter Zijlstra int clockid; 1513814c8c38SPeter Zijlstra }; 1514814c8c38SPeter Zijlstra 1515814c8c38SPeter Zijlstra #define CLOCKID_MAP(n, c) \ 1516814c8c38SPeter Zijlstra { .name = n, .clockid = (c), } 1517814c8c38SPeter Zijlstra 1518814c8c38SPeter Zijlstra #define CLOCKID_END { .name = NULL, } 1519814c8c38SPeter Zijlstra 1520814c8c38SPeter Zijlstra 1521814c8c38SPeter Zijlstra /* 1522814c8c38SPeter Zijlstra * Add the missing ones, we need to build on many distros... 1523814c8c38SPeter Zijlstra */ 1524814c8c38SPeter Zijlstra #ifndef CLOCK_MONOTONIC_RAW 1525814c8c38SPeter Zijlstra #define CLOCK_MONOTONIC_RAW 4 1526814c8c38SPeter Zijlstra #endif 1527814c8c38SPeter Zijlstra #ifndef CLOCK_BOOTTIME 1528814c8c38SPeter Zijlstra #define CLOCK_BOOTTIME 7 1529814c8c38SPeter Zijlstra #endif 1530814c8c38SPeter Zijlstra #ifndef CLOCK_TAI 1531814c8c38SPeter Zijlstra #define CLOCK_TAI 11 1532814c8c38SPeter Zijlstra #endif 1533814c8c38SPeter Zijlstra 1534814c8c38SPeter Zijlstra static const struct clockid_map clockids[] = { 1535814c8c38SPeter Zijlstra /* available for all events, NMI safe */ 1536814c8c38SPeter Zijlstra CLOCKID_MAP("monotonic", CLOCK_MONOTONIC), 1537814c8c38SPeter Zijlstra CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW), 1538814c8c38SPeter Zijlstra 1539814c8c38SPeter Zijlstra /* available for some events */ 1540814c8c38SPeter Zijlstra CLOCKID_MAP("realtime", CLOCK_REALTIME), 1541814c8c38SPeter Zijlstra CLOCKID_MAP("boottime", CLOCK_BOOTTIME), 1542814c8c38SPeter Zijlstra CLOCKID_MAP("tai", CLOCK_TAI), 1543814c8c38SPeter Zijlstra 1544814c8c38SPeter Zijlstra /* available for the lazy */ 1545814c8c38SPeter Zijlstra CLOCKID_MAP("mono", CLOCK_MONOTONIC), 1546814c8c38SPeter Zijlstra CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW), 1547814c8c38SPeter Zijlstra CLOCKID_MAP("real", CLOCK_REALTIME), 1548814c8c38SPeter Zijlstra CLOCKID_MAP("boot", CLOCK_BOOTTIME), 1549814c8c38SPeter Zijlstra 1550814c8c38SPeter Zijlstra CLOCKID_END, 1551814c8c38SPeter Zijlstra }; 1552814c8c38SPeter Zijlstra 1553cf790516SAlexey Budankov static int get_clockid_res(clockid_t clk_id, u64 *res_ns) 1554cf790516SAlexey Budankov { 1555cf790516SAlexey Budankov struct timespec res; 1556cf790516SAlexey Budankov 1557cf790516SAlexey Budankov *res_ns = 0; 1558cf790516SAlexey Budankov if (!clock_getres(clk_id, &res)) 1559cf790516SAlexey Budankov *res_ns = res.tv_nsec + res.tv_sec * NSEC_PER_SEC; 1560cf790516SAlexey Budankov else 1561cf790516SAlexey Budankov pr_warning("WARNING: Failed to determine specified clock resolution.\n"); 1562cf790516SAlexey Budankov 1563cf790516SAlexey Budankov return 0; 1564cf790516SAlexey Budankov } 1565cf790516SAlexey Budankov 1566814c8c38SPeter Zijlstra static int parse_clockid(const struct option *opt, const char *str, int unset) 1567814c8c38SPeter Zijlstra { 1568814c8c38SPeter Zijlstra struct record_opts *opts = (struct record_opts *)opt->value; 1569814c8c38SPeter Zijlstra const struct clockid_map *cm; 1570814c8c38SPeter Zijlstra const char *ostr = str; 1571814c8c38SPeter Zijlstra 1572814c8c38SPeter Zijlstra if (unset) { 1573814c8c38SPeter Zijlstra opts->use_clockid = 0; 1574814c8c38SPeter Zijlstra return 0; 1575814c8c38SPeter Zijlstra } 1576814c8c38SPeter Zijlstra 1577814c8c38SPeter Zijlstra /* no arg passed */ 1578814c8c38SPeter Zijlstra if (!str) 1579814c8c38SPeter Zijlstra return 0; 1580814c8c38SPeter Zijlstra 1581814c8c38SPeter Zijlstra /* no setting it twice */ 1582814c8c38SPeter Zijlstra if (opts->use_clockid) 1583814c8c38SPeter Zijlstra return -1; 1584814c8c38SPeter Zijlstra 1585814c8c38SPeter Zijlstra opts->use_clockid = true; 1586814c8c38SPeter Zijlstra 1587814c8c38SPeter Zijlstra /* if its a number, we're done */ 1588814c8c38SPeter Zijlstra if (sscanf(str, "%d", &opts->clockid) == 1) 1589cf790516SAlexey Budankov return get_clockid_res(opts->clockid, &opts->clockid_res_ns); 1590814c8c38SPeter Zijlstra 1591814c8c38SPeter Zijlstra /* allow a "CLOCK_" prefix to the name */ 1592814c8c38SPeter Zijlstra if (!strncasecmp(str, "CLOCK_", 6)) 1593814c8c38SPeter Zijlstra str += 6; 1594814c8c38SPeter Zijlstra 1595814c8c38SPeter Zijlstra for (cm = clockids; cm->name; cm++) { 1596814c8c38SPeter Zijlstra if (!strcasecmp(str, cm->name)) { 1597814c8c38SPeter Zijlstra opts->clockid = cm->clockid; 1598cf790516SAlexey Budankov return get_clockid_res(opts->clockid, 1599cf790516SAlexey Budankov &opts->clockid_res_ns); 1600814c8c38SPeter Zijlstra } 1601814c8c38SPeter Zijlstra } 1602814c8c38SPeter Zijlstra 1603814c8c38SPeter Zijlstra opts->use_clockid = false; 1604814c8c38SPeter Zijlstra ui__warning("unknown clockid %s, check man page\n", ostr); 1605814c8c38SPeter Zijlstra return -1; 1606814c8c38SPeter Zijlstra } 1607814c8c38SPeter Zijlstra 1608e9db1310SAdrian Hunter static int record__parse_mmap_pages(const struct option *opt, 1609e9db1310SAdrian Hunter const char *str, 1610e9db1310SAdrian Hunter int unset __maybe_unused) 1611e9db1310SAdrian Hunter { 1612e9db1310SAdrian Hunter struct record_opts *opts = opt->value; 1613e9db1310SAdrian Hunter char *s, *p; 1614e9db1310SAdrian Hunter unsigned int mmap_pages; 1615e9db1310SAdrian Hunter int ret; 1616e9db1310SAdrian Hunter 1617e9db1310SAdrian Hunter if (!str) 1618e9db1310SAdrian Hunter return -EINVAL; 1619e9db1310SAdrian Hunter 1620e9db1310SAdrian Hunter s = strdup(str); 1621e9db1310SAdrian Hunter if (!s) 1622e9db1310SAdrian Hunter return -ENOMEM; 1623e9db1310SAdrian Hunter 1624e9db1310SAdrian Hunter p = strchr(s, ','); 1625e9db1310SAdrian Hunter if (p) 1626e9db1310SAdrian Hunter *p = '\0'; 1627e9db1310SAdrian Hunter 1628e9db1310SAdrian Hunter if (*s) { 1629e9db1310SAdrian Hunter ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s); 1630e9db1310SAdrian Hunter if (ret) 1631e9db1310SAdrian Hunter goto out_free; 1632e9db1310SAdrian Hunter opts->mmap_pages = mmap_pages; 1633e9db1310SAdrian Hunter } 1634e9db1310SAdrian Hunter 1635e9db1310SAdrian Hunter if (!p) { 1636e9db1310SAdrian Hunter ret = 0; 1637e9db1310SAdrian Hunter goto out_free; 1638e9db1310SAdrian Hunter } 1639e9db1310SAdrian Hunter 1640e9db1310SAdrian Hunter ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1); 1641e9db1310SAdrian Hunter if (ret) 1642e9db1310SAdrian Hunter goto out_free; 1643e9db1310SAdrian Hunter 1644e9db1310SAdrian Hunter opts->auxtrace_mmap_pages = mmap_pages; 1645e9db1310SAdrian Hunter 1646e9db1310SAdrian Hunter out_free: 1647e9db1310SAdrian Hunter free(s); 1648e9db1310SAdrian Hunter return ret; 1649e9db1310SAdrian Hunter } 1650e9db1310SAdrian Hunter 16510c582449SJiri Olsa static void switch_output_size_warn(struct record *rec) 16520c582449SJiri Olsa { 16530c582449SJiri Olsa u64 wakeup_size = perf_evlist__mmap_size(rec->opts.mmap_pages); 16540c582449SJiri Olsa struct switch_output *s = &rec->switch_output; 16550c582449SJiri Olsa 16560c582449SJiri Olsa wakeup_size /= 2; 16570c582449SJiri Olsa 16580c582449SJiri Olsa if (s->size < wakeup_size) { 16590c582449SJiri Olsa char buf[100]; 16600c582449SJiri Olsa 16610c582449SJiri Olsa unit_number__scnprintf(buf, sizeof(buf), wakeup_size); 16620c582449SJiri Olsa pr_warning("WARNING: switch-output data size lower than " 16630c582449SJiri Olsa "wakeup kernel buffer size (%s) " 16640c582449SJiri Olsa "expect bigger perf.data sizes\n", buf); 16650c582449SJiri Olsa } 16660c582449SJiri Olsa } 16670c582449SJiri Olsa 1668cb4e1ebbSJiri Olsa static int switch_output_setup(struct record *rec) 1669cb4e1ebbSJiri Olsa { 1670cb4e1ebbSJiri Olsa struct switch_output *s = &rec->switch_output; 1671dc0c6127SJiri Olsa static struct parse_tag tags_size[] = { 1672dc0c6127SJiri Olsa { .tag = 'B', .mult = 1 }, 1673dc0c6127SJiri Olsa { .tag = 'K', .mult = 1 << 10 }, 1674dc0c6127SJiri Olsa { .tag = 'M', .mult = 1 << 20 }, 1675dc0c6127SJiri Olsa { .tag = 'G', .mult = 1 << 30 }, 1676dc0c6127SJiri Olsa { .tag = 0 }, 1677dc0c6127SJiri Olsa }; 1678bfacbe3bSJiri Olsa static struct parse_tag tags_time[] = { 1679bfacbe3bSJiri Olsa { .tag = 's', .mult = 1 }, 1680bfacbe3bSJiri Olsa { .tag = 'm', .mult = 60 }, 1681bfacbe3bSJiri Olsa { .tag = 'h', .mult = 60*60 }, 1682bfacbe3bSJiri Olsa { .tag = 'd', .mult = 60*60*24 }, 1683bfacbe3bSJiri Olsa { .tag = 0 }, 1684bfacbe3bSJiri Olsa }; 1685dc0c6127SJiri Olsa unsigned long val; 1686cb4e1ebbSJiri Olsa 1687cb4e1ebbSJiri Olsa if (!s->set) 1688cb4e1ebbSJiri Olsa return 0; 1689cb4e1ebbSJiri Olsa 1690cb4e1ebbSJiri Olsa if (!strcmp(s->str, "signal")) { 1691cb4e1ebbSJiri Olsa s->signal = true; 1692cb4e1ebbSJiri Olsa pr_debug("switch-output with SIGUSR2 signal\n"); 1693dc0c6127SJiri Olsa goto enabled; 1694dc0c6127SJiri Olsa } 1695dc0c6127SJiri Olsa 1696dc0c6127SJiri Olsa val = parse_tag_value(s->str, tags_size); 1697dc0c6127SJiri Olsa if (val != (unsigned long) -1) { 1698dc0c6127SJiri Olsa s->size = val; 1699dc0c6127SJiri Olsa pr_debug("switch-output with %s size threshold\n", s->str); 1700dc0c6127SJiri Olsa goto enabled; 1701cb4e1ebbSJiri Olsa } 1702cb4e1ebbSJiri Olsa 1703bfacbe3bSJiri Olsa val = parse_tag_value(s->str, tags_time); 1704bfacbe3bSJiri Olsa if (val != (unsigned long) -1) { 1705bfacbe3bSJiri Olsa s->time = val; 1706bfacbe3bSJiri Olsa pr_debug("switch-output with %s time threshold (%lu seconds)\n", 1707bfacbe3bSJiri Olsa s->str, s->time); 1708bfacbe3bSJiri Olsa goto enabled; 1709bfacbe3bSJiri Olsa } 1710bfacbe3bSJiri Olsa 1711cb4e1ebbSJiri Olsa return -1; 1712dc0c6127SJiri Olsa 1713dc0c6127SJiri Olsa enabled: 1714dc0c6127SJiri Olsa rec->timestamp_filename = true; 1715dc0c6127SJiri Olsa s->enabled = true; 17160c582449SJiri Olsa 17170c582449SJiri Olsa if (s->size && !rec->opts.no_buffering) 17180c582449SJiri Olsa switch_output_size_warn(rec); 17190c582449SJiri Olsa 1720dc0c6127SJiri Olsa return 0; 1721cb4e1ebbSJiri Olsa } 1722cb4e1ebbSJiri Olsa 1723e5b2c207SNamhyung Kim static const char * const __record_usage[] = { 172486470930SIngo Molnar "perf record [<options>] [<command>]", 172586470930SIngo Molnar "perf record [<options>] -- <command> [<options>]", 172686470930SIngo Molnar NULL 172786470930SIngo Molnar }; 1728e5b2c207SNamhyung Kim const char * const *record_usage = __record_usage; 172986470930SIngo Molnar 1730d20deb64SArnaldo Carvalho de Melo /* 17318c6f45a7SArnaldo Carvalho de Melo * XXX Ideally would be local to cmd_record() and passed to a record__new 17328c6f45a7SArnaldo Carvalho de Melo * because we need to have access to it in record__exit, that is called 1733d20deb64SArnaldo Carvalho de Melo * after cmd_record() exits, but since record_options need to be accessible to 1734d20deb64SArnaldo Carvalho de Melo * builtin-script, leave it here. 1735d20deb64SArnaldo Carvalho de Melo * 1736d20deb64SArnaldo Carvalho de Melo * At least we don't ouch it in all the other functions here directly. 1737d20deb64SArnaldo Carvalho de Melo * 1738d20deb64SArnaldo Carvalho de Melo * Just say no to tons of global variables, sigh. 1739d20deb64SArnaldo Carvalho de Melo */ 17408c6f45a7SArnaldo Carvalho de Melo static struct record record = { 1741d20deb64SArnaldo Carvalho de Melo .opts = { 17428affc2b8SAndi Kleen .sample_time = true, 1743d20deb64SArnaldo Carvalho de Melo .mmap_pages = UINT_MAX, 1744d20deb64SArnaldo Carvalho de Melo .user_freq = UINT_MAX, 1745d20deb64SArnaldo Carvalho de Melo .user_interval = ULLONG_MAX, 1746447a6013SArnaldo Carvalho de Melo .freq = 4000, 1747d1cb9fceSNamhyung Kim .target = { 1748d1cb9fceSNamhyung Kim .uses_mmap = true, 17493aa5939dSAdrian Hunter .default_per_cpu = true, 1750d1cb9fceSNamhyung Kim }, 17519d9cad76SKan Liang .proc_map_timeout = 500, 1752d20deb64SArnaldo Carvalho de Melo }, 1753e3d59112SNamhyung Kim .tool = { 1754e3d59112SNamhyung Kim .sample = process_sample_event, 1755e3d59112SNamhyung Kim .fork = perf_event__process_fork, 1756cca8482cSAdrian Hunter .exit = perf_event__process_exit, 1757e3d59112SNamhyung Kim .comm = perf_event__process_comm, 1758f3b3614aSHari Bathini .namespaces = perf_event__process_namespaces, 1759e3d59112SNamhyung Kim .mmap = perf_event__process_mmap, 1760e3d59112SNamhyung Kim .mmap2 = perf_event__process_mmap2, 1761cca8482cSAdrian Hunter .ordered_events = true, 1762e3d59112SNamhyung Kim }, 1763d20deb64SArnaldo Carvalho de Melo }; 17647865e817SFrederic Weisbecker 176576a26549SNamhyung Kim const char record_callchain_help[] = CALLCHAIN_RECORD_HELP 176676a26549SNamhyung Kim "\n\t\t\t\tDefault: fp"; 176761eaa3beSArnaldo Carvalho de Melo 17680aab2136SWang Nan static bool dry_run; 17690aab2136SWang Nan 1770d20deb64SArnaldo Carvalho de Melo /* 1771d20deb64SArnaldo Carvalho de Melo * XXX Will stay a global variable till we fix builtin-script.c to stop messing 1772d20deb64SArnaldo Carvalho de Melo * with it and switch to use the library functions in perf_evlist that came 1773b4006796SArnaldo Carvalho de Melo * from builtin-record.c, i.e. use record_opts, 1774d20deb64SArnaldo Carvalho de Melo * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record', 1775d20deb64SArnaldo Carvalho de Melo * using pipes, etc. 1776d20deb64SArnaldo Carvalho de Melo */ 1777efd21307SJiri Olsa static struct option __record_options[] = { 1778d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &record.evlist, "event", 177986470930SIngo Molnar "event selector. use 'perf list' to list available events", 1780f120f9d5SJiri Olsa parse_events_option), 1781d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK(0, "filter", &record.evlist, "filter", 1782c171b552SLi Zefan "event filter", parse_filter), 17834ba1faa1SWang Nan OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist, 17844ba1faa1SWang Nan NULL, "don't record events from perf itself", 17854ba1faa1SWang Nan exclude_perf), 1786bea03405SNamhyung Kim OPT_STRING('p', "pid", &record.opts.target.pid, "pid", 1787d6d901c2SZhang, Yanmin "record events on existing process id"), 1788bea03405SNamhyung Kim OPT_STRING('t', "tid", &record.opts.target.tid, "tid", 1789d6d901c2SZhang, Yanmin "record events on existing thread id"), 1790d20deb64SArnaldo Carvalho de Melo OPT_INTEGER('r', "realtime", &record.realtime_prio, 179186470930SIngo Molnar "collect data with this RT SCHED_FIFO priority"), 1792509051eaSArnaldo Carvalho de Melo OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering, 1793acac03faSKirill Smelkov "collect data without buffering"), 1794d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples, 1795daac07b2SFrederic Weisbecker "collect raw sample records from all opened counters"), 1796bea03405SNamhyung Kim OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide, 179786470930SIngo Molnar "system-wide collection from all CPUs"), 1798bea03405SNamhyung Kim OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", 1799c45c6ea2SStephane Eranian "list of cpus to monitor"), 1800d20deb64SArnaldo Carvalho de Melo OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"), 1801eae8ad80SJiri Olsa OPT_STRING('o', "output", &record.data.file.path, "file", 180286470930SIngo Molnar "output file name"), 180369e7e5b0SAdrian Hunter OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit, 180469e7e5b0SAdrian Hunter &record.opts.no_inherit_set, 18052e6cdf99SStephane Eranian "child tasks do not inherit counters"), 18064ea648aeSWang Nan OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize, 18074ea648aeSWang Nan "synthesize non-sample events at the end of output"), 1808626a6b78SWang Nan OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"), 1809b09c2364SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "strict-freq", &record.opts.strict_freq, 1810b09c2364SArnaldo Carvalho de Melo "Fail if the specified frequency can't be used"), 181167230479SArnaldo Carvalho de Melo OPT_CALLBACK('F', "freq", &record.opts, "freq or 'max'", 181267230479SArnaldo Carvalho de Melo "profile at this frequency", 181367230479SArnaldo Carvalho de Melo record__parse_freq), 1814e9db1310SAdrian Hunter OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]", 1815e9db1310SAdrian Hunter "number of mmap data pages and AUX area tracing mmap pages", 1816e9db1310SAdrian Hunter record__parse_mmap_pages), 1817d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "group", &record.opts.group, 181843bece79SLin Ming "put the counters into a counter group"), 18192ddd5c04SArnaldo Carvalho de Melo OPT_CALLBACK_NOOPT('g', NULL, &callchain_param, 182009b0fd45SJiri Olsa NULL, "enables call-graph recording" , 182109b0fd45SJiri Olsa &record_callchain_opt), 182209b0fd45SJiri Olsa OPT_CALLBACK(0, "call-graph", &record.opts, 182376a26549SNamhyung Kim "record_mode[,record_size]", record_callchain_help, 182409b0fd45SJiri Olsa &record_parse_callchain_opt), 1825c0555642SIan Munsie OPT_INCR('v', "verbose", &verbose, 18263da297a6SIngo Molnar "be more verbose (show counter open errors, etc)"), 1827b44308f5SArnaldo Carvalho de Melo OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"), 1828d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat, 1829649c48a9SPeter Zijlstra "per thread counts"), 183056100321SPeter Zijlstra OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"), 18313b0a5daaSKan Liang OPT_BOOLEAN(0, "phys-data", &record.opts.sample_phys_addr, 18323b0a5daaSKan Liang "Record the sample physical addresses"), 1833b6f35ed7SJiri Olsa OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"), 18343abebc55SAdrian Hunter OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time, 18353abebc55SAdrian Hunter &record.opts.sample_time_set, 18363abebc55SAdrian Hunter "Record the sample timestamps"), 1837f290aa1fSJiri Olsa OPT_BOOLEAN_SET('P', "period", &record.opts.period, &record.opts.period_set, 1838f290aa1fSJiri Olsa "Record the sample period"), 1839d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples, 1840649c48a9SPeter Zijlstra "don't sample"), 1841d2db9a98SWang Nan OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache, 1842d2db9a98SWang Nan &record.no_buildid_cache_set, 1843a1ac1d3cSStephane Eranian "do not update the buildid cache"), 1844d2db9a98SWang Nan OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid, 1845d2db9a98SWang Nan &record.no_buildid_set, 1846baa2f6ceSArnaldo Carvalho de Melo "do not collect buildids in perf.data"), 1847d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK('G', "cgroup", &record.evlist, "name", 1848023695d9SStephane Eranian "monitor event in cgroup name only", 1849023695d9SStephane Eranian parse_cgroups), 1850a6205a35SArnaldo Carvalho de Melo OPT_UINTEGER('D', "delay", &record.opts.initial_delay, 18516619a53eSAndi Kleen "ms to wait before starting measurement after program start"), 1852bea03405SNamhyung Kim OPT_STRING('u', "uid", &record.opts.target.uid_str, "user", 1853bea03405SNamhyung Kim "user to profile"), 1854a5aabdacSStephane Eranian 1855a5aabdacSStephane Eranian OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack, 1856a5aabdacSStephane Eranian "branch any", "sample any taken branches", 1857a5aabdacSStephane Eranian parse_branch_stack), 1858a5aabdacSStephane Eranian 1859a5aabdacSStephane Eranian OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack, 1860a5aabdacSStephane Eranian "branch filter mask", "branch stack filter modes", 1861bdfebd84SRoberto Agostino Vitillo parse_branch_stack), 186205484298SAndi Kleen OPT_BOOLEAN('W', "weight", &record.opts.sample_weight, 186305484298SAndi Kleen "sample by weight (on special events only)"), 1864475eeab9SAndi Kleen OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction, 1865475eeab9SAndi Kleen "sample transaction flags (special events only)"), 18663aa5939dSAdrian Hunter OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread, 18673aa5939dSAdrian Hunter "use per-thread mmaps"), 1868bcc84ec6SStephane Eranian OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register", 1869bcc84ec6SStephane Eranian "sample selected machine registers on interrupt," 1870bcc84ec6SStephane Eranian " use -I ? to list register names", parse_regs), 187184c41742SAndi Kleen OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register", 187284c41742SAndi Kleen "sample selected machine registers on interrupt," 187384c41742SAndi Kleen " use -I ? to list register names", parse_regs), 187485c273d2SAndi Kleen OPT_BOOLEAN(0, "running-time", &record.opts.running_time, 187585c273d2SAndi Kleen "Record running/enabled time of read (:S) events"), 1876814c8c38SPeter Zijlstra OPT_CALLBACK('k', "clockid", &record.opts, 1877814c8c38SPeter Zijlstra "clockid", "clockid to use for events, see clock_gettime()", 1878814c8c38SPeter Zijlstra parse_clockid), 18792dd6d8a1SAdrian Hunter OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts, 18802dd6d8a1SAdrian Hunter "opts", "AUX area tracing Snapshot Mode", ""), 18819d9cad76SKan Liang OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout, 18829d9cad76SKan Liang "per thread proc mmap processing timeout in ms"), 1883f3b3614aSHari Bathini OPT_BOOLEAN(0, "namespaces", &record.opts.record_namespaces, 1884f3b3614aSHari Bathini "Record namespaces events"), 1885b757bb09SAdrian Hunter OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events, 1886b757bb09SAdrian Hunter "Record context switch events"), 188785723885SJiri Olsa OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel, 188885723885SJiri Olsa "Configure all used events to run in kernel space.", 188985723885SJiri Olsa PARSE_OPT_EXCLUSIVE), 189085723885SJiri Olsa OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user, 189185723885SJiri Olsa "Configure all used events to run in user space.", 189285723885SJiri Olsa PARSE_OPT_EXCLUSIVE), 189371dc2326SWang Nan OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", 189471dc2326SWang Nan "clang binary to use for compiling BPF scriptlets"), 189571dc2326SWang Nan OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", 189671dc2326SWang Nan "options passed to clang when compiling BPF scriptlets"), 18977efe0e03SHe Kuang OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, 18987efe0e03SHe Kuang "file", "vmlinux pathname"), 18996156681bSNamhyung Kim OPT_BOOLEAN(0, "buildid-all", &record.buildid_all, 19006156681bSNamhyung Kim "Record build-id of all DSOs regardless of hits"), 1901ecfd7a9cSWang Nan OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename, 1902ecfd7a9cSWang Nan "append timestamp to output filename"), 190368588bafSJin Yao OPT_BOOLEAN(0, "timestamp-boundary", &record.timestamp_boundary, 190468588bafSJin Yao "Record timestamp boundary (time of first/last samples)"), 1905cb4e1ebbSJiri Olsa OPT_STRING_OPTARG_SET(0, "switch-output", &record.switch_output.str, 1906bfacbe3bSJiri Olsa &record.switch_output.set, "signal,size,time", 1907bfacbe3bSJiri Olsa "Switch output when receive SIGUSR2 or cross size,time threshold", 1908dc0c6127SJiri Olsa "signal"), 19090aab2136SWang Nan OPT_BOOLEAN(0, "dry-run", &dry_run, 19100aab2136SWang Nan "Parse options then exit"), 1911*d3d1af6fSAlexey Budankov #ifdef HAVE_AIO_SUPPORT 1912*d3d1af6fSAlexey Budankov OPT_CALLBACK_NOOPT(0, "aio", &record.opts, 1913*d3d1af6fSAlexey Budankov NULL, "Enable asynchronous trace writing mode", 1914*d3d1af6fSAlexey Budankov record__aio_parse), 1915*d3d1af6fSAlexey Budankov #endif 191686470930SIngo Molnar OPT_END() 191786470930SIngo Molnar }; 191886470930SIngo Molnar 1919e5b2c207SNamhyung Kim struct option *record_options = __record_options; 1920e5b2c207SNamhyung Kim 1921b0ad8ea6SArnaldo Carvalho de Melo int cmd_record(int argc, const char **argv) 192286470930SIngo Molnar { 1923ef149c25SAdrian Hunter int err; 19248c6f45a7SArnaldo Carvalho de Melo struct record *rec = &record; 192516ad2ffbSNamhyung Kim char errbuf[BUFSIZ]; 192686470930SIngo Molnar 192767230479SArnaldo Carvalho de Melo setlocale(LC_ALL, ""); 192867230479SArnaldo Carvalho de Melo 192948e1cab1SWang Nan #ifndef HAVE_LIBBPF_SUPPORT 193048e1cab1SWang Nan # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c) 193148e1cab1SWang Nan set_nobuild('\0', "clang-path", true); 193248e1cab1SWang Nan set_nobuild('\0', "clang-opt", true); 193348e1cab1SWang Nan # undef set_nobuild 193448e1cab1SWang Nan #endif 193548e1cab1SWang Nan 19367efe0e03SHe Kuang #ifndef HAVE_BPF_PROLOGUE 19377efe0e03SHe Kuang # if !defined (HAVE_DWARF_SUPPORT) 19387efe0e03SHe Kuang # define REASON "NO_DWARF=1" 19397efe0e03SHe Kuang # elif !defined (HAVE_LIBBPF_SUPPORT) 19407efe0e03SHe Kuang # define REASON "NO_LIBBPF=1" 19417efe0e03SHe Kuang # else 19427efe0e03SHe Kuang # define REASON "this architecture doesn't support BPF prologue" 19437efe0e03SHe Kuang # endif 19447efe0e03SHe Kuang # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c) 19457efe0e03SHe Kuang set_nobuild('\0', "vmlinux", true); 19467efe0e03SHe Kuang # undef set_nobuild 19477efe0e03SHe Kuang # undef REASON 19487efe0e03SHe Kuang #endif 19497efe0e03SHe Kuang 19503e2be2daSArnaldo Carvalho de Melo rec->evlist = perf_evlist__new(); 19513e2be2daSArnaldo Carvalho de Melo if (rec->evlist == NULL) 1952361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1953361c99a6SArnaldo Carvalho de Melo 1954ecc4c561SArnaldo Carvalho de Melo err = perf_config(perf_record_config, rec); 1955ecc4c561SArnaldo Carvalho de Melo if (err) 1956ecc4c561SArnaldo Carvalho de Melo return err; 1957eb853e80SJiri Olsa 1958bca647aaSTom Zanussi argc = parse_options(argc, argv, record_options, record_usage, 1959a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 196068ba3235SNamhyung Kim if (quiet) 196168ba3235SNamhyung Kim perf_quiet_option(); 1962483635a9SJiri Olsa 1963483635a9SJiri Olsa /* Make system wide (-a) the default target. */ 1964602ad878SArnaldo Carvalho de Melo if (!argc && target__none(&rec->opts.target)) 1965483635a9SJiri Olsa rec->opts.target.system_wide = true; 196686470930SIngo Molnar 1967bea03405SNamhyung Kim if (nr_cgroups && !rec->opts.target.system_wide) { 1968c7118369SNamhyung Kim usage_with_options_msg(record_usage, record_options, 1969c7118369SNamhyung Kim "cgroup monitoring only available in system-wide mode"); 1970c7118369SNamhyung Kim 1971023695d9SStephane Eranian } 1972b757bb09SAdrian Hunter if (rec->opts.record_switch_events && 1973b757bb09SAdrian Hunter !perf_can_record_switch_events()) { 1974c7118369SNamhyung Kim ui__error("kernel does not support recording context switch events\n"); 1975c7118369SNamhyung Kim parse_options_usage(record_usage, record_options, "switch-events", 0); 1976c7118369SNamhyung Kim return -EINVAL; 1977b757bb09SAdrian Hunter } 1978023695d9SStephane Eranian 1979cb4e1ebbSJiri Olsa if (switch_output_setup(rec)) { 1980cb4e1ebbSJiri Olsa parse_options_usage(record_usage, record_options, "switch-output", 0); 1981cb4e1ebbSJiri Olsa return -EINVAL; 1982cb4e1ebbSJiri Olsa } 1983cb4e1ebbSJiri Olsa 1984bfacbe3bSJiri Olsa if (rec->switch_output.time) { 1985bfacbe3bSJiri Olsa signal(SIGALRM, alarm_sig_handler); 1986bfacbe3bSJiri Olsa alarm(rec->switch_output.time); 1987bfacbe3bSJiri Olsa } 1988bfacbe3bSJiri Olsa 19891b36c03eSAdrian Hunter /* 19901b36c03eSAdrian Hunter * Allow aliases to facilitate the lookup of symbols for address 19911b36c03eSAdrian Hunter * filters. Refer to auxtrace_parse_filters(). 19921b36c03eSAdrian Hunter */ 19931b36c03eSAdrian Hunter symbol_conf.allow_aliases = true; 19941b36c03eSAdrian Hunter 19951b36c03eSAdrian Hunter symbol__init(NULL); 19961b36c03eSAdrian Hunter 19974b5ea3bdSAdrian Hunter err = record__auxtrace_init(rec); 19981b36c03eSAdrian Hunter if (err) 19991b36c03eSAdrian Hunter goto out; 20001b36c03eSAdrian Hunter 20010aab2136SWang Nan if (dry_run) 20025c01ad60SAdrian Hunter goto out; 20030aab2136SWang Nan 2004d7888573SWang Nan err = bpf__setup_stdout(rec->evlist); 2005d7888573SWang Nan if (err) { 2006d7888573SWang Nan bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf)); 2007d7888573SWang Nan pr_err("ERROR: Setup BPF stdout failed: %s\n", 2008d7888573SWang Nan errbuf); 20095c01ad60SAdrian Hunter goto out; 2010d7888573SWang Nan } 2011d7888573SWang Nan 2012ef149c25SAdrian Hunter err = -ENOMEM; 2013ef149c25SAdrian Hunter 20146c443954SArnaldo Carvalho de Melo if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(rec->evlist)) 2015646aaea6SArnaldo Carvalho de Melo pr_warning( 2016646aaea6SArnaldo Carvalho de Melo "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" 2017ec80fde7SArnaldo Carvalho de Melo "check /proc/sys/kernel/kptr_restrict.\n\n" 2018646aaea6SArnaldo Carvalho de Melo "Samples in kernel functions may not be resolved if a suitable vmlinux\n" 2019646aaea6SArnaldo Carvalho de Melo "file is not found in the buildid cache or in the vmlinux path.\n\n" 2020646aaea6SArnaldo Carvalho de Melo "Samples in kernel modules won't be resolved at all.\n\n" 2021646aaea6SArnaldo Carvalho de Melo "If some relocation was applied (e.g. kexec) symbols may be misresolved\n" 2022646aaea6SArnaldo Carvalho de Melo "even with a suitable vmlinux or kallsyms file.\n\n"); 2023ec80fde7SArnaldo Carvalho de Melo 20240c1d46a8SWang Nan if (rec->no_buildid_cache || rec->no_buildid) { 2025a1ac1d3cSStephane Eranian disable_buildid_cache(); 2026dc0c6127SJiri Olsa } else if (rec->switch_output.enabled) { 20270c1d46a8SWang Nan /* 20280c1d46a8SWang Nan * In 'perf record --switch-output', disable buildid 20290c1d46a8SWang Nan * generation by default to reduce data file switching 20300c1d46a8SWang Nan * overhead. Still generate buildid if they are required 20310c1d46a8SWang Nan * explicitly using 20320c1d46a8SWang Nan * 203360437ac0SJiri Olsa * perf record --switch-output --no-no-buildid \ 20340c1d46a8SWang Nan * --no-no-buildid-cache 20350c1d46a8SWang Nan * 20360c1d46a8SWang Nan * Following code equals to: 20370c1d46a8SWang Nan * 20380c1d46a8SWang Nan * if ((rec->no_buildid || !rec->no_buildid_set) && 20390c1d46a8SWang Nan * (rec->no_buildid_cache || !rec->no_buildid_cache_set)) 20400c1d46a8SWang Nan * disable_buildid_cache(); 20410c1d46a8SWang Nan */ 20420c1d46a8SWang Nan bool disable = true; 20430c1d46a8SWang Nan 20440c1d46a8SWang Nan if (rec->no_buildid_set && !rec->no_buildid) 20450c1d46a8SWang Nan disable = false; 20460c1d46a8SWang Nan if (rec->no_buildid_cache_set && !rec->no_buildid_cache) 20470c1d46a8SWang Nan disable = false; 20480c1d46a8SWang Nan if (disable) { 20490c1d46a8SWang Nan rec->no_buildid = true; 20500c1d46a8SWang Nan rec->no_buildid_cache = true; 20510c1d46a8SWang Nan disable_buildid_cache(); 20520c1d46a8SWang Nan } 20530c1d46a8SWang Nan } 2054655000e7SArnaldo Carvalho de Melo 20554ea648aeSWang Nan if (record.opts.overwrite) 20564ea648aeSWang Nan record.opts.tail_synthesize = true; 20574ea648aeSWang Nan 20583e2be2daSArnaldo Carvalho de Melo if (rec->evlist->nr_entries == 0 && 20594b4cd503SArnaldo Carvalho de Melo __perf_evlist__add_default(rec->evlist, !record.opts.no_samples) < 0) { 206069aad6f1SArnaldo Carvalho de Melo pr_err("Not enough memory for event selector list\n"); 2061394c01edSAdrian Hunter goto out; 2062bbd36e5eSPeter Zijlstra } 206386470930SIngo Molnar 206469e7e5b0SAdrian Hunter if (rec->opts.target.tid && !rec->opts.no_inherit_set) 206569e7e5b0SAdrian Hunter rec->opts.no_inherit = true; 206669e7e5b0SAdrian Hunter 2067602ad878SArnaldo Carvalho de Melo err = target__validate(&rec->opts.target); 206816ad2ffbSNamhyung Kim if (err) { 2069602ad878SArnaldo Carvalho de Melo target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); 2070c3dec27bSJiri Olsa ui__warning("%s\n", errbuf); 207116ad2ffbSNamhyung Kim } 20724bd0f2d2SNamhyung Kim 2073602ad878SArnaldo Carvalho de Melo err = target__parse_uid(&rec->opts.target); 207416ad2ffbSNamhyung Kim if (err) { 207516ad2ffbSNamhyung Kim int saved_errno = errno; 207616ad2ffbSNamhyung Kim 2077602ad878SArnaldo Carvalho de Melo target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); 20783780f488SNamhyung Kim ui__error("%s", errbuf); 207916ad2ffbSNamhyung Kim 208016ad2ffbSNamhyung Kim err = -saved_errno; 2081394c01edSAdrian Hunter goto out; 208216ad2ffbSNamhyung Kim } 20830d37aa34SArnaldo Carvalho de Melo 2084ca800068SMengting Zhang /* Enable ignoring missing threads when -u/-p option is defined. */ 2085ca800068SMengting Zhang rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX || rec->opts.target.pid; 208623dc4f15SJiri Olsa 208716ad2ffbSNamhyung Kim err = -ENOMEM; 20883e2be2daSArnaldo Carvalho de Melo if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0) 2089dd7927f4SArnaldo Carvalho de Melo usage_with_options(record_usage, record_options); 209069aad6f1SArnaldo Carvalho de Melo 2091ef149c25SAdrian Hunter err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts); 2092ef149c25SAdrian Hunter if (err) 2093394c01edSAdrian Hunter goto out; 2094ef149c25SAdrian Hunter 20956156681bSNamhyung Kim /* 20966156681bSNamhyung Kim * We take all buildids when the file contains 20976156681bSNamhyung Kim * AUX area tracing data because we do not decode the 20986156681bSNamhyung Kim * trace because it would take too long. 20996156681bSNamhyung Kim */ 21006156681bSNamhyung Kim if (rec->opts.full_auxtrace) 21016156681bSNamhyung Kim rec->buildid_all = true; 21026156681bSNamhyung Kim 2103b4006796SArnaldo Carvalho de Melo if (record_opts__config(&rec->opts)) { 210439d17dacSArnaldo Carvalho de Melo err = -EINVAL; 2105394c01edSAdrian Hunter goto out; 21067e4ff9e3SMike Galbraith } 21077e4ff9e3SMike Galbraith 2108*d3d1af6fSAlexey Budankov if (verbose > 0) 2109*d3d1af6fSAlexey Budankov pr_info("nr_cblocks: %d\n", rec->opts.nr_cblocks); 2110*d3d1af6fSAlexey Budankov 2111d20deb64SArnaldo Carvalho de Melo err = __cmd_record(&record, argc, argv); 2112394c01edSAdrian Hunter out: 211345604710SNamhyung Kim perf_evlist__delete(rec->evlist); 2114d65a458bSArnaldo Carvalho de Melo symbol__exit(); 2115ef149c25SAdrian Hunter auxtrace_record__free(rec->itr); 211639d17dacSArnaldo Carvalho de Melo return err; 211786470930SIngo Molnar } 21182dd6d8a1SAdrian Hunter 21192dd6d8a1SAdrian Hunter static void snapshot_sig_handler(int sig __maybe_unused) 21202dd6d8a1SAdrian Hunter { 2121dc0c6127SJiri Olsa struct record *rec = &record; 2122dc0c6127SJiri Olsa 21235f9cf599SWang Nan if (trigger_is_ready(&auxtrace_snapshot_trigger)) { 21245f9cf599SWang Nan trigger_hit(&auxtrace_snapshot_trigger); 21252dd6d8a1SAdrian Hunter auxtrace_record__snapshot_started = 1; 21265f9cf599SWang Nan if (auxtrace_record__snapshot_start(record.itr)) 21275f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 21285f9cf599SWang Nan } 21293c1cb7e3SWang Nan 2130dc0c6127SJiri Olsa if (switch_output_signal(rec)) 21313c1cb7e3SWang Nan trigger_hit(&switch_output_trigger); 21322dd6d8a1SAdrian Hunter } 2133bfacbe3bSJiri Olsa 2134bfacbe3bSJiri Olsa static void alarm_sig_handler(int sig __maybe_unused) 2135bfacbe3bSJiri Olsa { 2136bfacbe3bSJiri Olsa struct record *rec = &record; 2137bfacbe3bSJiri Olsa 2138bfacbe3bSJiri Olsa if (switch_output_time(rec)) 2139bfacbe3bSJiri Olsa trigger_hit(&switch_output_trigger); 2140bfacbe3bSJiri Olsa } 2141