186470930SIngo Molnar /* 286470930SIngo Molnar * builtin-record.c 386470930SIngo Molnar * 486470930SIngo Molnar * Builtin record command: Record the profile of a workload 586470930SIngo Molnar * (or a CPU, or a PID) into the perf.data output file - for 686470930SIngo Molnar * later analysis via perf report. 786470930SIngo Molnar */ 886470930SIngo Molnar #include "builtin.h" 986470930SIngo Molnar 1086470930SIngo Molnar #include "perf.h" 1186470930SIngo Molnar 126122e4e4SArnaldo Carvalho de Melo #include "util/build-id.h" 1386470930SIngo Molnar #include "util/util.h" 144b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h> 1586470930SIngo Molnar #include "util/parse-events.h" 1686470930SIngo Molnar 178f651eaeSArnaldo Carvalho de Melo #include "util/callchain.h" 18f14d5707SArnaldo Carvalho de Melo #include "util/cgroup.h" 197c6a1c65SPeter Zijlstra #include "util/header.h" 2066e274f3SFrederic Weisbecker #include "util/event.h" 21361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h" 2269aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h" 238f28827aSFrederic Weisbecker #include "util/debug.h" 2494c744b6SArnaldo Carvalho de Melo #include "util/session.h" 2545694aa7SArnaldo Carvalho de Melo #include "util/tool.h" 268d06367fSArnaldo Carvalho de Melo #include "util/symbol.h" 27a12b51c4SPaul Mackerras #include "util/cpumap.h" 28fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 29f5fc1412SJiri Olsa #include "util/data.h" 30bcc84ec6SStephane Eranian #include "util/perf_regs.h" 31ef149c25SAdrian Hunter #include "util/auxtrace.h" 3246bc29b9SAdrian Hunter #include "util/tsc.h" 33f00898f4SAndi Kleen #include "util/parse-branch-options.h" 34bcc84ec6SStephane Eranian #include "util/parse-regs-options.h" 3571dc2326SWang Nan #include "util/llvm-utils.h" 368690a2a7SWang Nan #include "util/bpf-loader.h" 375f9cf599SWang Nan #include "util/trigger.h" 38d8871ea7SWang Nan #include "asm/bug.h" 397c6a1c65SPeter Zijlstra 4086470930SIngo Molnar #include <unistd.h> 4186470930SIngo Molnar #include <sched.h> 42a41794cdSArnaldo Carvalho de Melo #include <sys/mman.h> 432d11c650SWang Nan #include <asm/bug.h> 4486470930SIngo Molnar 4578da39faSBernhard Rosenkraenzer 468c6f45a7SArnaldo Carvalho de Melo struct record { 4745694aa7SArnaldo Carvalho de Melo struct perf_tool tool; 48b4006796SArnaldo Carvalho de Melo struct record_opts opts; 49d20deb64SArnaldo Carvalho de Melo u64 bytes_written; 50f5fc1412SJiri Olsa struct perf_data_file file; 51ef149c25SAdrian Hunter struct auxtrace_record *itr; 52d20deb64SArnaldo Carvalho de Melo struct perf_evlist *evlist; 53d20deb64SArnaldo Carvalho de Melo struct perf_session *session; 54d20deb64SArnaldo Carvalho de Melo const char *progname; 55d20deb64SArnaldo Carvalho de Melo int realtime_prio; 56d20deb64SArnaldo Carvalho de Melo bool no_buildid; 57d2db9a98SWang Nan bool no_buildid_set; 58d20deb64SArnaldo Carvalho de Melo bool no_buildid_cache; 59d2db9a98SWang Nan bool no_buildid_cache_set; 606156681bSNamhyung Kim bool buildid_all; 61ecfd7a9cSWang Nan bool timestamp_filename; 623c1cb7e3SWang Nan bool switch_output; 639f065194SYang Shi unsigned long long samples; 640f82ebc4SArnaldo Carvalho de Melo }; 6586470930SIngo Molnar 668c6f45a7SArnaldo Carvalho de Melo static int record__write(struct record *rec, void *bf, size_t size) 67f5970550SPeter Zijlstra { 68cf8b2e69SArnaldo Carvalho de Melo if (perf_data_file__write(rec->session->file, bf, size) < 0) { 694f624685SAdrian Hunter pr_err("failed to write perf data, error: %m\n"); 708d3eca20SDavid Ahern return -1; 718d3eca20SDavid Ahern } 72f5970550SPeter Zijlstra 73cf8b2e69SArnaldo Carvalho de Melo rec->bytes_written += size; 748d3eca20SDavid Ahern return 0; 75f5970550SPeter Zijlstra } 76f5970550SPeter Zijlstra 7745694aa7SArnaldo Carvalho de Melo static int process_synthesized_event(struct perf_tool *tool, 78d20deb64SArnaldo Carvalho de Melo union perf_event *event, 791d037ca1SIrina Tirdea struct perf_sample *sample __maybe_unused, 801d037ca1SIrina Tirdea struct machine *machine __maybe_unused) 81234fbbf5SArnaldo Carvalho de Melo { 828c6f45a7SArnaldo Carvalho de Melo struct record *rec = container_of(tool, struct record, tool); 838c6f45a7SArnaldo Carvalho de Melo return record__write(rec, event, event->header.size); 84234fbbf5SArnaldo Carvalho de Melo } 85234fbbf5SArnaldo Carvalho de Melo 86e5685730SArnaldo Carvalho de Melo static int record__mmap_read(struct record *rec, int idx) 8786470930SIngo Molnar { 88e5685730SArnaldo Carvalho de Melo struct perf_mmap *md = &rec->evlist->mmap[idx]; 897b8283b5SDavid Ahern u64 head = perf_mmap__read_head(md); 907b8283b5SDavid Ahern u64 old = md->prev; 91*09fa4f40SWang Nan u64 end = head, start = old; 92918512b4SJiri Olsa unsigned char *data = md->base + page_size; 9386470930SIngo Molnar unsigned long size; 9486470930SIngo Molnar void *buf; 958d3eca20SDavid Ahern int rc = 0; 9686470930SIngo Molnar 97*09fa4f40SWang Nan if (start == end) 988d3eca20SDavid Ahern return 0; 9986470930SIngo Molnar 100d20deb64SArnaldo Carvalho de Melo rec->samples++; 10186470930SIngo Molnar 102*09fa4f40SWang Nan size = end - start; 1032d11c650SWang Nan if (size > (unsigned long)(md->mask) + 1) { 1042d11c650SWang Nan WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); 1052d11c650SWang Nan 1062d11c650SWang Nan md->prev = head; 1072d11c650SWang Nan perf_evlist__mmap_consume(rec->evlist, idx); 1082d11c650SWang Nan return 0; 1092d11c650SWang Nan } 11086470930SIngo Molnar 111*09fa4f40SWang Nan if ((start & md->mask) + size != (end & md->mask)) { 112*09fa4f40SWang Nan buf = &data[start & md->mask]; 113*09fa4f40SWang Nan size = md->mask + 1 - (start & md->mask); 114*09fa4f40SWang Nan start += size; 11586470930SIngo Molnar 1168c6f45a7SArnaldo Carvalho de Melo if (record__write(rec, buf, size) < 0) { 1178d3eca20SDavid Ahern rc = -1; 1188d3eca20SDavid Ahern goto out; 1198d3eca20SDavid Ahern } 12086470930SIngo Molnar } 12186470930SIngo Molnar 122*09fa4f40SWang Nan buf = &data[start & md->mask]; 123*09fa4f40SWang Nan size = end - start; 124*09fa4f40SWang Nan start += size; 12586470930SIngo Molnar 1268c6f45a7SArnaldo Carvalho de Melo if (record__write(rec, buf, size) < 0) { 1278d3eca20SDavid Ahern rc = -1; 1288d3eca20SDavid Ahern goto out; 1298d3eca20SDavid Ahern } 13086470930SIngo Molnar 131*09fa4f40SWang Nan md->prev = head; 132e5685730SArnaldo Carvalho de Melo perf_evlist__mmap_consume(rec->evlist, idx); 1338d3eca20SDavid Ahern out: 1348d3eca20SDavid Ahern return rc; 13586470930SIngo Molnar } 13686470930SIngo Molnar 1372dd6d8a1SAdrian Hunter static volatile int done; 1382dd6d8a1SAdrian Hunter static volatile int signr = -1; 1392dd6d8a1SAdrian Hunter static volatile int child_finished; 140c0bdc1c4SWang Nan 1412dd6d8a1SAdrian Hunter static volatile int auxtrace_record__snapshot_started; 1425f9cf599SWang Nan static DEFINE_TRIGGER(auxtrace_snapshot_trigger); 1433c1cb7e3SWang Nan static DEFINE_TRIGGER(switch_output_trigger); 1442dd6d8a1SAdrian Hunter 1452dd6d8a1SAdrian Hunter static void sig_handler(int sig) 1462dd6d8a1SAdrian Hunter { 1472dd6d8a1SAdrian Hunter if (sig == SIGCHLD) 1482dd6d8a1SAdrian Hunter child_finished = 1; 1492dd6d8a1SAdrian Hunter else 1502dd6d8a1SAdrian Hunter signr = sig; 1512dd6d8a1SAdrian Hunter 1522dd6d8a1SAdrian Hunter done = 1; 1532dd6d8a1SAdrian Hunter } 1542dd6d8a1SAdrian Hunter 1552dd6d8a1SAdrian Hunter static void record__sig_exit(void) 1562dd6d8a1SAdrian Hunter { 1572dd6d8a1SAdrian Hunter if (signr == -1) 1582dd6d8a1SAdrian Hunter return; 1592dd6d8a1SAdrian Hunter 1602dd6d8a1SAdrian Hunter signal(signr, SIG_DFL); 1612dd6d8a1SAdrian Hunter raise(signr); 1622dd6d8a1SAdrian Hunter } 1632dd6d8a1SAdrian Hunter 164e31f0d01SAdrian Hunter #ifdef HAVE_AUXTRACE_SUPPORT 165e31f0d01SAdrian Hunter 166ef149c25SAdrian Hunter static int record__process_auxtrace(struct perf_tool *tool, 167ef149c25SAdrian Hunter union perf_event *event, void *data1, 168ef149c25SAdrian Hunter size_t len1, void *data2, size_t len2) 169ef149c25SAdrian Hunter { 170ef149c25SAdrian Hunter struct record *rec = container_of(tool, struct record, tool); 17199fa2984SAdrian Hunter struct perf_data_file *file = &rec->file; 172ef149c25SAdrian Hunter size_t padding; 173ef149c25SAdrian Hunter u8 pad[8] = {0}; 174ef149c25SAdrian Hunter 17599fa2984SAdrian Hunter if (!perf_data_file__is_pipe(file)) { 17699fa2984SAdrian Hunter off_t file_offset; 17799fa2984SAdrian Hunter int fd = perf_data_file__fd(file); 17899fa2984SAdrian Hunter int err; 17999fa2984SAdrian Hunter 18099fa2984SAdrian Hunter file_offset = lseek(fd, 0, SEEK_CUR); 18199fa2984SAdrian Hunter if (file_offset == -1) 18299fa2984SAdrian Hunter return -1; 18399fa2984SAdrian Hunter err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index, 18499fa2984SAdrian Hunter event, file_offset); 18599fa2984SAdrian Hunter if (err) 18699fa2984SAdrian Hunter return err; 18799fa2984SAdrian Hunter } 18899fa2984SAdrian Hunter 189ef149c25SAdrian Hunter /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */ 190ef149c25SAdrian Hunter padding = (len1 + len2) & 7; 191ef149c25SAdrian Hunter if (padding) 192ef149c25SAdrian Hunter padding = 8 - padding; 193ef149c25SAdrian Hunter 194ef149c25SAdrian Hunter record__write(rec, event, event->header.size); 195ef149c25SAdrian Hunter record__write(rec, data1, len1); 196ef149c25SAdrian Hunter if (len2) 197ef149c25SAdrian Hunter record__write(rec, data2, len2); 198ef149c25SAdrian Hunter record__write(rec, &pad, padding); 199ef149c25SAdrian Hunter 200ef149c25SAdrian Hunter return 0; 201ef149c25SAdrian Hunter } 202ef149c25SAdrian Hunter 203ef149c25SAdrian Hunter static int record__auxtrace_mmap_read(struct record *rec, 204ef149c25SAdrian Hunter struct auxtrace_mmap *mm) 205ef149c25SAdrian Hunter { 206ef149c25SAdrian Hunter int ret; 207ef149c25SAdrian Hunter 208ef149c25SAdrian Hunter ret = auxtrace_mmap__read(mm, rec->itr, &rec->tool, 209ef149c25SAdrian Hunter record__process_auxtrace); 210ef149c25SAdrian Hunter if (ret < 0) 211ef149c25SAdrian Hunter return ret; 212ef149c25SAdrian Hunter 213ef149c25SAdrian Hunter if (ret) 214ef149c25SAdrian Hunter rec->samples++; 215ef149c25SAdrian Hunter 216ef149c25SAdrian Hunter return 0; 217ef149c25SAdrian Hunter } 218ef149c25SAdrian Hunter 2192dd6d8a1SAdrian Hunter static int record__auxtrace_mmap_read_snapshot(struct record *rec, 2202dd6d8a1SAdrian Hunter struct auxtrace_mmap *mm) 2212dd6d8a1SAdrian Hunter { 2222dd6d8a1SAdrian Hunter int ret; 2232dd6d8a1SAdrian Hunter 2242dd6d8a1SAdrian Hunter ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool, 2252dd6d8a1SAdrian Hunter record__process_auxtrace, 2262dd6d8a1SAdrian Hunter rec->opts.auxtrace_snapshot_size); 2272dd6d8a1SAdrian Hunter if (ret < 0) 2282dd6d8a1SAdrian Hunter return ret; 2292dd6d8a1SAdrian Hunter 2302dd6d8a1SAdrian Hunter if (ret) 2312dd6d8a1SAdrian Hunter rec->samples++; 2322dd6d8a1SAdrian Hunter 2332dd6d8a1SAdrian Hunter return 0; 2342dd6d8a1SAdrian Hunter } 2352dd6d8a1SAdrian Hunter 2362dd6d8a1SAdrian Hunter static int record__auxtrace_read_snapshot_all(struct record *rec) 2372dd6d8a1SAdrian Hunter { 2382dd6d8a1SAdrian Hunter int i; 2392dd6d8a1SAdrian Hunter int rc = 0; 2402dd6d8a1SAdrian Hunter 2412dd6d8a1SAdrian Hunter for (i = 0; i < rec->evlist->nr_mmaps; i++) { 2422dd6d8a1SAdrian Hunter struct auxtrace_mmap *mm = 2432dd6d8a1SAdrian Hunter &rec->evlist->mmap[i].auxtrace_mmap; 2442dd6d8a1SAdrian Hunter 2452dd6d8a1SAdrian Hunter if (!mm->base) 2462dd6d8a1SAdrian Hunter continue; 2472dd6d8a1SAdrian Hunter 2482dd6d8a1SAdrian Hunter if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) { 2492dd6d8a1SAdrian Hunter rc = -1; 2502dd6d8a1SAdrian Hunter goto out; 2512dd6d8a1SAdrian Hunter } 2522dd6d8a1SAdrian Hunter } 2532dd6d8a1SAdrian Hunter out: 2542dd6d8a1SAdrian Hunter return rc; 2552dd6d8a1SAdrian Hunter } 2562dd6d8a1SAdrian Hunter 2572dd6d8a1SAdrian Hunter static void record__read_auxtrace_snapshot(struct record *rec) 2582dd6d8a1SAdrian Hunter { 2592dd6d8a1SAdrian Hunter pr_debug("Recording AUX area tracing snapshot\n"); 2602dd6d8a1SAdrian Hunter if (record__auxtrace_read_snapshot_all(rec) < 0) { 2615f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 2622dd6d8a1SAdrian Hunter } else { 2635f9cf599SWang Nan if (auxtrace_record__snapshot_finish(rec->itr)) 2645f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 2655f9cf599SWang Nan else 2665f9cf599SWang Nan trigger_ready(&auxtrace_snapshot_trigger); 2672dd6d8a1SAdrian Hunter } 2682dd6d8a1SAdrian Hunter } 2692dd6d8a1SAdrian Hunter 270e31f0d01SAdrian Hunter #else 271e31f0d01SAdrian Hunter 272e31f0d01SAdrian Hunter static inline 273e31f0d01SAdrian Hunter int record__auxtrace_mmap_read(struct record *rec __maybe_unused, 274e31f0d01SAdrian Hunter struct auxtrace_mmap *mm __maybe_unused) 275e31f0d01SAdrian Hunter { 276e31f0d01SAdrian Hunter return 0; 277e31f0d01SAdrian Hunter } 278e31f0d01SAdrian Hunter 2792dd6d8a1SAdrian Hunter static inline 2802dd6d8a1SAdrian Hunter void record__read_auxtrace_snapshot(struct record *rec __maybe_unused) 2812dd6d8a1SAdrian Hunter { 2822dd6d8a1SAdrian Hunter } 2832dd6d8a1SAdrian Hunter 2842dd6d8a1SAdrian Hunter static inline 2852dd6d8a1SAdrian Hunter int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused) 2862dd6d8a1SAdrian Hunter { 2872dd6d8a1SAdrian Hunter return 0; 2882dd6d8a1SAdrian Hunter } 2892dd6d8a1SAdrian Hunter 290e31f0d01SAdrian Hunter #endif 291e31f0d01SAdrian Hunter 2928c6f45a7SArnaldo Carvalho de Melo static int record__open(struct record *rec) 293dd7927f4SArnaldo Carvalho de Melo { 29456e52e85SArnaldo Carvalho de Melo char msg[512]; 2956a4bb04cSJiri Olsa struct perf_evsel *pos; 296d20deb64SArnaldo Carvalho de Melo struct perf_evlist *evlist = rec->evlist; 297d20deb64SArnaldo Carvalho de Melo struct perf_session *session = rec->session; 298b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &rec->opts; 2998d3eca20SDavid Ahern int rc = 0; 300dd7927f4SArnaldo Carvalho de Melo 301e68ae9cfSArnaldo Carvalho de Melo perf_evlist__config(evlist, opts, &callchain_param); 302cac21425SJiri Olsa 3030050f7aaSArnaldo Carvalho de Melo evlist__for_each(evlist, pos) { 3043da297a6SIngo Molnar try_again: 305d988d5eeSKan Liang if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { 30656e52e85SArnaldo Carvalho de Melo if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { 3073da297a6SIngo Molnar if (verbose) 308c0a54341SArnaldo Carvalho de Melo ui__warning("%s\n", msg); 3093da297a6SIngo Molnar goto try_again; 3103da297a6SIngo Molnar } 311ca6a4258SDavid Ahern 31256e52e85SArnaldo Carvalho de Melo rc = -errno; 31356e52e85SArnaldo Carvalho de Melo perf_evsel__open_strerror(pos, &opts->target, 31456e52e85SArnaldo Carvalho de Melo errno, msg, sizeof(msg)); 31556e52e85SArnaldo Carvalho de Melo ui__error("%s\n", msg); 3168d3eca20SDavid Ahern goto out; 3177c6a1c65SPeter Zijlstra } 3187c6a1c65SPeter Zijlstra } 3197c6a1c65SPeter Zijlstra 32023d4aad4SArnaldo Carvalho de Melo if (perf_evlist__apply_filters(evlist, &pos)) { 32123d4aad4SArnaldo Carvalho de Melo error("failed to set filter \"%s\" on event %s with %d (%s)\n", 32223d4aad4SArnaldo Carvalho de Melo pos->filter, perf_evsel__name(pos), errno, 32335550da3SMasami Hiramatsu strerror_r(errno, msg, sizeof(msg))); 3248d3eca20SDavid Ahern rc = -1; 3258d3eca20SDavid Ahern goto out; 3260a102479SFrederic Weisbecker } 3270a102479SFrederic Weisbecker 328ef149c25SAdrian Hunter if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, 3292dd6d8a1SAdrian Hunter opts->auxtrace_mmap_pages, 3302dd6d8a1SAdrian Hunter opts->auxtrace_snapshot_mode) < 0) { 3318d3eca20SDavid Ahern if (errno == EPERM) { 3328d3eca20SDavid Ahern pr_err("Permission error mapping pages.\n" 33318e60939SNelson Elhage "Consider increasing " 33418e60939SNelson Elhage "/proc/sys/kernel/perf_event_mlock_kb,\n" 33518e60939SNelson Elhage "or try again with a smaller value of -m/--mmap_pages.\n" 336ef149c25SAdrian Hunter "(current value: %u,%u)\n", 337ef149c25SAdrian Hunter opts->mmap_pages, opts->auxtrace_mmap_pages); 3388d3eca20SDavid Ahern rc = -errno; 3398d3eca20SDavid Ahern } else { 34035550da3SMasami Hiramatsu pr_err("failed to mmap with %d (%s)\n", errno, 34135550da3SMasami Hiramatsu strerror_r(errno, msg, sizeof(msg))); 34295c36561SWang Nan if (errno) 3438d3eca20SDavid Ahern rc = -errno; 34495c36561SWang Nan else 34595c36561SWang Nan rc = -EINVAL; 3468d3eca20SDavid Ahern } 3478d3eca20SDavid Ahern goto out; 34818e60939SNelson Elhage } 3490a27d7f9SArnaldo Carvalho de Melo 350a91e5431SArnaldo Carvalho de Melo session->evlist = evlist; 3517b56cce2SArnaldo Carvalho de Melo perf_session__set_id_hdr_size(session); 3528d3eca20SDavid Ahern out: 3538d3eca20SDavid Ahern return rc; 354a91e5431SArnaldo Carvalho de Melo } 355a91e5431SArnaldo Carvalho de Melo 356e3d59112SNamhyung Kim static int process_sample_event(struct perf_tool *tool, 357e3d59112SNamhyung Kim union perf_event *event, 358e3d59112SNamhyung Kim struct perf_sample *sample, 359e3d59112SNamhyung Kim struct perf_evsel *evsel, 360e3d59112SNamhyung Kim struct machine *machine) 361e3d59112SNamhyung Kim { 362e3d59112SNamhyung Kim struct record *rec = container_of(tool, struct record, tool); 363e3d59112SNamhyung Kim 364e3d59112SNamhyung Kim rec->samples++; 365e3d59112SNamhyung Kim 366e3d59112SNamhyung Kim return build_id__mark_dso_hit(tool, event, sample, evsel, machine); 367e3d59112SNamhyung Kim } 368e3d59112SNamhyung Kim 3698c6f45a7SArnaldo Carvalho de Melo static int process_buildids(struct record *rec) 3706122e4e4SArnaldo Carvalho de Melo { 371f5fc1412SJiri Olsa struct perf_data_file *file = &rec->file; 372f5fc1412SJiri Olsa struct perf_session *session = rec->session; 3736122e4e4SArnaldo Carvalho de Melo 374457ae94aSHe Kuang if (file->size == 0) 3759f591fd7SArnaldo Carvalho de Melo return 0; 3769f591fd7SArnaldo Carvalho de Melo 37700dc8657SNamhyung Kim /* 37800dc8657SNamhyung Kim * During this process, it'll load kernel map and replace the 37900dc8657SNamhyung Kim * dso->long_name to a real pathname it found. In this case 38000dc8657SNamhyung Kim * we prefer the vmlinux path like 38100dc8657SNamhyung Kim * /lib/modules/3.16.4/build/vmlinux 38200dc8657SNamhyung Kim * 38300dc8657SNamhyung Kim * rather than build-id path (in debug directory). 38400dc8657SNamhyung Kim * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551 38500dc8657SNamhyung Kim */ 38600dc8657SNamhyung Kim symbol_conf.ignore_vmlinux_buildid = true; 38700dc8657SNamhyung Kim 3886156681bSNamhyung Kim /* 3896156681bSNamhyung Kim * If --buildid-all is given, it marks all DSO regardless of hits, 3906156681bSNamhyung Kim * so no need to process samples. 3916156681bSNamhyung Kim */ 3926156681bSNamhyung Kim if (rec->buildid_all) 3936156681bSNamhyung Kim rec->tool.sample = NULL; 3946156681bSNamhyung Kim 395b7b61cbeSArnaldo Carvalho de Melo return perf_session__process_events(session); 3966122e4e4SArnaldo Carvalho de Melo } 3976122e4e4SArnaldo Carvalho de Melo 3988115d60cSArnaldo Carvalho de Melo static void perf_event__synthesize_guest_os(struct machine *machine, void *data) 399a1645ce1SZhang, Yanmin { 400a1645ce1SZhang, Yanmin int err; 40145694aa7SArnaldo Carvalho de Melo struct perf_tool *tool = data; 402a1645ce1SZhang, Yanmin /* 403a1645ce1SZhang, Yanmin *As for guest kernel when processing subcommand record&report, 404a1645ce1SZhang, Yanmin *we arrange module mmap prior to guest kernel mmap and trigger 405a1645ce1SZhang, Yanmin *a preload dso because default guest module symbols are loaded 406a1645ce1SZhang, Yanmin *from guest kallsyms instead of /lib/modules/XXX/XXX. This 407a1645ce1SZhang, Yanmin *method is used to avoid symbol missing when the first addr is 408a1645ce1SZhang, Yanmin *in module instead of in guest kernel. 409a1645ce1SZhang, Yanmin */ 41045694aa7SArnaldo Carvalho de Melo err = perf_event__synthesize_modules(tool, process_synthesized_event, 411743eb868SArnaldo Carvalho de Melo machine); 412a1645ce1SZhang, Yanmin if (err < 0) 413a1645ce1SZhang, Yanmin pr_err("Couldn't record guest kernel [%d]'s reference" 41423346f21SArnaldo Carvalho de Melo " relocation symbol.\n", machine->pid); 415a1645ce1SZhang, Yanmin 416a1645ce1SZhang, Yanmin /* 417a1645ce1SZhang, Yanmin * We use _stext for guest kernel because guest kernel's /proc/kallsyms 418a1645ce1SZhang, Yanmin * have no _text sometimes. 419a1645ce1SZhang, Yanmin */ 42045694aa7SArnaldo Carvalho de Melo err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, 4210ae617beSAdrian Hunter machine); 422a1645ce1SZhang, Yanmin if (err < 0) 423a1645ce1SZhang, Yanmin pr_err("Couldn't record guest kernel [%d]'s reference" 42423346f21SArnaldo Carvalho de Melo " relocation symbol.\n", machine->pid); 425a1645ce1SZhang, Yanmin } 426a1645ce1SZhang, Yanmin 42798402807SFrederic Weisbecker static struct perf_event_header finished_round_event = { 42898402807SFrederic Weisbecker .size = sizeof(struct perf_event_header), 42998402807SFrederic Weisbecker .type = PERF_RECORD_FINISHED_ROUND, 43098402807SFrederic Weisbecker }; 43198402807SFrederic Weisbecker 4328c6f45a7SArnaldo Carvalho de Melo static int record__mmap_read_all(struct record *rec) 43398402807SFrederic Weisbecker { 434dcabb507SJiri Olsa u64 bytes_written = rec->bytes_written; 4350e2e63ddSPeter Zijlstra int i; 4368d3eca20SDavid Ahern int rc = 0; 43798402807SFrederic Weisbecker 438d20deb64SArnaldo Carvalho de Melo for (i = 0; i < rec->evlist->nr_mmaps; i++) { 439ef149c25SAdrian Hunter struct auxtrace_mmap *mm = &rec->evlist->mmap[i].auxtrace_mmap; 440ef149c25SAdrian Hunter 4418d3eca20SDavid Ahern if (rec->evlist->mmap[i].base) { 442e5685730SArnaldo Carvalho de Melo if (record__mmap_read(rec, i) != 0) { 4438d3eca20SDavid Ahern rc = -1; 4448d3eca20SDavid Ahern goto out; 4458d3eca20SDavid Ahern } 4468d3eca20SDavid Ahern } 447ef149c25SAdrian Hunter 4482dd6d8a1SAdrian Hunter if (mm->base && !rec->opts.auxtrace_snapshot_mode && 449ef149c25SAdrian Hunter record__auxtrace_mmap_read(rec, mm) != 0) { 450ef149c25SAdrian Hunter rc = -1; 451ef149c25SAdrian Hunter goto out; 452ef149c25SAdrian Hunter } 45398402807SFrederic Weisbecker } 45498402807SFrederic Weisbecker 455dcabb507SJiri Olsa /* 456dcabb507SJiri Olsa * Mark the round finished in case we wrote 457dcabb507SJiri Olsa * at least one event. 458dcabb507SJiri Olsa */ 459dcabb507SJiri Olsa if (bytes_written != rec->bytes_written) 4608c6f45a7SArnaldo Carvalho de Melo rc = record__write(rec, &finished_round_event, sizeof(finished_round_event)); 4618d3eca20SDavid Ahern 4628d3eca20SDavid Ahern out: 4638d3eca20SDavid Ahern return rc; 46498402807SFrederic Weisbecker } 46598402807SFrederic Weisbecker 4668c6f45a7SArnaldo Carvalho de Melo static void record__init_features(struct record *rec) 46757706abcSDavid Ahern { 46857706abcSDavid Ahern struct perf_session *session = rec->session; 46957706abcSDavid Ahern int feat; 47057706abcSDavid Ahern 47157706abcSDavid Ahern for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++) 47257706abcSDavid Ahern perf_header__set_feat(&session->header, feat); 47357706abcSDavid Ahern 47457706abcSDavid Ahern if (rec->no_buildid) 47557706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_BUILD_ID); 47657706abcSDavid Ahern 4773e2be2daSArnaldo Carvalho de Melo if (!have_tracepoints(&rec->evlist->entries)) 47857706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); 47957706abcSDavid Ahern 48057706abcSDavid Ahern if (!rec->opts.branch_stack) 48157706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 482ef149c25SAdrian Hunter 483ef149c25SAdrian Hunter if (!rec->opts.full_auxtrace) 484ef149c25SAdrian Hunter perf_header__clear_feat(&session->header, HEADER_AUXTRACE); 485ffa517adSJiri Olsa 486ffa517adSJiri Olsa perf_header__clear_feat(&session->header, HEADER_STAT); 48757706abcSDavid Ahern } 48857706abcSDavid Ahern 489e1ab48baSWang Nan static void 490e1ab48baSWang Nan record__finish_output(struct record *rec) 491e1ab48baSWang Nan { 492e1ab48baSWang Nan struct perf_data_file *file = &rec->file; 493e1ab48baSWang Nan int fd = perf_data_file__fd(file); 494e1ab48baSWang Nan 495e1ab48baSWang Nan if (file->is_pipe) 496e1ab48baSWang Nan return; 497e1ab48baSWang Nan 498e1ab48baSWang Nan rec->session->header.data_size += rec->bytes_written; 499e1ab48baSWang Nan file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR); 500e1ab48baSWang Nan 501e1ab48baSWang Nan if (!rec->no_buildid) { 502e1ab48baSWang Nan process_buildids(rec); 503e1ab48baSWang Nan 504e1ab48baSWang Nan if (rec->buildid_all) 505e1ab48baSWang Nan dsos__hit_all(rec->session); 506e1ab48baSWang Nan } 507e1ab48baSWang Nan perf_session__write_header(rec->session, rec->evlist, fd, true); 508e1ab48baSWang Nan 509e1ab48baSWang Nan return; 510e1ab48baSWang Nan } 511e1ab48baSWang Nan 512be7b0c9eSWang Nan static int record__synthesize_workload(struct record *rec) 513be7b0c9eSWang Nan { 514be7b0c9eSWang Nan struct { 515be7b0c9eSWang Nan struct thread_map map; 516be7b0c9eSWang Nan struct thread_map_data map_data; 517be7b0c9eSWang Nan } thread_map; 518be7b0c9eSWang Nan 519be7b0c9eSWang Nan thread_map.map.nr = 1; 520be7b0c9eSWang Nan thread_map.map.map[0].pid = rec->evlist->workload.pid; 521be7b0c9eSWang Nan thread_map.map.map[0].comm = NULL; 522be7b0c9eSWang Nan return perf_event__synthesize_thread_map(&rec->tool, &thread_map.map, 523be7b0c9eSWang Nan process_synthesized_event, 524be7b0c9eSWang Nan &rec->session->machines.host, 525be7b0c9eSWang Nan rec->opts.sample_address, 526be7b0c9eSWang Nan rec->opts.proc_map_timeout); 527be7b0c9eSWang Nan } 528be7b0c9eSWang Nan 5293c1cb7e3SWang Nan static int record__synthesize(struct record *rec); 5303c1cb7e3SWang Nan 531ecfd7a9cSWang Nan static int 532ecfd7a9cSWang Nan record__switch_output(struct record *rec, bool at_exit) 533ecfd7a9cSWang Nan { 534ecfd7a9cSWang Nan struct perf_data_file *file = &rec->file; 535ecfd7a9cSWang Nan int fd, err; 536ecfd7a9cSWang Nan 537ecfd7a9cSWang Nan /* Same Size: "2015122520103046"*/ 538ecfd7a9cSWang Nan char timestamp[] = "InvalidTimestamp"; 539ecfd7a9cSWang Nan 540ecfd7a9cSWang Nan rec->samples = 0; 541ecfd7a9cSWang Nan record__finish_output(rec); 542ecfd7a9cSWang Nan err = fetch_current_timestamp(timestamp, sizeof(timestamp)); 543ecfd7a9cSWang Nan if (err) { 544ecfd7a9cSWang Nan pr_err("Failed to get current timestamp\n"); 545ecfd7a9cSWang Nan return -EINVAL; 546ecfd7a9cSWang Nan } 547ecfd7a9cSWang Nan 548ecfd7a9cSWang Nan fd = perf_data_file__switch(file, timestamp, 549ecfd7a9cSWang Nan rec->session->header.data_offset, 550ecfd7a9cSWang Nan at_exit); 551ecfd7a9cSWang Nan if (fd >= 0 && !at_exit) { 552ecfd7a9cSWang Nan rec->bytes_written = 0; 553ecfd7a9cSWang Nan rec->session->header.data_size = 0; 554ecfd7a9cSWang Nan } 555ecfd7a9cSWang Nan 556ecfd7a9cSWang Nan if (!quiet) 557ecfd7a9cSWang Nan fprintf(stderr, "[ perf record: Dump %s.%s ]\n", 558ecfd7a9cSWang Nan file->path, timestamp); 5593c1cb7e3SWang Nan 5603c1cb7e3SWang Nan /* Output tracking events */ 561be7b0c9eSWang Nan if (!at_exit) { 5623c1cb7e3SWang Nan record__synthesize(rec); 5633c1cb7e3SWang Nan 564be7b0c9eSWang Nan /* 565be7b0c9eSWang Nan * In 'perf record --switch-output' without -a, 566be7b0c9eSWang Nan * record__synthesize() in record__switch_output() won't 567be7b0c9eSWang Nan * generate tracking events because there's no thread_map 568be7b0c9eSWang Nan * in evlist. Which causes newly created perf.data doesn't 569be7b0c9eSWang Nan * contain map and comm information. 570be7b0c9eSWang Nan * Create a fake thread_map and directly call 571be7b0c9eSWang Nan * perf_event__synthesize_thread_map() for those events. 572be7b0c9eSWang Nan */ 573be7b0c9eSWang Nan if (target__none(&rec->opts.target)) 574be7b0c9eSWang Nan record__synthesize_workload(rec); 575be7b0c9eSWang Nan } 576ecfd7a9cSWang Nan return fd; 577ecfd7a9cSWang Nan } 578ecfd7a9cSWang Nan 579f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno; 580f33cbe72SArnaldo Carvalho de Melo 581f33cbe72SArnaldo Carvalho de Melo /* 582f33cbe72SArnaldo Carvalho de Melo * perf_evlist__prepare_workload will send a SIGUSR1 583f33cbe72SArnaldo Carvalho de Melo * if the fork fails, since we asked by setting its 584f33cbe72SArnaldo Carvalho de Melo * want_signal to true. 585f33cbe72SArnaldo Carvalho de Melo */ 58645604710SNamhyung Kim static void workload_exec_failed_signal(int signo __maybe_unused, 58745604710SNamhyung Kim siginfo_t *info, 588f33cbe72SArnaldo Carvalho de Melo void *ucontext __maybe_unused) 589f33cbe72SArnaldo Carvalho de Melo { 590f33cbe72SArnaldo Carvalho de Melo workload_exec_errno = info->si_value.sival_int; 591f33cbe72SArnaldo Carvalho de Melo done = 1; 592f33cbe72SArnaldo Carvalho de Melo child_finished = 1; 593f33cbe72SArnaldo Carvalho de Melo } 594f33cbe72SArnaldo Carvalho de Melo 5952dd6d8a1SAdrian Hunter static void snapshot_sig_handler(int sig); 5962dd6d8a1SAdrian Hunter 59746bc29b9SAdrian Hunter int __weak 59846bc29b9SAdrian Hunter perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused, 59946bc29b9SAdrian Hunter struct perf_tool *tool __maybe_unused, 60046bc29b9SAdrian Hunter perf_event__handler_t process __maybe_unused, 60146bc29b9SAdrian Hunter struct machine *machine __maybe_unused) 60246bc29b9SAdrian Hunter { 60346bc29b9SAdrian Hunter return 0; 60446bc29b9SAdrian Hunter } 60546bc29b9SAdrian Hunter 606c45c86ebSWang Nan static int record__synthesize(struct record *rec) 607c45c86ebSWang Nan { 608c45c86ebSWang Nan struct perf_session *session = rec->session; 609c45c86ebSWang Nan struct machine *machine = &session->machines.host; 610c45c86ebSWang Nan struct perf_data_file *file = &rec->file; 611c45c86ebSWang Nan struct record_opts *opts = &rec->opts; 612c45c86ebSWang Nan struct perf_tool *tool = &rec->tool; 613c45c86ebSWang Nan int fd = perf_data_file__fd(file); 614c45c86ebSWang Nan int err = 0; 615c45c86ebSWang Nan 616c45c86ebSWang Nan if (file->is_pipe) { 617c45c86ebSWang Nan err = perf_event__synthesize_attrs(tool, session, 618c45c86ebSWang Nan process_synthesized_event); 619c45c86ebSWang Nan if (err < 0) { 620c45c86ebSWang Nan pr_err("Couldn't synthesize attrs.\n"); 621c45c86ebSWang Nan goto out; 622c45c86ebSWang Nan } 623c45c86ebSWang Nan 624c45c86ebSWang Nan if (have_tracepoints(&rec->evlist->entries)) { 625c45c86ebSWang Nan /* 626c45c86ebSWang Nan * FIXME err <= 0 here actually means that 627c45c86ebSWang Nan * there were no tracepoints so its not really 628c45c86ebSWang Nan * an error, just that we don't need to 629c45c86ebSWang Nan * synthesize anything. We really have to 630c45c86ebSWang Nan * return this more properly and also 631c45c86ebSWang Nan * propagate errors that now are calling die() 632c45c86ebSWang Nan */ 633c45c86ebSWang Nan err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist, 634c45c86ebSWang Nan process_synthesized_event); 635c45c86ebSWang Nan if (err <= 0) { 636c45c86ebSWang Nan pr_err("Couldn't record tracing data.\n"); 637c45c86ebSWang Nan goto out; 638c45c86ebSWang Nan } 639c45c86ebSWang Nan rec->bytes_written += err; 640c45c86ebSWang Nan } 641c45c86ebSWang Nan } 642c45c86ebSWang Nan 64346bc29b9SAdrian Hunter err = perf_event__synth_time_conv(rec->evlist->mmap[0].base, tool, 64446bc29b9SAdrian Hunter process_synthesized_event, machine); 64546bc29b9SAdrian Hunter if (err) 64646bc29b9SAdrian Hunter goto out; 64746bc29b9SAdrian Hunter 648c45c86ebSWang Nan if (rec->opts.full_auxtrace) { 649c45c86ebSWang Nan err = perf_event__synthesize_auxtrace_info(rec->itr, tool, 650c45c86ebSWang Nan session, process_synthesized_event); 651c45c86ebSWang Nan if (err) 652c45c86ebSWang Nan goto out; 653c45c86ebSWang Nan } 654c45c86ebSWang Nan 655c45c86ebSWang Nan err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, 656c45c86ebSWang Nan machine); 657c45c86ebSWang Nan WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n" 658c45c86ebSWang Nan "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 659c45c86ebSWang Nan "Check /proc/kallsyms permission or run as root.\n"); 660c45c86ebSWang Nan 661c45c86ebSWang Nan err = perf_event__synthesize_modules(tool, process_synthesized_event, 662c45c86ebSWang Nan machine); 663c45c86ebSWang Nan WARN_ONCE(err < 0, "Couldn't record kernel module information.\n" 664c45c86ebSWang Nan "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 665c45c86ebSWang Nan "Check /proc/modules permission or run as root.\n"); 666c45c86ebSWang Nan 667c45c86ebSWang Nan if (perf_guest) { 668c45c86ebSWang Nan machines__process_guests(&session->machines, 669c45c86ebSWang Nan perf_event__synthesize_guest_os, tool); 670c45c86ebSWang Nan } 671c45c86ebSWang Nan 672c45c86ebSWang Nan err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads, 673c45c86ebSWang Nan process_synthesized_event, opts->sample_address, 674c45c86ebSWang Nan opts->proc_map_timeout); 675c45c86ebSWang Nan out: 676c45c86ebSWang Nan return err; 677c45c86ebSWang Nan } 678c45c86ebSWang Nan 6798c6f45a7SArnaldo Carvalho de Melo static int __cmd_record(struct record *rec, int argc, const char **argv) 68086470930SIngo Molnar { 68157706abcSDavid Ahern int err; 68245604710SNamhyung Kim int status = 0; 6838b412664SPeter Zijlstra unsigned long waking = 0; 68446be604bSZhang, Yanmin const bool forks = argc > 0; 68523346f21SArnaldo Carvalho de Melo struct machine *machine; 68645694aa7SArnaldo Carvalho de Melo struct perf_tool *tool = &rec->tool; 687b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &rec->opts; 688f5fc1412SJiri Olsa struct perf_data_file *file = &rec->file; 689d20deb64SArnaldo Carvalho de Melo struct perf_session *session; 6906dcf45efSArnaldo Carvalho de Melo bool disabled = false, draining = false; 69142aa276fSNamhyung Kim int fd; 69286470930SIngo Molnar 693d20deb64SArnaldo Carvalho de Melo rec->progname = argv[0]; 69433e49ea7SAndi Kleen 69545604710SNamhyung Kim atexit(record__sig_exit); 696f5970550SPeter Zijlstra signal(SIGCHLD, sig_handler); 697f5970550SPeter Zijlstra signal(SIGINT, sig_handler); 698804f7ac7SDavid Ahern signal(SIGTERM, sig_handler); 699c0bdc1c4SWang Nan 7003c1cb7e3SWang Nan if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) { 7012dd6d8a1SAdrian Hunter signal(SIGUSR2, snapshot_sig_handler); 7023c1cb7e3SWang Nan if (rec->opts.auxtrace_snapshot_mode) 7035f9cf599SWang Nan trigger_on(&auxtrace_snapshot_trigger); 7043c1cb7e3SWang Nan if (rec->switch_output) 7053c1cb7e3SWang Nan trigger_on(&switch_output_trigger); 706c0bdc1c4SWang Nan } else { 7072dd6d8a1SAdrian Hunter signal(SIGUSR2, SIG_IGN); 708c0bdc1c4SWang Nan } 709f5970550SPeter Zijlstra 710b7b61cbeSArnaldo Carvalho de Melo session = perf_session__new(file, false, tool); 71194c744b6SArnaldo Carvalho de Melo if (session == NULL) { 712ffa91880SAdrien BAK pr_err("Perf session creation failed.\n"); 713a9a70bbcSArnaldo Carvalho de Melo return -1; 714a9a70bbcSArnaldo Carvalho de Melo } 715a9a70bbcSArnaldo Carvalho de Melo 71642aa276fSNamhyung Kim fd = perf_data_file__fd(file); 717d20deb64SArnaldo Carvalho de Melo rec->session = session; 718d20deb64SArnaldo Carvalho de Melo 7198c6f45a7SArnaldo Carvalho de Melo record__init_features(rec); 720330aa675SStephane Eranian 721d4db3f16SArnaldo Carvalho de Melo if (forks) { 7223e2be2daSArnaldo Carvalho de Melo err = perf_evlist__prepare_workload(rec->evlist, &opts->target, 723f5fc1412SJiri Olsa argv, file->is_pipe, 724735f7e0bSArnaldo Carvalho de Melo workload_exec_failed_signal); 72535b9d88eSArnaldo Carvalho de Melo if (err < 0) { 72635b9d88eSArnaldo Carvalho de Melo pr_err("Couldn't run the workload!\n"); 72745604710SNamhyung Kim status = err; 72835b9d88eSArnaldo Carvalho de Melo goto out_delete_session; 729856e9660SPeter Zijlstra } 730856e9660SPeter Zijlstra } 731856e9660SPeter Zijlstra 7328c6f45a7SArnaldo Carvalho de Melo if (record__open(rec) != 0) { 7338d3eca20SDavid Ahern err = -1; 73445604710SNamhyung Kim goto out_child; 7358d3eca20SDavid Ahern } 73686470930SIngo Molnar 7378690a2a7SWang Nan err = bpf__apply_obj_config(); 7388690a2a7SWang Nan if (err) { 7398690a2a7SWang Nan char errbuf[BUFSIZ]; 7408690a2a7SWang Nan 7418690a2a7SWang Nan bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf)); 7428690a2a7SWang Nan pr_err("ERROR: Apply config to BPF failed: %s\n", 7438690a2a7SWang Nan errbuf); 7448690a2a7SWang Nan goto out_child; 7458690a2a7SWang Nan } 7468690a2a7SWang Nan 747cca8482cSAdrian Hunter /* 748cca8482cSAdrian Hunter * Normally perf_session__new would do this, but it doesn't have the 749cca8482cSAdrian Hunter * evlist. 750cca8482cSAdrian Hunter */ 751cca8482cSAdrian Hunter if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) { 752cca8482cSAdrian Hunter pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n"); 753cca8482cSAdrian Hunter rec->tool.ordered_events = false; 754cca8482cSAdrian Hunter } 755cca8482cSAdrian Hunter 7563e2be2daSArnaldo Carvalho de Melo if (!rec->evlist->nr_groups) 757a8bb559bSNamhyung Kim perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); 758a8bb559bSNamhyung Kim 759f5fc1412SJiri Olsa if (file->is_pipe) { 76042aa276fSNamhyung Kim err = perf_header__write_pipe(fd); 761529870e3STom Zanussi if (err < 0) 76245604710SNamhyung Kim goto out_child; 763563aecb2SJiri Olsa } else { 76442aa276fSNamhyung Kim err = perf_session__write_header(session, rec->evlist, fd, false); 765d5eed904SArnaldo Carvalho de Melo if (err < 0) 76645604710SNamhyung Kim goto out_child; 767d5eed904SArnaldo Carvalho de Melo } 7687c6a1c65SPeter Zijlstra 769d3665498SDavid Ahern if (!rec->no_buildid 770e20960c0SRobert Richter && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) { 771d3665498SDavid Ahern pr_err("Couldn't generate buildids. " 772e20960c0SRobert Richter "Use --no-buildid to profile anyway.\n"); 7738d3eca20SDavid Ahern err = -1; 77445604710SNamhyung Kim goto out_child; 775e20960c0SRobert Richter } 776e20960c0SRobert Richter 77734ba5122SArnaldo Carvalho de Melo machine = &session->machines.host; 778743eb868SArnaldo Carvalho de Melo 779c45c86ebSWang Nan err = record__synthesize(rec); 780c45c86ebSWang Nan if (err < 0) 78145604710SNamhyung Kim goto out_child; 7828d3eca20SDavid Ahern 783d20deb64SArnaldo Carvalho de Melo if (rec->realtime_prio) { 78486470930SIngo Molnar struct sched_param param; 78586470930SIngo Molnar 786d20deb64SArnaldo Carvalho de Melo param.sched_priority = rec->realtime_prio; 78786470930SIngo Molnar if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { 7886beba7adSArnaldo Carvalho de Melo pr_err("Could not set realtime priority.\n"); 7898d3eca20SDavid Ahern err = -1; 79045604710SNamhyung Kim goto out_child; 79186470930SIngo Molnar } 79286470930SIngo Molnar } 79386470930SIngo Molnar 794774cb499SJiri Olsa /* 795774cb499SJiri Olsa * When perf is starting the traced process, all the events 796774cb499SJiri Olsa * (apart from group members) have enable_on_exec=1 set, 797774cb499SJiri Olsa * so don't spoil it by prematurely enabling them. 798774cb499SJiri Olsa */ 7996619a53eSAndi Kleen if (!target__none(&opts->target) && !opts->initial_delay) 8003e2be2daSArnaldo Carvalho de Melo perf_evlist__enable(rec->evlist); 801764e16a3SDavid Ahern 802856e9660SPeter Zijlstra /* 803856e9660SPeter Zijlstra * Let the child rip 804856e9660SPeter Zijlstra */ 805e803cf97SNamhyung Kim if (forks) { 806e5bed564SNamhyung Kim union perf_event *event; 807e5bed564SNamhyung Kim 808e5bed564SNamhyung Kim event = malloc(sizeof(event->comm) + machine->id_hdr_size); 809e5bed564SNamhyung Kim if (event == NULL) { 810e5bed564SNamhyung Kim err = -ENOMEM; 811e5bed564SNamhyung Kim goto out_child; 812e5bed564SNamhyung Kim } 813e5bed564SNamhyung Kim 814e803cf97SNamhyung Kim /* 815e803cf97SNamhyung Kim * Some H/W events are generated before COMM event 816e803cf97SNamhyung Kim * which is emitted during exec(), so perf script 817e803cf97SNamhyung Kim * cannot see a correct process name for those events. 818e803cf97SNamhyung Kim * Synthesize COMM event to prevent it. 819e803cf97SNamhyung Kim */ 820e5bed564SNamhyung Kim perf_event__synthesize_comm(tool, event, 821e803cf97SNamhyung Kim rec->evlist->workload.pid, 822e803cf97SNamhyung Kim process_synthesized_event, 823e803cf97SNamhyung Kim machine); 824e5bed564SNamhyung Kim free(event); 825e803cf97SNamhyung Kim 8263e2be2daSArnaldo Carvalho de Melo perf_evlist__start_workload(rec->evlist); 827e803cf97SNamhyung Kim } 828856e9660SPeter Zijlstra 8296619a53eSAndi Kleen if (opts->initial_delay) { 8306619a53eSAndi Kleen usleep(opts->initial_delay * 1000); 8316619a53eSAndi Kleen perf_evlist__enable(rec->evlist); 8326619a53eSAndi Kleen } 8336619a53eSAndi Kleen 8345f9cf599SWang Nan trigger_ready(&auxtrace_snapshot_trigger); 8353c1cb7e3SWang Nan trigger_ready(&switch_output_trigger); 836649c48a9SPeter Zijlstra for (;;) { 8379f065194SYang Shi unsigned long long hits = rec->samples; 83886470930SIngo Molnar 8398c6f45a7SArnaldo Carvalho de Melo if (record__mmap_read_all(rec) < 0) { 8405f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 8413c1cb7e3SWang Nan trigger_error(&switch_output_trigger); 8428d3eca20SDavid Ahern err = -1; 84345604710SNamhyung Kim goto out_child; 8448d3eca20SDavid Ahern } 84586470930SIngo Molnar 8462dd6d8a1SAdrian Hunter if (auxtrace_record__snapshot_started) { 8472dd6d8a1SAdrian Hunter auxtrace_record__snapshot_started = 0; 8485f9cf599SWang Nan if (!trigger_is_error(&auxtrace_snapshot_trigger)) 8492dd6d8a1SAdrian Hunter record__read_auxtrace_snapshot(rec); 8505f9cf599SWang Nan if (trigger_is_error(&auxtrace_snapshot_trigger)) { 8512dd6d8a1SAdrian Hunter pr_err("AUX area tracing snapshot failed\n"); 8522dd6d8a1SAdrian Hunter err = -1; 8532dd6d8a1SAdrian Hunter goto out_child; 8542dd6d8a1SAdrian Hunter } 8552dd6d8a1SAdrian Hunter } 8562dd6d8a1SAdrian Hunter 8573c1cb7e3SWang Nan if (trigger_is_hit(&switch_output_trigger)) { 8583c1cb7e3SWang Nan trigger_ready(&switch_output_trigger); 8593c1cb7e3SWang Nan 8603c1cb7e3SWang Nan if (!quiet) 8613c1cb7e3SWang Nan fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n", 8623c1cb7e3SWang Nan waking); 8633c1cb7e3SWang Nan waking = 0; 8643c1cb7e3SWang Nan fd = record__switch_output(rec, false); 8653c1cb7e3SWang Nan if (fd < 0) { 8663c1cb7e3SWang Nan pr_err("Failed to switch to new file\n"); 8673c1cb7e3SWang Nan trigger_error(&switch_output_trigger); 8683c1cb7e3SWang Nan err = fd; 8693c1cb7e3SWang Nan goto out_child; 8703c1cb7e3SWang Nan } 8713c1cb7e3SWang Nan } 8723c1cb7e3SWang Nan 873d20deb64SArnaldo Carvalho de Melo if (hits == rec->samples) { 8746dcf45efSArnaldo Carvalho de Melo if (done || draining) 875649c48a9SPeter Zijlstra break; 876f66a889dSArnaldo Carvalho de Melo err = perf_evlist__poll(rec->evlist, -1); 877a515114fSJiri Olsa /* 878a515114fSJiri Olsa * Propagate error, only if there's any. Ignore positive 879a515114fSJiri Olsa * number of returned events and interrupt error. 880a515114fSJiri Olsa */ 881a515114fSJiri Olsa if (err > 0 || (err < 0 && errno == EINTR)) 88245604710SNamhyung Kim err = 0; 8838b412664SPeter Zijlstra waking++; 8846dcf45efSArnaldo Carvalho de Melo 8856dcf45efSArnaldo Carvalho de Melo if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0) 8866dcf45efSArnaldo Carvalho de Melo draining = true; 8878b412664SPeter Zijlstra } 8888b412664SPeter Zijlstra 889774cb499SJiri Olsa /* 890774cb499SJiri Olsa * When perf is starting the traced process, at the end events 891774cb499SJiri Olsa * die with the process and we wait for that. Thus no need to 892774cb499SJiri Olsa * disable events in this case. 893774cb499SJiri Olsa */ 894602ad878SArnaldo Carvalho de Melo if (done && !disabled && !target__none(&opts->target)) { 8955f9cf599SWang Nan trigger_off(&auxtrace_snapshot_trigger); 8963e2be2daSArnaldo Carvalho de Melo perf_evlist__disable(rec->evlist); 8972711926aSJiri Olsa disabled = true; 8982711926aSJiri Olsa } 8998b412664SPeter Zijlstra } 9005f9cf599SWang Nan trigger_off(&auxtrace_snapshot_trigger); 9013c1cb7e3SWang Nan trigger_off(&switch_output_trigger); 9028b412664SPeter Zijlstra 903f33cbe72SArnaldo Carvalho de Melo if (forks && workload_exec_errno) { 90435550da3SMasami Hiramatsu char msg[STRERR_BUFSIZE]; 905f33cbe72SArnaldo Carvalho de Melo const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg)); 906f33cbe72SArnaldo Carvalho de Melo pr_err("Workload failed: %s\n", emsg); 907f33cbe72SArnaldo Carvalho de Melo err = -1; 90845604710SNamhyung Kim goto out_child; 909f33cbe72SArnaldo Carvalho de Melo } 910f33cbe72SArnaldo Carvalho de Melo 911e3d59112SNamhyung Kim if (!quiet) 9128b412664SPeter Zijlstra fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); 91386470930SIngo Molnar 91445604710SNamhyung Kim out_child: 91545604710SNamhyung Kim if (forks) { 91645604710SNamhyung Kim int exit_status; 91745604710SNamhyung Kim 91845604710SNamhyung Kim if (!child_finished) 91945604710SNamhyung Kim kill(rec->evlist->workload.pid, SIGTERM); 92045604710SNamhyung Kim 92145604710SNamhyung Kim wait(&exit_status); 92245604710SNamhyung Kim 92345604710SNamhyung Kim if (err < 0) 92445604710SNamhyung Kim status = err; 92545604710SNamhyung Kim else if (WIFEXITED(exit_status)) 92645604710SNamhyung Kim status = WEXITSTATUS(exit_status); 92745604710SNamhyung Kim else if (WIFSIGNALED(exit_status)) 92845604710SNamhyung Kim signr = WTERMSIG(exit_status); 92945604710SNamhyung Kim } else 93045604710SNamhyung Kim status = err; 93145604710SNamhyung Kim 932e3d59112SNamhyung Kim /* this will be recalculated during process_buildids() */ 933e3d59112SNamhyung Kim rec->samples = 0; 934e3d59112SNamhyung Kim 935ecfd7a9cSWang Nan if (!err) { 936ecfd7a9cSWang Nan if (!rec->timestamp_filename) { 937e1ab48baSWang Nan record__finish_output(rec); 938ecfd7a9cSWang Nan } else { 939ecfd7a9cSWang Nan fd = record__switch_output(rec, true); 940ecfd7a9cSWang Nan if (fd < 0) { 941ecfd7a9cSWang Nan status = fd; 942ecfd7a9cSWang Nan goto out_delete_session; 943ecfd7a9cSWang Nan } 944ecfd7a9cSWang Nan } 945ecfd7a9cSWang Nan } 94639d17dacSArnaldo Carvalho de Melo 947e3d59112SNamhyung Kim if (!err && !quiet) { 948e3d59112SNamhyung Kim char samples[128]; 949ecfd7a9cSWang Nan const char *postfix = rec->timestamp_filename ? 950ecfd7a9cSWang Nan ".<timestamp>" : ""; 951e3d59112SNamhyung Kim 952ef149c25SAdrian Hunter if (rec->samples && !rec->opts.full_auxtrace) 953e3d59112SNamhyung Kim scnprintf(samples, sizeof(samples), 954e3d59112SNamhyung Kim " (%" PRIu64 " samples)", rec->samples); 955e3d59112SNamhyung Kim else 956e3d59112SNamhyung Kim samples[0] = '\0'; 957e3d59112SNamhyung Kim 958ecfd7a9cSWang Nan fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n", 959e3d59112SNamhyung Kim perf_data_file__size(file) / 1024.0 / 1024.0, 960ecfd7a9cSWang Nan file->path, postfix, samples); 961e3d59112SNamhyung Kim } 962e3d59112SNamhyung Kim 96339d17dacSArnaldo Carvalho de Melo out_delete_session: 96439d17dacSArnaldo Carvalho de Melo perf_session__delete(session); 96545604710SNamhyung Kim return status; 96686470930SIngo Molnar } 96786470930SIngo Molnar 9680883e820SArnaldo Carvalho de Melo static void callchain_debug(struct callchain_param *callchain) 96909b0fd45SJiri Olsa { 970aad2b21cSKan Liang static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" }; 971a601fdffSJiri Olsa 9720883e820SArnaldo Carvalho de Melo pr_debug("callchain: type %s\n", str[callchain->record_mode]); 97326d33022SJiri Olsa 9740883e820SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_DWARF) 97509b0fd45SJiri Olsa pr_debug("callchain: stack dump size %d\n", 9760883e820SArnaldo Carvalho de Melo callchain->dump_size); 9770883e820SArnaldo Carvalho de Melo } 9780883e820SArnaldo Carvalho de Melo 9790883e820SArnaldo Carvalho de Melo int record_opts__parse_callchain(struct record_opts *record, 9800883e820SArnaldo Carvalho de Melo struct callchain_param *callchain, 9810883e820SArnaldo Carvalho de Melo const char *arg, bool unset) 9820883e820SArnaldo Carvalho de Melo { 9830883e820SArnaldo Carvalho de Melo int ret; 9840883e820SArnaldo Carvalho de Melo callchain->enabled = !unset; 9850883e820SArnaldo Carvalho de Melo 9860883e820SArnaldo Carvalho de Melo /* --no-call-graph */ 9870883e820SArnaldo Carvalho de Melo if (unset) { 9880883e820SArnaldo Carvalho de Melo callchain->record_mode = CALLCHAIN_NONE; 9890883e820SArnaldo Carvalho de Melo pr_debug("callchain: disabled\n"); 9900883e820SArnaldo Carvalho de Melo return 0; 9910883e820SArnaldo Carvalho de Melo } 9920883e820SArnaldo Carvalho de Melo 9930883e820SArnaldo Carvalho de Melo ret = parse_callchain_record_opt(arg, callchain); 9940883e820SArnaldo Carvalho de Melo if (!ret) { 9950883e820SArnaldo Carvalho de Melo /* Enable data address sampling for DWARF unwind. */ 9960883e820SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_DWARF) 9970883e820SArnaldo Carvalho de Melo record->sample_address = true; 9980883e820SArnaldo Carvalho de Melo callchain_debug(callchain); 9990883e820SArnaldo Carvalho de Melo } 10000883e820SArnaldo Carvalho de Melo 10010883e820SArnaldo Carvalho de Melo return ret; 100209b0fd45SJiri Olsa } 100309b0fd45SJiri Olsa 1004c421e80bSKan Liang int record_parse_callchain_opt(const struct option *opt, 100509b0fd45SJiri Olsa const char *arg, 100609b0fd45SJiri Olsa int unset) 100709b0fd45SJiri Olsa { 10080883e820SArnaldo Carvalho de Melo return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset); 100926d33022SJiri Olsa } 101026d33022SJiri Olsa 1011c421e80bSKan Liang int record_callchain_opt(const struct option *opt, 101209b0fd45SJiri Olsa const char *arg __maybe_unused, 101309b0fd45SJiri Olsa int unset __maybe_unused) 101409b0fd45SJiri Olsa { 10152ddd5c04SArnaldo Carvalho de Melo struct callchain_param *callchain = opt->value; 1016c421e80bSKan Liang 10172ddd5c04SArnaldo Carvalho de Melo callchain->enabled = true; 101809b0fd45SJiri Olsa 10192ddd5c04SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_NONE) 10202ddd5c04SArnaldo Carvalho de Melo callchain->record_mode = CALLCHAIN_FP; 1021eb853e80SJiri Olsa 10222ddd5c04SArnaldo Carvalho de Melo callchain_debug(callchain); 102309b0fd45SJiri Olsa return 0; 102409b0fd45SJiri Olsa } 102509b0fd45SJiri Olsa 1026eb853e80SJiri Olsa static int perf_record_config(const char *var, const char *value, void *cb) 1027eb853e80SJiri Olsa { 10287a29c087SNamhyung Kim struct record *rec = cb; 10297a29c087SNamhyung Kim 10307a29c087SNamhyung Kim if (!strcmp(var, "record.build-id")) { 10317a29c087SNamhyung Kim if (!strcmp(value, "cache")) 10327a29c087SNamhyung Kim rec->no_buildid_cache = false; 10337a29c087SNamhyung Kim else if (!strcmp(value, "no-cache")) 10347a29c087SNamhyung Kim rec->no_buildid_cache = true; 10357a29c087SNamhyung Kim else if (!strcmp(value, "skip")) 10367a29c087SNamhyung Kim rec->no_buildid = true; 10377a29c087SNamhyung Kim else 10387a29c087SNamhyung Kim return -1; 10397a29c087SNamhyung Kim return 0; 10407a29c087SNamhyung Kim } 1041eb853e80SJiri Olsa if (!strcmp(var, "record.call-graph")) 10425a2e5e85SNamhyung Kim var = "call-graph.record-mode"; /* fall-through */ 1043eb853e80SJiri Olsa 1044eb853e80SJiri Olsa return perf_default_config(var, value, cb); 1045eb853e80SJiri Olsa } 1046eb853e80SJiri Olsa 1047814c8c38SPeter Zijlstra struct clockid_map { 1048814c8c38SPeter Zijlstra const char *name; 1049814c8c38SPeter Zijlstra int clockid; 1050814c8c38SPeter Zijlstra }; 1051814c8c38SPeter Zijlstra 1052814c8c38SPeter Zijlstra #define CLOCKID_MAP(n, c) \ 1053814c8c38SPeter Zijlstra { .name = n, .clockid = (c), } 1054814c8c38SPeter Zijlstra 1055814c8c38SPeter Zijlstra #define CLOCKID_END { .name = NULL, } 1056814c8c38SPeter Zijlstra 1057814c8c38SPeter Zijlstra 1058814c8c38SPeter Zijlstra /* 1059814c8c38SPeter Zijlstra * Add the missing ones, we need to build on many distros... 1060814c8c38SPeter Zijlstra */ 1061814c8c38SPeter Zijlstra #ifndef CLOCK_MONOTONIC_RAW 1062814c8c38SPeter Zijlstra #define CLOCK_MONOTONIC_RAW 4 1063814c8c38SPeter Zijlstra #endif 1064814c8c38SPeter Zijlstra #ifndef CLOCK_BOOTTIME 1065814c8c38SPeter Zijlstra #define CLOCK_BOOTTIME 7 1066814c8c38SPeter Zijlstra #endif 1067814c8c38SPeter Zijlstra #ifndef CLOCK_TAI 1068814c8c38SPeter Zijlstra #define CLOCK_TAI 11 1069814c8c38SPeter Zijlstra #endif 1070814c8c38SPeter Zijlstra 1071814c8c38SPeter Zijlstra static const struct clockid_map clockids[] = { 1072814c8c38SPeter Zijlstra /* available for all events, NMI safe */ 1073814c8c38SPeter Zijlstra CLOCKID_MAP("monotonic", CLOCK_MONOTONIC), 1074814c8c38SPeter Zijlstra CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW), 1075814c8c38SPeter Zijlstra 1076814c8c38SPeter Zijlstra /* available for some events */ 1077814c8c38SPeter Zijlstra CLOCKID_MAP("realtime", CLOCK_REALTIME), 1078814c8c38SPeter Zijlstra CLOCKID_MAP("boottime", CLOCK_BOOTTIME), 1079814c8c38SPeter Zijlstra CLOCKID_MAP("tai", CLOCK_TAI), 1080814c8c38SPeter Zijlstra 1081814c8c38SPeter Zijlstra /* available for the lazy */ 1082814c8c38SPeter Zijlstra CLOCKID_MAP("mono", CLOCK_MONOTONIC), 1083814c8c38SPeter Zijlstra CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW), 1084814c8c38SPeter Zijlstra CLOCKID_MAP("real", CLOCK_REALTIME), 1085814c8c38SPeter Zijlstra CLOCKID_MAP("boot", CLOCK_BOOTTIME), 1086814c8c38SPeter Zijlstra 1087814c8c38SPeter Zijlstra CLOCKID_END, 1088814c8c38SPeter Zijlstra }; 1089814c8c38SPeter Zijlstra 1090814c8c38SPeter Zijlstra static int parse_clockid(const struct option *opt, const char *str, int unset) 1091814c8c38SPeter Zijlstra { 1092814c8c38SPeter Zijlstra struct record_opts *opts = (struct record_opts *)opt->value; 1093814c8c38SPeter Zijlstra const struct clockid_map *cm; 1094814c8c38SPeter Zijlstra const char *ostr = str; 1095814c8c38SPeter Zijlstra 1096814c8c38SPeter Zijlstra if (unset) { 1097814c8c38SPeter Zijlstra opts->use_clockid = 0; 1098814c8c38SPeter Zijlstra return 0; 1099814c8c38SPeter Zijlstra } 1100814c8c38SPeter Zijlstra 1101814c8c38SPeter Zijlstra /* no arg passed */ 1102814c8c38SPeter Zijlstra if (!str) 1103814c8c38SPeter Zijlstra return 0; 1104814c8c38SPeter Zijlstra 1105814c8c38SPeter Zijlstra /* no setting it twice */ 1106814c8c38SPeter Zijlstra if (opts->use_clockid) 1107814c8c38SPeter Zijlstra return -1; 1108814c8c38SPeter Zijlstra 1109814c8c38SPeter Zijlstra opts->use_clockid = true; 1110814c8c38SPeter Zijlstra 1111814c8c38SPeter Zijlstra /* if its a number, we're done */ 1112814c8c38SPeter Zijlstra if (sscanf(str, "%d", &opts->clockid) == 1) 1113814c8c38SPeter Zijlstra return 0; 1114814c8c38SPeter Zijlstra 1115814c8c38SPeter Zijlstra /* allow a "CLOCK_" prefix to the name */ 1116814c8c38SPeter Zijlstra if (!strncasecmp(str, "CLOCK_", 6)) 1117814c8c38SPeter Zijlstra str += 6; 1118814c8c38SPeter Zijlstra 1119814c8c38SPeter Zijlstra for (cm = clockids; cm->name; cm++) { 1120814c8c38SPeter Zijlstra if (!strcasecmp(str, cm->name)) { 1121814c8c38SPeter Zijlstra opts->clockid = cm->clockid; 1122814c8c38SPeter Zijlstra return 0; 1123814c8c38SPeter Zijlstra } 1124814c8c38SPeter Zijlstra } 1125814c8c38SPeter Zijlstra 1126814c8c38SPeter Zijlstra opts->use_clockid = false; 1127814c8c38SPeter Zijlstra ui__warning("unknown clockid %s, check man page\n", ostr); 1128814c8c38SPeter Zijlstra return -1; 1129814c8c38SPeter Zijlstra } 1130814c8c38SPeter Zijlstra 1131e9db1310SAdrian Hunter static int record__parse_mmap_pages(const struct option *opt, 1132e9db1310SAdrian Hunter const char *str, 1133e9db1310SAdrian Hunter int unset __maybe_unused) 1134e9db1310SAdrian Hunter { 1135e9db1310SAdrian Hunter struct record_opts *opts = opt->value; 1136e9db1310SAdrian Hunter char *s, *p; 1137e9db1310SAdrian Hunter unsigned int mmap_pages; 1138e9db1310SAdrian Hunter int ret; 1139e9db1310SAdrian Hunter 1140e9db1310SAdrian Hunter if (!str) 1141e9db1310SAdrian Hunter return -EINVAL; 1142e9db1310SAdrian Hunter 1143e9db1310SAdrian Hunter s = strdup(str); 1144e9db1310SAdrian Hunter if (!s) 1145e9db1310SAdrian Hunter return -ENOMEM; 1146e9db1310SAdrian Hunter 1147e9db1310SAdrian Hunter p = strchr(s, ','); 1148e9db1310SAdrian Hunter if (p) 1149e9db1310SAdrian Hunter *p = '\0'; 1150e9db1310SAdrian Hunter 1151e9db1310SAdrian Hunter if (*s) { 1152e9db1310SAdrian Hunter ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s); 1153e9db1310SAdrian Hunter if (ret) 1154e9db1310SAdrian Hunter goto out_free; 1155e9db1310SAdrian Hunter opts->mmap_pages = mmap_pages; 1156e9db1310SAdrian Hunter } 1157e9db1310SAdrian Hunter 1158e9db1310SAdrian Hunter if (!p) { 1159e9db1310SAdrian Hunter ret = 0; 1160e9db1310SAdrian Hunter goto out_free; 1161e9db1310SAdrian Hunter } 1162e9db1310SAdrian Hunter 1163e9db1310SAdrian Hunter ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1); 1164e9db1310SAdrian Hunter if (ret) 1165e9db1310SAdrian Hunter goto out_free; 1166e9db1310SAdrian Hunter 1167e9db1310SAdrian Hunter opts->auxtrace_mmap_pages = mmap_pages; 1168e9db1310SAdrian Hunter 1169e9db1310SAdrian Hunter out_free: 1170e9db1310SAdrian Hunter free(s); 1171e9db1310SAdrian Hunter return ret; 1172e9db1310SAdrian Hunter } 1173e9db1310SAdrian Hunter 1174e5b2c207SNamhyung Kim static const char * const __record_usage[] = { 117586470930SIngo Molnar "perf record [<options>] [<command>]", 117686470930SIngo Molnar "perf record [<options>] -- <command> [<options>]", 117786470930SIngo Molnar NULL 117886470930SIngo Molnar }; 1179e5b2c207SNamhyung Kim const char * const *record_usage = __record_usage; 118086470930SIngo Molnar 1181d20deb64SArnaldo Carvalho de Melo /* 11828c6f45a7SArnaldo Carvalho de Melo * XXX Ideally would be local to cmd_record() and passed to a record__new 11838c6f45a7SArnaldo Carvalho de Melo * because we need to have access to it in record__exit, that is called 1184d20deb64SArnaldo Carvalho de Melo * after cmd_record() exits, but since record_options need to be accessible to 1185d20deb64SArnaldo Carvalho de Melo * builtin-script, leave it here. 1186d20deb64SArnaldo Carvalho de Melo * 1187d20deb64SArnaldo Carvalho de Melo * At least we don't ouch it in all the other functions here directly. 1188d20deb64SArnaldo Carvalho de Melo * 1189d20deb64SArnaldo Carvalho de Melo * Just say no to tons of global variables, sigh. 1190d20deb64SArnaldo Carvalho de Melo */ 11918c6f45a7SArnaldo Carvalho de Melo static struct record record = { 1192d20deb64SArnaldo Carvalho de Melo .opts = { 11938affc2b8SAndi Kleen .sample_time = true, 1194d20deb64SArnaldo Carvalho de Melo .mmap_pages = UINT_MAX, 1195d20deb64SArnaldo Carvalho de Melo .user_freq = UINT_MAX, 1196d20deb64SArnaldo Carvalho de Melo .user_interval = ULLONG_MAX, 1197447a6013SArnaldo Carvalho de Melo .freq = 4000, 1198d1cb9fceSNamhyung Kim .target = { 1199d1cb9fceSNamhyung Kim .uses_mmap = true, 12003aa5939dSAdrian Hunter .default_per_cpu = true, 1201d1cb9fceSNamhyung Kim }, 12029d9cad76SKan Liang .proc_map_timeout = 500, 1203d20deb64SArnaldo Carvalho de Melo }, 1204e3d59112SNamhyung Kim .tool = { 1205e3d59112SNamhyung Kim .sample = process_sample_event, 1206e3d59112SNamhyung Kim .fork = perf_event__process_fork, 1207cca8482cSAdrian Hunter .exit = perf_event__process_exit, 1208e3d59112SNamhyung Kim .comm = perf_event__process_comm, 1209e3d59112SNamhyung Kim .mmap = perf_event__process_mmap, 1210e3d59112SNamhyung Kim .mmap2 = perf_event__process_mmap2, 1211cca8482cSAdrian Hunter .ordered_events = true, 1212e3d59112SNamhyung Kim }, 1213d20deb64SArnaldo Carvalho de Melo }; 12147865e817SFrederic Weisbecker 121576a26549SNamhyung Kim const char record_callchain_help[] = CALLCHAIN_RECORD_HELP 121676a26549SNamhyung Kim "\n\t\t\t\tDefault: fp"; 121761eaa3beSArnaldo Carvalho de Melo 1218d20deb64SArnaldo Carvalho de Melo /* 1219d20deb64SArnaldo Carvalho de Melo * XXX Will stay a global variable till we fix builtin-script.c to stop messing 1220d20deb64SArnaldo Carvalho de Melo * with it and switch to use the library functions in perf_evlist that came 1221b4006796SArnaldo Carvalho de Melo * from builtin-record.c, i.e. use record_opts, 1222d20deb64SArnaldo Carvalho de Melo * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record', 1223d20deb64SArnaldo Carvalho de Melo * using pipes, etc. 1224d20deb64SArnaldo Carvalho de Melo */ 1225e5b2c207SNamhyung Kim struct option __record_options[] = { 1226d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &record.evlist, "event", 122786470930SIngo Molnar "event selector. use 'perf list' to list available events", 1228f120f9d5SJiri Olsa parse_events_option), 1229d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK(0, "filter", &record.evlist, "filter", 1230c171b552SLi Zefan "event filter", parse_filter), 12314ba1faa1SWang Nan OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist, 12324ba1faa1SWang Nan NULL, "don't record events from perf itself", 12334ba1faa1SWang Nan exclude_perf), 1234bea03405SNamhyung Kim OPT_STRING('p', "pid", &record.opts.target.pid, "pid", 1235d6d901c2SZhang, Yanmin "record events on existing process id"), 1236bea03405SNamhyung Kim OPT_STRING('t', "tid", &record.opts.target.tid, "tid", 1237d6d901c2SZhang, Yanmin "record events on existing thread id"), 1238d20deb64SArnaldo Carvalho de Melo OPT_INTEGER('r', "realtime", &record.realtime_prio, 123986470930SIngo Molnar "collect data with this RT SCHED_FIFO priority"), 1240509051eaSArnaldo Carvalho de Melo OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering, 1241acac03faSKirill Smelkov "collect data without buffering"), 1242d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples, 1243daac07b2SFrederic Weisbecker "collect raw sample records from all opened counters"), 1244bea03405SNamhyung Kim OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide, 124586470930SIngo Molnar "system-wide collection from all CPUs"), 1246bea03405SNamhyung Kim OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", 1247c45c6ea2SStephane Eranian "list of cpus to monitor"), 1248d20deb64SArnaldo Carvalho de Melo OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"), 1249f5fc1412SJiri Olsa OPT_STRING('o', "output", &record.file.path, "file", 125086470930SIngo Molnar "output file name"), 125169e7e5b0SAdrian Hunter OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit, 125269e7e5b0SAdrian Hunter &record.opts.no_inherit_set, 12532e6cdf99SStephane Eranian "child tasks do not inherit counters"), 1254d20deb64SArnaldo Carvalho de Melo OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"), 1255e9db1310SAdrian Hunter OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]", 1256e9db1310SAdrian Hunter "number of mmap data pages and AUX area tracing mmap pages", 1257e9db1310SAdrian Hunter record__parse_mmap_pages), 1258d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "group", &record.opts.group, 125943bece79SLin Ming "put the counters into a counter group"), 12602ddd5c04SArnaldo Carvalho de Melo OPT_CALLBACK_NOOPT('g', NULL, &callchain_param, 126109b0fd45SJiri Olsa NULL, "enables call-graph recording" , 126209b0fd45SJiri Olsa &record_callchain_opt), 126309b0fd45SJiri Olsa OPT_CALLBACK(0, "call-graph", &record.opts, 126476a26549SNamhyung Kim "record_mode[,record_size]", record_callchain_help, 126509b0fd45SJiri Olsa &record_parse_callchain_opt), 1266c0555642SIan Munsie OPT_INCR('v', "verbose", &verbose, 12673da297a6SIngo Molnar "be more verbose (show counter open errors, etc)"), 1268b44308f5SArnaldo Carvalho de Melo OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"), 1269d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat, 1270649c48a9SPeter Zijlstra "per thread counts"), 127156100321SPeter Zijlstra OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"), 12723abebc55SAdrian Hunter OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time, 12733abebc55SAdrian Hunter &record.opts.sample_time_set, 12743abebc55SAdrian Hunter "Record the sample timestamps"), 127556100321SPeter Zijlstra OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"), 1276d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples, 1277649c48a9SPeter Zijlstra "don't sample"), 1278d2db9a98SWang Nan OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache, 1279d2db9a98SWang Nan &record.no_buildid_cache_set, 1280a1ac1d3cSStephane Eranian "do not update the buildid cache"), 1281d2db9a98SWang Nan OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid, 1282d2db9a98SWang Nan &record.no_buildid_set, 1283baa2f6ceSArnaldo Carvalho de Melo "do not collect buildids in perf.data"), 1284d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK('G', "cgroup", &record.evlist, "name", 1285023695d9SStephane Eranian "monitor event in cgroup name only", 1286023695d9SStephane Eranian parse_cgroups), 1287a6205a35SArnaldo Carvalho de Melo OPT_UINTEGER('D', "delay", &record.opts.initial_delay, 12886619a53eSAndi Kleen "ms to wait before starting measurement after program start"), 1289bea03405SNamhyung Kim OPT_STRING('u', "uid", &record.opts.target.uid_str, "user", 1290bea03405SNamhyung Kim "user to profile"), 1291a5aabdacSStephane Eranian 1292a5aabdacSStephane Eranian OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack, 1293a5aabdacSStephane Eranian "branch any", "sample any taken branches", 1294a5aabdacSStephane Eranian parse_branch_stack), 1295a5aabdacSStephane Eranian 1296a5aabdacSStephane Eranian OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack, 1297a5aabdacSStephane Eranian "branch filter mask", "branch stack filter modes", 1298bdfebd84SRoberto Agostino Vitillo parse_branch_stack), 129905484298SAndi Kleen OPT_BOOLEAN('W', "weight", &record.opts.sample_weight, 130005484298SAndi Kleen "sample by weight (on special events only)"), 1301475eeab9SAndi Kleen OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction, 1302475eeab9SAndi Kleen "sample transaction flags (special events only)"), 13033aa5939dSAdrian Hunter OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread, 13043aa5939dSAdrian Hunter "use per-thread mmaps"), 1305bcc84ec6SStephane Eranian OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register", 1306bcc84ec6SStephane Eranian "sample selected machine registers on interrupt," 1307bcc84ec6SStephane Eranian " use -I ? to list register names", parse_regs), 130885c273d2SAndi Kleen OPT_BOOLEAN(0, "running-time", &record.opts.running_time, 130985c273d2SAndi Kleen "Record running/enabled time of read (:S) events"), 1310814c8c38SPeter Zijlstra OPT_CALLBACK('k', "clockid", &record.opts, 1311814c8c38SPeter Zijlstra "clockid", "clockid to use for events, see clock_gettime()", 1312814c8c38SPeter Zijlstra parse_clockid), 13132dd6d8a1SAdrian Hunter OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts, 13142dd6d8a1SAdrian Hunter "opts", "AUX area tracing Snapshot Mode", ""), 13159d9cad76SKan Liang OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout, 13169d9cad76SKan Liang "per thread proc mmap processing timeout in ms"), 1317b757bb09SAdrian Hunter OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events, 1318b757bb09SAdrian Hunter "Record context switch events"), 131985723885SJiri Olsa OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel, 132085723885SJiri Olsa "Configure all used events to run in kernel space.", 132185723885SJiri Olsa PARSE_OPT_EXCLUSIVE), 132285723885SJiri Olsa OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user, 132385723885SJiri Olsa "Configure all used events to run in user space.", 132485723885SJiri Olsa PARSE_OPT_EXCLUSIVE), 132571dc2326SWang Nan OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", 132671dc2326SWang Nan "clang binary to use for compiling BPF scriptlets"), 132771dc2326SWang Nan OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", 132871dc2326SWang Nan "options passed to clang when compiling BPF scriptlets"), 13297efe0e03SHe Kuang OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, 13307efe0e03SHe Kuang "file", "vmlinux pathname"), 13316156681bSNamhyung Kim OPT_BOOLEAN(0, "buildid-all", &record.buildid_all, 13326156681bSNamhyung Kim "Record build-id of all DSOs regardless of hits"), 1333ecfd7a9cSWang Nan OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename, 1334ecfd7a9cSWang Nan "append timestamp to output filename"), 13353c1cb7e3SWang Nan OPT_BOOLEAN(0, "switch-output", &record.switch_output, 13363c1cb7e3SWang Nan "Switch output when receive SIGUSR2"), 133786470930SIngo Molnar OPT_END() 133886470930SIngo Molnar }; 133986470930SIngo Molnar 1340e5b2c207SNamhyung Kim struct option *record_options = __record_options; 1341e5b2c207SNamhyung Kim 13421d037ca1SIrina Tirdea int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) 134386470930SIngo Molnar { 1344ef149c25SAdrian Hunter int err; 13458c6f45a7SArnaldo Carvalho de Melo struct record *rec = &record; 134616ad2ffbSNamhyung Kim char errbuf[BUFSIZ]; 134786470930SIngo Molnar 134848e1cab1SWang Nan #ifndef HAVE_LIBBPF_SUPPORT 134948e1cab1SWang Nan # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c) 135048e1cab1SWang Nan set_nobuild('\0', "clang-path", true); 135148e1cab1SWang Nan set_nobuild('\0', "clang-opt", true); 135248e1cab1SWang Nan # undef set_nobuild 135348e1cab1SWang Nan #endif 135448e1cab1SWang Nan 13557efe0e03SHe Kuang #ifndef HAVE_BPF_PROLOGUE 13567efe0e03SHe Kuang # if !defined (HAVE_DWARF_SUPPORT) 13577efe0e03SHe Kuang # define REASON "NO_DWARF=1" 13587efe0e03SHe Kuang # elif !defined (HAVE_LIBBPF_SUPPORT) 13597efe0e03SHe Kuang # define REASON "NO_LIBBPF=1" 13607efe0e03SHe Kuang # else 13617efe0e03SHe Kuang # define REASON "this architecture doesn't support BPF prologue" 13627efe0e03SHe Kuang # endif 13637efe0e03SHe Kuang # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c) 13647efe0e03SHe Kuang set_nobuild('\0', "vmlinux", true); 13657efe0e03SHe Kuang # undef set_nobuild 13667efe0e03SHe Kuang # undef REASON 13677efe0e03SHe Kuang #endif 13687efe0e03SHe Kuang 13693e2be2daSArnaldo Carvalho de Melo rec->evlist = perf_evlist__new(); 13703e2be2daSArnaldo Carvalho de Melo if (rec->evlist == NULL) 1371361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1372361c99a6SArnaldo Carvalho de Melo 1373eb853e80SJiri Olsa perf_config(perf_record_config, rec); 1374eb853e80SJiri Olsa 1375bca647aaSTom Zanussi argc = parse_options(argc, argv, record_options, record_usage, 1376a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 1377602ad878SArnaldo Carvalho de Melo if (!argc && target__none(&rec->opts.target)) 1378bca647aaSTom Zanussi usage_with_options(record_usage, record_options); 137986470930SIngo Molnar 1380bea03405SNamhyung Kim if (nr_cgroups && !rec->opts.target.system_wide) { 1381c7118369SNamhyung Kim usage_with_options_msg(record_usage, record_options, 1382c7118369SNamhyung Kim "cgroup monitoring only available in system-wide mode"); 1383c7118369SNamhyung Kim 1384023695d9SStephane Eranian } 1385b757bb09SAdrian Hunter if (rec->opts.record_switch_events && 1386b757bb09SAdrian Hunter !perf_can_record_switch_events()) { 1387c7118369SNamhyung Kim ui__error("kernel does not support recording context switch events\n"); 1388c7118369SNamhyung Kim parse_options_usage(record_usage, record_options, "switch-events", 0); 1389c7118369SNamhyung Kim return -EINVAL; 1390b757bb09SAdrian Hunter } 1391023695d9SStephane Eranian 1392eca857abSWang Nan if (rec->switch_output) 1393eca857abSWang Nan rec->timestamp_filename = true; 1394eca857abSWang Nan 1395ef149c25SAdrian Hunter if (!rec->itr) { 1396ef149c25SAdrian Hunter rec->itr = auxtrace_record__init(rec->evlist, &err); 1397ef149c25SAdrian Hunter if (err) 1398ef149c25SAdrian Hunter return err; 1399ef149c25SAdrian Hunter } 1400ef149c25SAdrian Hunter 14012dd6d8a1SAdrian Hunter err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts, 14022dd6d8a1SAdrian Hunter rec->opts.auxtrace_snapshot_opts); 14032dd6d8a1SAdrian Hunter if (err) 14042dd6d8a1SAdrian Hunter return err; 14052dd6d8a1SAdrian Hunter 1406d7888573SWang Nan err = bpf__setup_stdout(rec->evlist); 1407d7888573SWang Nan if (err) { 1408d7888573SWang Nan bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf)); 1409d7888573SWang Nan pr_err("ERROR: Setup BPF stdout failed: %s\n", 1410d7888573SWang Nan errbuf); 1411d7888573SWang Nan return err; 1412d7888573SWang Nan } 1413d7888573SWang Nan 1414ef149c25SAdrian Hunter err = -ENOMEM; 1415ef149c25SAdrian Hunter 14160a7e6d1bSNamhyung Kim symbol__init(NULL); 1417baa2f6ceSArnaldo Carvalho de Melo 1418ec80fde7SArnaldo Carvalho de Melo if (symbol_conf.kptr_restrict) 1419646aaea6SArnaldo Carvalho de Melo pr_warning( 1420646aaea6SArnaldo Carvalho de Melo "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" 1421ec80fde7SArnaldo Carvalho de Melo "check /proc/sys/kernel/kptr_restrict.\n\n" 1422646aaea6SArnaldo Carvalho de Melo "Samples in kernel functions may not be resolved if a suitable vmlinux\n" 1423646aaea6SArnaldo Carvalho de Melo "file is not found in the buildid cache or in the vmlinux path.\n\n" 1424646aaea6SArnaldo Carvalho de Melo "Samples in kernel modules won't be resolved at all.\n\n" 1425646aaea6SArnaldo Carvalho de Melo "If some relocation was applied (e.g. kexec) symbols may be misresolved\n" 1426646aaea6SArnaldo Carvalho de Melo "even with a suitable vmlinux or kallsyms file.\n\n"); 1427ec80fde7SArnaldo Carvalho de Melo 14280c1d46a8SWang Nan if (rec->no_buildid_cache || rec->no_buildid) { 1429a1ac1d3cSStephane Eranian disable_buildid_cache(); 14300c1d46a8SWang Nan } else if (rec->switch_output) { 14310c1d46a8SWang Nan /* 14320c1d46a8SWang Nan * In 'perf record --switch-output', disable buildid 14330c1d46a8SWang Nan * generation by default to reduce data file switching 14340c1d46a8SWang Nan * overhead. Still generate buildid if they are required 14350c1d46a8SWang Nan * explicitly using 14360c1d46a8SWang Nan * 14370c1d46a8SWang Nan * perf record --signal-trigger --no-no-buildid \ 14380c1d46a8SWang Nan * --no-no-buildid-cache 14390c1d46a8SWang Nan * 14400c1d46a8SWang Nan * Following code equals to: 14410c1d46a8SWang Nan * 14420c1d46a8SWang Nan * if ((rec->no_buildid || !rec->no_buildid_set) && 14430c1d46a8SWang Nan * (rec->no_buildid_cache || !rec->no_buildid_cache_set)) 14440c1d46a8SWang Nan * disable_buildid_cache(); 14450c1d46a8SWang Nan */ 14460c1d46a8SWang Nan bool disable = true; 14470c1d46a8SWang Nan 14480c1d46a8SWang Nan if (rec->no_buildid_set && !rec->no_buildid) 14490c1d46a8SWang Nan disable = false; 14500c1d46a8SWang Nan if (rec->no_buildid_cache_set && !rec->no_buildid_cache) 14510c1d46a8SWang Nan disable = false; 14520c1d46a8SWang Nan if (disable) { 14530c1d46a8SWang Nan rec->no_buildid = true; 14540c1d46a8SWang Nan rec->no_buildid_cache = true; 14550c1d46a8SWang Nan disable_buildid_cache(); 14560c1d46a8SWang Nan } 14570c1d46a8SWang Nan } 1458655000e7SArnaldo Carvalho de Melo 14593e2be2daSArnaldo Carvalho de Melo if (rec->evlist->nr_entries == 0 && 14603e2be2daSArnaldo Carvalho de Melo perf_evlist__add_default(rec->evlist) < 0) { 146169aad6f1SArnaldo Carvalho de Melo pr_err("Not enough memory for event selector list\n"); 146269aad6f1SArnaldo Carvalho de Melo goto out_symbol_exit; 1463bbd36e5eSPeter Zijlstra } 146486470930SIngo Molnar 146569e7e5b0SAdrian Hunter if (rec->opts.target.tid && !rec->opts.no_inherit_set) 146669e7e5b0SAdrian Hunter rec->opts.no_inherit = true; 146769e7e5b0SAdrian Hunter 1468602ad878SArnaldo Carvalho de Melo err = target__validate(&rec->opts.target); 146916ad2ffbSNamhyung Kim if (err) { 1470602ad878SArnaldo Carvalho de Melo target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); 147116ad2ffbSNamhyung Kim ui__warning("%s", errbuf); 147216ad2ffbSNamhyung Kim } 14734bd0f2d2SNamhyung Kim 1474602ad878SArnaldo Carvalho de Melo err = target__parse_uid(&rec->opts.target); 147516ad2ffbSNamhyung Kim if (err) { 147616ad2ffbSNamhyung Kim int saved_errno = errno; 147716ad2ffbSNamhyung Kim 1478602ad878SArnaldo Carvalho de Melo target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); 14793780f488SNamhyung Kim ui__error("%s", errbuf); 148016ad2ffbSNamhyung Kim 148116ad2ffbSNamhyung Kim err = -saved_errno; 14828fa60e1fSNamhyung Kim goto out_symbol_exit; 148316ad2ffbSNamhyung Kim } 14840d37aa34SArnaldo Carvalho de Melo 148516ad2ffbSNamhyung Kim err = -ENOMEM; 14863e2be2daSArnaldo Carvalho de Melo if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0) 1487dd7927f4SArnaldo Carvalho de Melo usage_with_options(record_usage, record_options); 148869aad6f1SArnaldo Carvalho de Melo 1489ef149c25SAdrian Hunter err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts); 1490ef149c25SAdrian Hunter if (err) 1491ef149c25SAdrian Hunter goto out_symbol_exit; 1492ef149c25SAdrian Hunter 14936156681bSNamhyung Kim /* 14946156681bSNamhyung Kim * We take all buildids when the file contains 14956156681bSNamhyung Kim * AUX area tracing data because we do not decode the 14966156681bSNamhyung Kim * trace because it would take too long. 14976156681bSNamhyung Kim */ 14986156681bSNamhyung Kim if (rec->opts.full_auxtrace) 14996156681bSNamhyung Kim rec->buildid_all = true; 15006156681bSNamhyung Kim 1501b4006796SArnaldo Carvalho de Melo if (record_opts__config(&rec->opts)) { 150239d17dacSArnaldo Carvalho de Melo err = -EINVAL; 150303ad9747SArnaldo Carvalho de Melo goto out_symbol_exit; 15047e4ff9e3SMike Galbraith } 15057e4ff9e3SMike Galbraith 1506d20deb64SArnaldo Carvalho de Melo err = __cmd_record(&record, argc, argv); 1507d65a458bSArnaldo Carvalho de Melo out_symbol_exit: 150845604710SNamhyung Kim perf_evlist__delete(rec->evlist); 1509d65a458bSArnaldo Carvalho de Melo symbol__exit(); 1510ef149c25SAdrian Hunter auxtrace_record__free(rec->itr); 151139d17dacSArnaldo Carvalho de Melo return err; 151286470930SIngo Molnar } 15132dd6d8a1SAdrian Hunter 15142dd6d8a1SAdrian Hunter static void snapshot_sig_handler(int sig __maybe_unused) 15152dd6d8a1SAdrian Hunter { 15165f9cf599SWang Nan if (trigger_is_ready(&auxtrace_snapshot_trigger)) { 15175f9cf599SWang Nan trigger_hit(&auxtrace_snapshot_trigger); 15182dd6d8a1SAdrian Hunter auxtrace_record__snapshot_started = 1; 15195f9cf599SWang Nan if (auxtrace_record__snapshot_start(record.itr)) 15205f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 15215f9cf599SWang Nan } 15223c1cb7e3SWang Nan 15233c1cb7e3SWang Nan if (trigger_is_ready(&switch_output_trigger)) 15243c1cb7e3SWang Nan trigger_hit(&switch_output_trigger); 15252dd6d8a1SAdrian Hunter } 1526