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 86*3a62a7b8SWang Nan static int 87*3a62a7b8SWang Nan backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end) 88*3a62a7b8SWang Nan { 89*3a62a7b8SWang Nan struct perf_event_header *pheader; 90*3a62a7b8SWang Nan u64 evt_head = head; 91*3a62a7b8SWang Nan int size = mask + 1; 92*3a62a7b8SWang Nan 93*3a62a7b8SWang Nan pr_debug2("backward_rb_find_range: buf=%p, head=%"PRIx64"\n", buf, head); 94*3a62a7b8SWang Nan pheader = (struct perf_event_header *)(buf + (head & mask)); 95*3a62a7b8SWang Nan *start = head; 96*3a62a7b8SWang Nan while (true) { 97*3a62a7b8SWang Nan if (evt_head - head >= (unsigned int)size) { 98*3a62a7b8SWang Nan pr_debug("Finshed reading backward ring buffer: rewind\n"); 99*3a62a7b8SWang Nan if (evt_head - head > (unsigned int)size) 100*3a62a7b8SWang Nan evt_head -= pheader->size; 101*3a62a7b8SWang Nan *end = evt_head; 102*3a62a7b8SWang Nan return 0; 103*3a62a7b8SWang Nan } 104*3a62a7b8SWang Nan 105*3a62a7b8SWang Nan pheader = (struct perf_event_header *)(buf + (evt_head & mask)); 106*3a62a7b8SWang Nan 107*3a62a7b8SWang Nan if (pheader->size == 0) { 108*3a62a7b8SWang Nan pr_debug("Finshed reading backward ring buffer: get start\n"); 109*3a62a7b8SWang Nan *end = evt_head; 110*3a62a7b8SWang Nan return 0; 111*3a62a7b8SWang Nan } 112*3a62a7b8SWang Nan 113*3a62a7b8SWang Nan evt_head += pheader->size; 114*3a62a7b8SWang Nan pr_debug3("move evt_head: %"PRIx64"\n", evt_head); 115*3a62a7b8SWang Nan } 116*3a62a7b8SWang Nan WARN_ONCE(1, "Shouldn't get here\n"); 117*3a62a7b8SWang Nan return -1; 118*3a62a7b8SWang Nan } 119*3a62a7b8SWang Nan 120*3a62a7b8SWang Nan static int 121*3a62a7b8SWang Nan rb_find_range(struct perf_evlist *evlist, 122*3a62a7b8SWang Nan void *data, int mask, u64 head, u64 old, 123*3a62a7b8SWang Nan u64 *start, u64 *end) 124*3a62a7b8SWang Nan { 125*3a62a7b8SWang Nan if (!evlist->backward) { 126*3a62a7b8SWang Nan *start = old; 127*3a62a7b8SWang Nan *end = head; 128*3a62a7b8SWang Nan return 0; 129*3a62a7b8SWang Nan } 130*3a62a7b8SWang Nan 131*3a62a7b8SWang Nan return backward_rb_find_range(data, mask, head, start, end); 132*3a62a7b8SWang Nan } 133*3a62a7b8SWang Nan 134e5685730SArnaldo Carvalho de Melo static int record__mmap_read(struct record *rec, int idx) 13586470930SIngo Molnar { 136e5685730SArnaldo Carvalho de Melo struct perf_mmap *md = &rec->evlist->mmap[idx]; 1377b8283b5SDavid Ahern u64 head = perf_mmap__read_head(md); 1387b8283b5SDavid Ahern u64 old = md->prev; 13909fa4f40SWang Nan u64 end = head, start = old; 140918512b4SJiri Olsa unsigned char *data = md->base + page_size; 14186470930SIngo Molnar unsigned long size; 14286470930SIngo Molnar void *buf; 1438d3eca20SDavid Ahern int rc = 0; 14486470930SIngo Molnar 145*3a62a7b8SWang Nan if (rb_find_range(rec->evlist, data, md->mask, head, 146*3a62a7b8SWang Nan old, &start, &end)) 147*3a62a7b8SWang Nan return -1; 148*3a62a7b8SWang Nan 14909fa4f40SWang Nan if (start == end) 1508d3eca20SDavid Ahern return 0; 15186470930SIngo Molnar 152d20deb64SArnaldo Carvalho de Melo rec->samples++; 15386470930SIngo Molnar 15409fa4f40SWang Nan size = end - start; 1552d11c650SWang Nan if (size > (unsigned long)(md->mask) + 1) { 1562d11c650SWang Nan WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); 1572d11c650SWang Nan 1582d11c650SWang Nan md->prev = head; 1592d11c650SWang Nan perf_evlist__mmap_consume(rec->evlist, idx); 1602d11c650SWang Nan return 0; 1612d11c650SWang Nan } 16286470930SIngo Molnar 16309fa4f40SWang Nan if ((start & md->mask) + size != (end & md->mask)) { 16409fa4f40SWang Nan buf = &data[start & md->mask]; 16509fa4f40SWang Nan size = md->mask + 1 - (start & md->mask); 16609fa4f40SWang Nan start += size; 16786470930SIngo Molnar 1688c6f45a7SArnaldo Carvalho de Melo if (record__write(rec, buf, size) < 0) { 1698d3eca20SDavid Ahern rc = -1; 1708d3eca20SDavid Ahern goto out; 1718d3eca20SDavid Ahern } 17286470930SIngo Molnar } 17386470930SIngo Molnar 17409fa4f40SWang Nan buf = &data[start & md->mask]; 17509fa4f40SWang Nan size = end - start; 17609fa4f40SWang Nan start += size; 17786470930SIngo Molnar 1788c6f45a7SArnaldo Carvalho de Melo if (record__write(rec, buf, size) < 0) { 1798d3eca20SDavid Ahern rc = -1; 1808d3eca20SDavid Ahern goto out; 1818d3eca20SDavid Ahern } 18286470930SIngo Molnar 18309fa4f40SWang Nan md->prev = head; 184e5685730SArnaldo Carvalho de Melo perf_evlist__mmap_consume(rec->evlist, idx); 1858d3eca20SDavid Ahern out: 1868d3eca20SDavid Ahern return rc; 18786470930SIngo Molnar } 18886470930SIngo Molnar 1892dd6d8a1SAdrian Hunter static volatile int done; 1902dd6d8a1SAdrian Hunter static volatile int signr = -1; 1912dd6d8a1SAdrian Hunter static volatile int child_finished; 192c0bdc1c4SWang Nan 1932dd6d8a1SAdrian Hunter static volatile int auxtrace_record__snapshot_started; 1945f9cf599SWang Nan static DEFINE_TRIGGER(auxtrace_snapshot_trigger); 1953c1cb7e3SWang Nan static DEFINE_TRIGGER(switch_output_trigger); 1962dd6d8a1SAdrian Hunter 1972dd6d8a1SAdrian Hunter static void sig_handler(int sig) 1982dd6d8a1SAdrian Hunter { 1992dd6d8a1SAdrian Hunter if (sig == SIGCHLD) 2002dd6d8a1SAdrian Hunter child_finished = 1; 2012dd6d8a1SAdrian Hunter else 2022dd6d8a1SAdrian Hunter signr = sig; 2032dd6d8a1SAdrian Hunter 2042dd6d8a1SAdrian Hunter done = 1; 2052dd6d8a1SAdrian Hunter } 2062dd6d8a1SAdrian Hunter 2072dd6d8a1SAdrian Hunter static void record__sig_exit(void) 2082dd6d8a1SAdrian Hunter { 2092dd6d8a1SAdrian Hunter if (signr == -1) 2102dd6d8a1SAdrian Hunter return; 2112dd6d8a1SAdrian Hunter 2122dd6d8a1SAdrian Hunter signal(signr, SIG_DFL); 2132dd6d8a1SAdrian Hunter raise(signr); 2142dd6d8a1SAdrian Hunter } 2152dd6d8a1SAdrian Hunter 216e31f0d01SAdrian Hunter #ifdef HAVE_AUXTRACE_SUPPORT 217e31f0d01SAdrian Hunter 218ef149c25SAdrian Hunter static int record__process_auxtrace(struct perf_tool *tool, 219ef149c25SAdrian Hunter union perf_event *event, void *data1, 220ef149c25SAdrian Hunter size_t len1, void *data2, size_t len2) 221ef149c25SAdrian Hunter { 222ef149c25SAdrian Hunter struct record *rec = container_of(tool, struct record, tool); 22399fa2984SAdrian Hunter struct perf_data_file *file = &rec->file; 224ef149c25SAdrian Hunter size_t padding; 225ef149c25SAdrian Hunter u8 pad[8] = {0}; 226ef149c25SAdrian Hunter 22799fa2984SAdrian Hunter if (!perf_data_file__is_pipe(file)) { 22899fa2984SAdrian Hunter off_t file_offset; 22999fa2984SAdrian Hunter int fd = perf_data_file__fd(file); 23099fa2984SAdrian Hunter int err; 23199fa2984SAdrian Hunter 23299fa2984SAdrian Hunter file_offset = lseek(fd, 0, SEEK_CUR); 23399fa2984SAdrian Hunter if (file_offset == -1) 23499fa2984SAdrian Hunter return -1; 23599fa2984SAdrian Hunter err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index, 23699fa2984SAdrian Hunter event, file_offset); 23799fa2984SAdrian Hunter if (err) 23899fa2984SAdrian Hunter return err; 23999fa2984SAdrian Hunter } 24099fa2984SAdrian Hunter 241ef149c25SAdrian Hunter /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */ 242ef149c25SAdrian Hunter padding = (len1 + len2) & 7; 243ef149c25SAdrian Hunter if (padding) 244ef149c25SAdrian Hunter padding = 8 - padding; 245ef149c25SAdrian Hunter 246ef149c25SAdrian Hunter record__write(rec, event, event->header.size); 247ef149c25SAdrian Hunter record__write(rec, data1, len1); 248ef149c25SAdrian Hunter if (len2) 249ef149c25SAdrian Hunter record__write(rec, data2, len2); 250ef149c25SAdrian Hunter record__write(rec, &pad, padding); 251ef149c25SAdrian Hunter 252ef149c25SAdrian Hunter return 0; 253ef149c25SAdrian Hunter } 254ef149c25SAdrian Hunter 255ef149c25SAdrian Hunter static int record__auxtrace_mmap_read(struct record *rec, 256ef149c25SAdrian Hunter struct auxtrace_mmap *mm) 257ef149c25SAdrian Hunter { 258ef149c25SAdrian Hunter int ret; 259ef149c25SAdrian Hunter 260ef149c25SAdrian Hunter ret = auxtrace_mmap__read(mm, rec->itr, &rec->tool, 261ef149c25SAdrian Hunter record__process_auxtrace); 262ef149c25SAdrian Hunter if (ret < 0) 263ef149c25SAdrian Hunter return ret; 264ef149c25SAdrian Hunter 265ef149c25SAdrian Hunter if (ret) 266ef149c25SAdrian Hunter rec->samples++; 267ef149c25SAdrian Hunter 268ef149c25SAdrian Hunter return 0; 269ef149c25SAdrian Hunter } 270ef149c25SAdrian Hunter 2712dd6d8a1SAdrian Hunter static int record__auxtrace_mmap_read_snapshot(struct record *rec, 2722dd6d8a1SAdrian Hunter struct auxtrace_mmap *mm) 2732dd6d8a1SAdrian Hunter { 2742dd6d8a1SAdrian Hunter int ret; 2752dd6d8a1SAdrian Hunter 2762dd6d8a1SAdrian Hunter ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool, 2772dd6d8a1SAdrian Hunter record__process_auxtrace, 2782dd6d8a1SAdrian Hunter rec->opts.auxtrace_snapshot_size); 2792dd6d8a1SAdrian Hunter if (ret < 0) 2802dd6d8a1SAdrian Hunter return ret; 2812dd6d8a1SAdrian Hunter 2822dd6d8a1SAdrian Hunter if (ret) 2832dd6d8a1SAdrian Hunter rec->samples++; 2842dd6d8a1SAdrian Hunter 2852dd6d8a1SAdrian Hunter return 0; 2862dd6d8a1SAdrian Hunter } 2872dd6d8a1SAdrian Hunter 2882dd6d8a1SAdrian Hunter static int record__auxtrace_read_snapshot_all(struct record *rec) 2892dd6d8a1SAdrian Hunter { 2902dd6d8a1SAdrian Hunter int i; 2912dd6d8a1SAdrian Hunter int rc = 0; 2922dd6d8a1SAdrian Hunter 2932dd6d8a1SAdrian Hunter for (i = 0; i < rec->evlist->nr_mmaps; i++) { 2942dd6d8a1SAdrian Hunter struct auxtrace_mmap *mm = 2952dd6d8a1SAdrian Hunter &rec->evlist->mmap[i].auxtrace_mmap; 2962dd6d8a1SAdrian Hunter 2972dd6d8a1SAdrian Hunter if (!mm->base) 2982dd6d8a1SAdrian Hunter continue; 2992dd6d8a1SAdrian Hunter 3002dd6d8a1SAdrian Hunter if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) { 3012dd6d8a1SAdrian Hunter rc = -1; 3022dd6d8a1SAdrian Hunter goto out; 3032dd6d8a1SAdrian Hunter } 3042dd6d8a1SAdrian Hunter } 3052dd6d8a1SAdrian Hunter out: 3062dd6d8a1SAdrian Hunter return rc; 3072dd6d8a1SAdrian Hunter } 3082dd6d8a1SAdrian Hunter 3092dd6d8a1SAdrian Hunter static void record__read_auxtrace_snapshot(struct record *rec) 3102dd6d8a1SAdrian Hunter { 3112dd6d8a1SAdrian Hunter pr_debug("Recording AUX area tracing snapshot\n"); 3122dd6d8a1SAdrian Hunter if (record__auxtrace_read_snapshot_all(rec) < 0) { 3135f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 3142dd6d8a1SAdrian Hunter } else { 3155f9cf599SWang Nan if (auxtrace_record__snapshot_finish(rec->itr)) 3165f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 3175f9cf599SWang Nan else 3185f9cf599SWang Nan trigger_ready(&auxtrace_snapshot_trigger); 3192dd6d8a1SAdrian Hunter } 3202dd6d8a1SAdrian Hunter } 3212dd6d8a1SAdrian Hunter 322e31f0d01SAdrian Hunter #else 323e31f0d01SAdrian Hunter 324e31f0d01SAdrian Hunter static inline 325e31f0d01SAdrian Hunter int record__auxtrace_mmap_read(struct record *rec __maybe_unused, 326e31f0d01SAdrian Hunter struct auxtrace_mmap *mm __maybe_unused) 327e31f0d01SAdrian Hunter { 328e31f0d01SAdrian Hunter return 0; 329e31f0d01SAdrian Hunter } 330e31f0d01SAdrian Hunter 3312dd6d8a1SAdrian Hunter static inline 3322dd6d8a1SAdrian Hunter void record__read_auxtrace_snapshot(struct record *rec __maybe_unused) 3332dd6d8a1SAdrian Hunter { 3342dd6d8a1SAdrian Hunter } 3352dd6d8a1SAdrian Hunter 3362dd6d8a1SAdrian Hunter static inline 3372dd6d8a1SAdrian Hunter int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused) 3382dd6d8a1SAdrian Hunter { 3392dd6d8a1SAdrian Hunter return 0; 3402dd6d8a1SAdrian Hunter } 3412dd6d8a1SAdrian Hunter 342e31f0d01SAdrian Hunter #endif 343e31f0d01SAdrian Hunter 3448c6f45a7SArnaldo Carvalho de Melo static int record__open(struct record *rec) 345dd7927f4SArnaldo Carvalho de Melo { 34656e52e85SArnaldo Carvalho de Melo char msg[512]; 3476a4bb04cSJiri Olsa struct perf_evsel *pos; 348d20deb64SArnaldo Carvalho de Melo struct perf_evlist *evlist = rec->evlist; 349d20deb64SArnaldo Carvalho de Melo struct perf_session *session = rec->session; 350b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &rec->opts; 3518d3eca20SDavid Ahern int rc = 0; 352dd7927f4SArnaldo Carvalho de Melo 353e68ae9cfSArnaldo Carvalho de Melo perf_evlist__config(evlist, opts, &callchain_param); 354cac21425SJiri Olsa 3550050f7aaSArnaldo Carvalho de Melo evlist__for_each(evlist, pos) { 3563da297a6SIngo Molnar try_again: 357d988d5eeSKan Liang if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { 35856e52e85SArnaldo Carvalho de Melo if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { 3593da297a6SIngo Molnar if (verbose) 360c0a54341SArnaldo Carvalho de Melo ui__warning("%s\n", msg); 3613da297a6SIngo Molnar goto try_again; 3623da297a6SIngo Molnar } 363ca6a4258SDavid Ahern 36456e52e85SArnaldo Carvalho de Melo rc = -errno; 36556e52e85SArnaldo Carvalho de Melo perf_evsel__open_strerror(pos, &opts->target, 36656e52e85SArnaldo Carvalho de Melo errno, msg, sizeof(msg)); 36756e52e85SArnaldo Carvalho de Melo ui__error("%s\n", msg); 3688d3eca20SDavid Ahern goto out; 3697c6a1c65SPeter Zijlstra } 3707c6a1c65SPeter Zijlstra } 3717c6a1c65SPeter Zijlstra 37223d4aad4SArnaldo Carvalho de Melo if (perf_evlist__apply_filters(evlist, &pos)) { 37323d4aad4SArnaldo Carvalho de Melo error("failed to set filter \"%s\" on event %s with %d (%s)\n", 37423d4aad4SArnaldo Carvalho de Melo pos->filter, perf_evsel__name(pos), errno, 37535550da3SMasami Hiramatsu strerror_r(errno, msg, sizeof(msg))); 3768d3eca20SDavid Ahern rc = -1; 3778d3eca20SDavid Ahern goto out; 3780a102479SFrederic Weisbecker } 3790a102479SFrederic Weisbecker 380ef149c25SAdrian Hunter if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, 3812dd6d8a1SAdrian Hunter opts->auxtrace_mmap_pages, 3822dd6d8a1SAdrian Hunter opts->auxtrace_snapshot_mode) < 0) { 3838d3eca20SDavid Ahern if (errno == EPERM) { 3848d3eca20SDavid Ahern pr_err("Permission error mapping pages.\n" 38518e60939SNelson Elhage "Consider increasing " 38618e60939SNelson Elhage "/proc/sys/kernel/perf_event_mlock_kb,\n" 38718e60939SNelson Elhage "or try again with a smaller value of -m/--mmap_pages.\n" 388ef149c25SAdrian Hunter "(current value: %u,%u)\n", 389ef149c25SAdrian Hunter opts->mmap_pages, opts->auxtrace_mmap_pages); 3908d3eca20SDavid Ahern rc = -errno; 3918d3eca20SDavid Ahern } else { 39235550da3SMasami Hiramatsu pr_err("failed to mmap with %d (%s)\n", errno, 39335550da3SMasami Hiramatsu strerror_r(errno, msg, sizeof(msg))); 39495c36561SWang Nan if (errno) 3958d3eca20SDavid Ahern rc = -errno; 39695c36561SWang Nan else 39795c36561SWang Nan rc = -EINVAL; 3988d3eca20SDavid Ahern } 3998d3eca20SDavid Ahern goto out; 40018e60939SNelson Elhage } 4010a27d7f9SArnaldo Carvalho de Melo 402a91e5431SArnaldo Carvalho de Melo session->evlist = evlist; 4037b56cce2SArnaldo Carvalho de Melo perf_session__set_id_hdr_size(session); 4048d3eca20SDavid Ahern out: 4058d3eca20SDavid Ahern return rc; 406a91e5431SArnaldo Carvalho de Melo } 407a91e5431SArnaldo Carvalho de Melo 408e3d59112SNamhyung Kim static int process_sample_event(struct perf_tool *tool, 409e3d59112SNamhyung Kim union perf_event *event, 410e3d59112SNamhyung Kim struct perf_sample *sample, 411e3d59112SNamhyung Kim struct perf_evsel *evsel, 412e3d59112SNamhyung Kim struct machine *machine) 413e3d59112SNamhyung Kim { 414e3d59112SNamhyung Kim struct record *rec = container_of(tool, struct record, tool); 415e3d59112SNamhyung Kim 416e3d59112SNamhyung Kim rec->samples++; 417e3d59112SNamhyung Kim 418e3d59112SNamhyung Kim return build_id__mark_dso_hit(tool, event, sample, evsel, machine); 419e3d59112SNamhyung Kim } 420e3d59112SNamhyung Kim 4218c6f45a7SArnaldo Carvalho de Melo static int process_buildids(struct record *rec) 4226122e4e4SArnaldo Carvalho de Melo { 423f5fc1412SJiri Olsa struct perf_data_file *file = &rec->file; 424f5fc1412SJiri Olsa struct perf_session *session = rec->session; 4256122e4e4SArnaldo Carvalho de Melo 426457ae94aSHe Kuang if (file->size == 0) 4279f591fd7SArnaldo Carvalho de Melo return 0; 4289f591fd7SArnaldo Carvalho de Melo 42900dc8657SNamhyung Kim /* 43000dc8657SNamhyung Kim * During this process, it'll load kernel map and replace the 43100dc8657SNamhyung Kim * dso->long_name to a real pathname it found. In this case 43200dc8657SNamhyung Kim * we prefer the vmlinux path like 43300dc8657SNamhyung Kim * /lib/modules/3.16.4/build/vmlinux 43400dc8657SNamhyung Kim * 43500dc8657SNamhyung Kim * rather than build-id path (in debug directory). 43600dc8657SNamhyung Kim * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551 43700dc8657SNamhyung Kim */ 43800dc8657SNamhyung Kim symbol_conf.ignore_vmlinux_buildid = true; 43900dc8657SNamhyung Kim 4406156681bSNamhyung Kim /* 4416156681bSNamhyung Kim * If --buildid-all is given, it marks all DSO regardless of hits, 4426156681bSNamhyung Kim * so no need to process samples. 4436156681bSNamhyung Kim */ 4446156681bSNamhyung Kim if (rec->buildid_all) 4456156681bSNamhyung Kim rec->tool.sample = NULL; 4466156681bSNamhyung Kim 447b7b61cbeSArnaldo Carvalho de Melo return perf_session__process_events(session); 4486122e4e4SArnaldo Carvalho de Melo } 4496122e4e4SArnaldo Carvalho de Melo 4508115d60cSArnaldo Carvalho de Melo static void perf_event__synthesize_guest_os(struct machine *machine, void *data) 451a1645ce1SZhang, Yanmin { 452a1645ce1SZhang, Yanmin int err; 45345694aa7SArnaldo Carvalho de Melo struct perf_tool *tool = data; 454a1645ce1SZhang, Yanmin /* 455a1645ce1SZhang, Yanmin *As for guest kernel when processing subcommand record&report, 456a1645ce1SZhang, Yanmin *we arrange module mmap prior to guest kernel mmap and trigger 457a1645ce1SZhang, Yanmin *a preload dso because default guest module symbols are loaded 458a1645ce1SZhang, Yanmin *from guest kallsyms instead of /lib/modules/XXX/XXX. This 459a1645ce1SZhang, Yanmin *method is used to avoid symbol missing when the first addr is 460a1645ce1SZhang, Yanmin *in module instead of in guest kernel. 461a1645ce1SZhang, Yanmin */ 46245694aa7SArnaldo Carvalho de Melo err = perf_event__synthesize_modules(tool, process_synthesized_event, 463743eb868SArnaldo Carvalho de Melo machine); 464a1645ce1SZhang, Yanmin if (err < 0) 465a1645ce1SZhang, Yanmin pr_err("Couldn't record guest kernel [%d]'s reference" 46623346f21SArnaldo Carvalho de Melo " relocation symbol.\n", machine->pid); 467a1645ce1SZhang, Yanmin 468a1645ce1SZhang, Yanmin /* 469a1645ce1SZhang, Yanmin * We use _stext for guest kernel because guest kernel's /proc/kallsyms 470a1645ce1SZhang, Yanmin * have no _text sometimes. 471a1645ce1SZhang, Yanmin */ 47245694aa7SArnaldo Carvalho de Melo err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, 4730ae617beSAdrian Hunter machine); 474a1645ce1SZhang, Yanmin if (err < 0) 475a1645ce1SZhang, Yanmin pr_err("Couldn't record guest kernel [%d]'s reference" 47623346f21SArnaldo Carvalho de Melo " relocation symbol.\n", machine->pid); 477a1645ce1SZhang, Yanmin } 478a1645ce1SZhang, Yanmin 47998402807SFrederic Weisbecker static struct perf_event_header finished_round_event = { 48098402807SFrederic Weisbecker .size = sizeof(struct perf_event_header), 48198402807SFrederic Weisbecker .type = PERF_RECORD_FINISHED_ROUND, 48298402807SFrederic Weisbecker }; 48398402807SFrederic Weisbecker 4848c6f45a7SArnaldo Carvalho de Melo static int record__mmap_read_all(struct record *rec) 48598402807SFrederic Weisbecker { 486dcabb507SJiri Olsa u64 bytes_written = rec->bytes_written; 4870e2e63ddSPeter Zijlstra int i; 4888d3eca20SDavid Ahern int rc = 0; 48998402807SFrederic Weisbecker 490d20deb64SArnaldo Carvalho de Melo for (i = 0; i < rec->evlist->nr_mmaps; i++) { 491ef149c25SAdrian Hunter struct auxtrace_mmap *mm = &rec->evlist->mmap[i].auxtrace_mmap; 492ef149c25SAdrian Hunter 4938d3eca20SDavid Ahern if (rec->evlist->mmap[i].base) { 494e5685730SArnaldo Carvalho de Melo if (record__mmap_read(rec, i) != 0) { 4958d3eca20SDavid Ahern rc = -1; 4968d3eca20SDavid Ahern goto out; 4978d3eca20SDavid Ahern } 4988d3eca20SDavid Ahern } 499ef149c25SAdrian Hunter 5002dd6d8a1SAdrian Hunter if (mm->base && !rec->opts.auxtrace_snapshot_mode && 501ef149c25SAdrian Hunter record__auxtrace_mmap_read(rec, mm) != 0) { 502ef149c25SAdrian Hunter rc = -1; 503ef149c25SAdrian Hunter goto out; 504ef149c25SAdrian Hunter } 50598402807SFrederic Weisbecker } 50698402807SFrederic Weisbecker 507dcabb507SJiri Olsa /* 508dcabb507SJiri Olsa * Mark the round finished in case we wrote 509dcabb507SJiri Olsa * at least one event. 510dcabb507SJiri Olsa */ 511dcabb507SJiri Olsa if (bytes_written != rec->bytes_written) 5128c6f45a7SArnaldo Carvalho de Melo rc = record__write(rec, &finished_round_event, sizeof(finished_round_event)); 5138d3eca20SDavid Ahern 5148d3eca20SDavid Ahern out: 5158d3eca20SDavid Ahern return rc; 51698402807SFrederic Weisbecker } 51798402807SFrederic Weisbecker 5188c6f45a7SArnaldo Carvalho de Melo static void record__init_features(struct record *rec) 51957706abcSDavid Ahern { 52057706abcSDavid Ahern struct perf_session *session = rec->session; 52157706abcSDavid Ahern int feat; 52257706abcSDavid Ahern 52357706abcSDavid Ahern for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++) 52457706abcSDavid Ahern perf_header__set_feat(&session->header, feat); 52557706abcSDavid Ahern 52657706abcSDavid Ahern if (rec->no_buildid) 52757706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_BUILD_ID); 52857706abcSDavid Ahern 5293e2be2daSArnaldo Carvalho de Melo if (!have_tracepoints(&rec->evlist->entries)) 53057706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); 53157706abcSDavid Ahern 53257706abcSDavid Ahern if (!rec->opts.branch_stack) 53357706abcSDavid Ahern perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 534ef149c25SAdrian Hunter 535ef149c25SAdrian Hunter if (!rec->opts.full_auxtrace) 536ef149c25SAdrian Hunter perf_header__clear_feat(&session->header, HEADER_AUXTRACE); 537ffa517adSJiri Olsa 538ffa517adSJiri Olsa perf_header__clear_feat(&session->header, HEADER_STAT); 53957706abcSDavid Ahern } 54057706abcSDavid Ahern 541e1ab48baSWang Nan static void 542e1ab48baSWang Nan record__finish_output(struct record *rec) 543e1ab48baSWang Nan { 544e1ab48baSWang Nan struct perf_data_file *file = &rec->file; 545e1ab48baSWang Nan int fd = perf_data_file__fd(file); 546e1ab48baSWang Nan 547e1ab48baSWang Nan if (file->is_pipe) 548e1ab48baSWang Nan return; 549e1ab48baSWang Nan 550e1ab48baSWang Nan rec->session->header.data_size += rec->bytes_written; 551e1ab48baSWang Nan file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR); 552e1ab48baSWang Nan 553e1ab48baSWang Nan if (!rec->no_buildid) { 554e1ab48baSWang Nan process_buildids(rec); 555e1ab48baSWang Nan 556e1ab48baSWang Nan if (rec->buildid_all) 557e1ab48baSWang Nan dsos__hit_all(rec->session); 558e1ab48baSWang Nan } 559e1ab48baSWang Nan perf_session__write_header(rec->session, rec->evlist, fd, true); 560e1ab48baSWang Nan 561e1ab48baSWang Nan return; 562e1ab48baSWang Nan } 563e1ab48baSWang Nan 564be7b0c9eSWang Nan static int record__synthesize_workload(struct record *rec) 565be7b0c9eSWang Nan { 566be7b0c9eSWang Nan struct { 567be7b0c9eSWang Nan struct thread_map map; 568be7b0c9eSWang Nan struct thread_map_data map_data; 569be7b0c9eSWang Nan } thread_map; 570be7b0c9eSWang Nan 571be7b0c9eSWang Nan thread_map.map.nr = 1; 572be7b0c9eSWang Nan thread_map.map.map[0].pid = rec->evlist->workload.pid; 573be7b0c9eSWang Nan thread_map.map.map[0].comm = NULL; 574be7b0c9eSWang Nan return perf_event__synthesize_thread_map(&rec->tool, &thread_map.map, 575be7b0c9eSWang Nan process_synthesized_event, 576be7b0c9eSWang Nan &rec->session->machines.host, 577be7b0c9eSWang Nan rec->opts.sample_address, 578be7b0c9eSWang Nan rec->opts.proc_map_timeout); 579be7b0c9eSWang Nan } 580be7b0c9eSWang Nan 5813c1cb7e3SWang Nan static int record__synthesize(struct record *rec); 5823c1cb7e3SWang Nan 583ecfd7a9cSWang Nan static int 584ecfd7a9cSWang Nan record__switch_output(struct record *rec, bool at_exit) 585ecfd7a9cSWang Nan { 586ecfd7a9cSWang Nan struct perf_data_file *file = &rec->file; 587ecfd7a9cSWang Nan int fd, err; 588ecfd7a9cSWang Nan 589ecfd7a9cSWang Nan /* Same Size: "2015122520103046"*/ 590ecfd7a9cSWang Nan char timestamp[] = "InvalidTimestamp"; 591ecfd7a9cSWang Nan 592ecfd7a9cSWang Nan rec->samples = 0; 593ecfd7a9cSWang Nan record__finish_output(rec); 594ecfd7a9cSWang Nan err = fetch_current_timestamp(timestamp, sizeof(timestamp)); 595ecfd7a9cSWang Nan if (err) { 596ecfd7a9cSWang Nan pr_err("Failed to get current timestamp\n"); 597ecfd7a9cSWang Nan return -EINVAL; 598ecfd7a9cSWang Nan } 599ecfd7a9cSWang Nan 600ecfd7a9cSWang Nan fd = perf_data_file__switch(file, timestamp, 601ecfd7a9cSWang Nan rec->session->header.data_offset, 602ecfd7a9cSWang Nan at_exit); 603ecfd7a9cSWang Nan if (fd >= 0 && !at_exit) { 604ecfd7a9cSWang Nan rec->bytes_written = 0; 605ecfd7a9cSWang Nan rec->session->header.data_size = 0; 606ecfd7a9cSWang Nan } 607ecfd7a9cSWang Nan 608ecfd7a9cSWang Nan if (!quiet) 609ecfd7a9cSWang Nan fprintf(stderr, "[ perf record: Dump %s.%s ]\n", 610ecfd7a9cSWang Nan file->path, timestamp); 6113c1cb7e3SWang Nan 6123c1cb7e3SWang Nan /* Output tracking events */ 613be7b0c9eSWang Nan if (!at_exit) { 6143c1cb7e3SWang Nan record__synthesize(rec); 6153c1cb7e3SWang Nan 616be7b0c9eSWang Nan /* 617be7b0c9eSWang Nan * In 'perf record --switch-output' without -a, 618be7b0c9eSWang Nan * record__synthesize() in record__switch_output() won't 619be7b0c9eSWang Nan * generate tracking events because there's no thread_map 620be7b0c9eSWang Nan * in evlist. Which causes newly created perf.data doesn't 621be7b0c9eSWang Nan * contain map and comm information. 622be7b0c9eSWang Nan * Create a fake thread_map and directly call 623be7b0c9eSWang Nan * perf_event__synthesize_thread_map() for those events. 624be7b0c9eSWang Nan */ 625be7b0c9eSWang Nan if (target__none(&rec->opts.target)) 626be7b0c9eSWang Nan record__synthesize_workload(rec); 627be7b0c9eSWang Nan } 628ecfd7a9cSWang Nan return fd; 629ecfd7a9cSWang Nan } 630ecfd7a9cSWang Nan 631f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno; 632f33cbe72SArnaldo Carvalho de Melo 633f33cbe72SArnaldo Carvalho de Melo /* 634f33cbe72SArnaldo Carvalho de Melo * perf_evlist__prepare_workload will send a SIGUSR1 635f33cbe72SArnaldo Carvalho de Melo * if the fork fails, since we asked by setting its 636f33cbe72SArnaldo Carvalho de Melo * want_signal to true. 637f33cbe72SArnaldo Carvalho de Melo */ 63845604710SNamhyung Kim static void workload_exec_failed_signal(int signo __maybe_unused, 63945604710SNamhyung Kim siginfo_t *info, 640f33cbe72SArnaldo Carvalho de Melo void *ucontext __maybe_unused) 641f33cbe72SArnaldo Carvalho de Melo { 642f33cbe72SArnaldo Carvalho de Melo workload_exec_errno = info->si_value.sival_int; 643f33cbe72SArnaldo Carvalho de Melo done = 1; 644f33cbe72SArnaldo Carvalho de Melo child_finished = 1; 645f33cbe72SArnaldo Carvalho de Melo } 646f33cbe72SArnaldo Carvalho de Melo 6472dd6d8a1SAdrian Hunter static void snapshot_sig_handler(int sig); 6482dd6d8a1SAdrian Hunter 64946bc29b9SAdrian Hunter int __weak 65046bc29b9SAdrian Hunter perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused, 65146bc29b9SAdrian Hunter struct perf_tool *tool __maybe_unused, 65246bc29b9SAdrian Hunter perf_event__handler_t process __maybe_unused, 65346bc29b9SAdrian Hunter struct machine *machine __maybe_unused) 65446bc29b9SAdrian Hunter { 65546bc29b9SAdrian Hunter return 0; 65646bc29b9SAdrian Hunter } 65746bc29b9SAdrian Hunter 658c45c86ebSWang Nan static int record__synthesize(struct record *rec) 659c45c86ebSWang Nan { 660c45c86ebSWang Nan struct perf_session *session = rec->session; 661c45c86ebSWang Nan struct machine *machine = &session->machines.host; 662c45c86ebSWang Nan struct perf_data_file *file = &rec->file; 663c45c86ebSWang Nan struct record_opts *opts = &rec->opts; 664c45c86ebSWang Nan struct perf_tool *tool = &rec->tool; 665c45c86ebSWang Nan int fd = perf_data_file__fd(file); 666c45c86ebSWang Nan int err = 0; 667c45c86ebSWang Nan 668c45c86ebSWang Nan if (file->is_pipe) { 669c45c86ebSWang Nan err = perf_event__synthesize_attrs(tool, session, 670c45c86ebSWang Nan process_synthesized_event); 671c45c86ebSWang Nan if (err < 0) { 672c45c86ebSWang Nan pr_err("Couldn't synthesize attrs.\n"); 673c45c86ebSWang Nan goto out; 674c45c86ebSWang Nan } 675c45c86ebSWang Nan 676c45c86ebSWang Nan if (have_tracepoints(&rec->evlist->entries)) { 677c45c86ebSWang Nan /* 678c45c86ebSWang Nan * FIXME err <= 0 here actually means that 679c45c86ebSWang Nan * there were no tracepoints so its not really 680c45c86ebSWang Nan * an error, just that we don't need to 681c45c86ebSWang Nan * synthesize anything. We really have to 682c45c86ebSWang Nan * return this more properly and also 683c45c86ebSWang Nan * propagate errors that now are calling die() 684c45c86ebSWang Nan */ 685c45c86ebSWang Nan err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist, 686c45c86ebSWang Nan process_synthesized_event); 687c45c86ebSWang Nan if (err <= 0) { 688c45c86ebSWang Nan pr_err("Couldn't record tracing data.\n"); 689c45c86ebSWang Nan goto out; 690c45c86ebSWang Nan } 691c45c86ebSWang Nan rec->bytes_written += err; 692c45c86ebSWang Nan } 693c45c86ebSWang Nan } 694c45c86ebSWang Nan 69546bc29b9SAdrian Hunter err = perf_event__synth_time_conv(rec->evlist->mmap[0].base, tool, 69646bc29b9SAdrian Hunter process_synthesized_event, machine); 69746bc29b9SAdrian Hunter if (err) 69846bc29b9SAdrian Hunter goto out; 69946bc29b9SAdrian Hunter 700c45c86ebSWang Nan if (rec->opts.full_auxtrace) { 701c45c86ebSWang Nan err = perf_event__synthesize_auxtrace_info(rec->itr, tool, 702c45c86ebSWang Nan session, process_synthesized_event); 703c45c86ebSWang Nan if (err) 704c45c86ebSWang Nan goto out; 705c45c86ebSWang Nan } 706c45c86ebSWang Nan 707c45c86ebSWang Nan err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, 708c45c86ebSWang Nan machine); 709c45c86ebSWang Nan WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n" 710c45c86ebSWang Nan "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 711c45c86ebSWang Nan "Check /proc/kallsyms permission or run as root.\n"); 712c45c86ebSWang Nan 713c45c86ebSWang Nan err = perf_event__synthesize_modules(tool, process_synthesized_event, 714c45c86ebSWang Nan machine); 715c45c86ebSWang Nan WARN_ONCE(err < 0, "Couldn't record kernel module information.\n" 716c45c86ebSWang Nan "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 717c45c86ebSWang Nan "Check /proc/modules permission or run as root.\n"); 718c45c86ebSWang Nan 719c45c86ebSWang Nan if (perf_guest) { 720c45c86ebSWang Nan machines__process_guests(&session->machines, 721c45c86ebSWang Nan perf_event__synthesize_guest_os, tool); 722c45c86ebSWang Nan } 723c45c86ebSWang Nan 724c45c86ebSWang Nan err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads, 725c45c86ebSWang Nan process_synthesized_event, opts->sample_address, 726c45c86ebSWang Nan opts->proc_map_timeout); 727c45c86ebSWang Nan out: 728c45c86ebSWang Nan return err; 729c45c86ebSWang Nan } 730c45c86ebSWang Nan 7318c6f45a7SArnaldo Carvalho de Melo static int __cmd_record(struct record *rec, int argc, const char **argv) 73286470930SIngo Molnar { 73357706abcSDavid Ahern int err; 73445604710SNamhyung Kim int status = 0; 7358b412664SPeter Zijlstra unsigned long waking = 0; 73646be604bSZhang, Yanmin const bool forks = argc > 0; 73723346f21SArnaldo Carvalho de Melo struct machine *machine; 73845694aa7SArnaldo Carvalho de Melo struct perf_tool *tool = &rec->tool; 739b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &rec->opts; 740f5fc1412SJiri Olsa struct perf_data_file *file = &rec->file; 741d20deb64SArnaldo Carvalho de Melo struct perf_session *session; 7426dcf45efSArnaldo Carvalho de Melo bool disabled = false, draining = false; 74342aa276fSNamhyung Kim int fd; 74486470930SIngo Molnar 745d20deb64SArnaldo Carvalho de Melo rec->progname = argv[0]; 74633e49ea7SAndi Kleen 74745604710SNamhyung Kim atexit(record__sig_exit); 748f5970550SPeter Zijlstra signal(SIGCHLD, sig_handler); 749f5970550SPeter Zijlstra signal(SIGINT, sig_handler); 750804f7ac7SDavid Ahern signal(SIGTERM, sig_handler); 751c0bdc1c4SWang Nan 7523c1cb7e3SWang Nan if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) { 7532dd6d8a1SAdrian Hunter signal(SIGUSR2, snapshot_sig_handler); 7543c1cb7e3SWang Nan if (rec->opts.auxtrace_snapshot_mode) 7555f9cf599SWang Nan trigger_on(&auxtrace_snapshot_trigger); 7563c1cb7e3SWang Nan if (rec->switch_output) 7573c1cb7e3SWang Nan trigger_on(&switch_output_trigger); 758c0bdc1c4SWang Nan } else { 7592dd6d8a1SAdrian Hunter signal(SIGUSR2, SIG_IGN); 760c0bdc1c4SWang Nan } 761f5970550SPeter Zijlstra 762b7b61cbeSArnaldo Carvalho de Melo session = perf_session__new(file, false, tool); 76394c744b6SArnaldo Carvalho de Melo if (session == NULL) { 764ffa91880SAdrien BAK pr_err("Perf session creation failed.\n"); 765a9a70bbcSArnaldo Carvalho de Melo return -1; 766a9a70bbcSArnaldo Carvalho de Melo } 767a9a70bbcSArnaldo Carvalho de Melo 76842aa276fSNamhyung Kim fd = perf_data_file__fd(file); 769d20deb64SArnaldo Carvalho de Melo rec->session = session; 770d20deb64SArnaldo Carvalho de Melo 7718c6f45a7SArnaldo Carvalho de Melo record__init_features(rec); 772330aa675SStephane Eranian 773d4db3f16SArnaldo Carvalho de Melo if (forks) { 7743e2be2daSArnaldo Carvalho de Melo err = perf_evlist__prepare_workload(rec->evlist, &opts->target, 775f5fc1412SJiri Olsa argv, file->is_pipe, 776735f7e0bSArnaldo Carvalho de Melo workload_exec_failed_signal); 77735b9d88eSArnaldo Carvalho de Melo if (err < 0) { 77835b9d88eSArnaldo Carvalho de Melo pr_err("Couldn't run the workload!\n"); 77945604710SNamhyung Kim status = err; 78035b9d88eSArnaldo Carvalho de Melo goto out_delete_session; 781856e9660SPeter Zijlstra } 782856e9660SPeter Zijlstra } 783856e9660SPeter Zijlstra 7848c6f45a7SArnaldo Carvalho de Melo if (record__open(rec) != 0) { 7858d3eca20SDavid Ahern err = -1; 78645604710SNamhyung Kim goto out_child; 7878d3eca20SDavid Ahern } 78886470930SIngo Molnar 7898690a2a7SWang Nan err = bpf__apply_obj_config(); 7908690a2a7SWang Nan if (err) { 7918690a2a7SWang Nan char errbuf[BUFSIZ]; 7928690a2a7SWang Nan 7938690a2a7SWang Nan bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf)); 7948690a2a7SWang Nan pr_err("ERROR: Apply config to BPF failed: %s\n", 7958690a2a7SWang Nan errbuf); 7968690a2a7SWang Nan goto out_child; 7978690a2a7SWang Nan } 7988690a2a7SWang Nan 799cca8482cSAdrian Hunter /* 800cca8482cSAdrian Hunter * Normally perf_session__new would do this, but it doesn't have the 801cca8482cSAdrian Hunter * evlist. 802cca8482cSAdrian Hunter */ 803cca8482cSAdrian Hunter if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) { 804cca8482cSAdrian Hunter pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n"); 805cca8482cSAdrian Hunter rec->tool.ordered_events = false; 806cca8482cSAdrian Hunter } 807cca8482cSAdrian Hunter 8083e2be2daSArnaldo Carvalho de Melo if (!rec->evlist->nr_groups) 809a8bb559bSNamhyung Kim perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); 810a8bb559bSNamhyung Kim 811f5fc1412SJiri Olsa if (file->is_pipe) { 81242aa276fSNamhyung Kim err = perf_header__write_pipe(fd); 813529870e3STom Zanussi if (err < 0) 81445604710SNamhyung Kim goto out_child; 815563aecb2SJiri Olsa } else { 81642aa276fSNamhyung Kim err = perf_session__write_header(session, rec->evlist, fd, false); 817d5eed904SArnaldo Carvalho de Melo if (err < 0) 81845604710SNamhyung Kim goto out_child; 819d5eed904SArnaldo Carvalho de Melo } 8207c6a1c65SPeter Zijlstra 821d3665498SDavid Ahern if (!rec->no_buildid 822e20960c0SRobert Richter && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) { 823d3665498SDavid Ahern pr_err("Couldn't generate buildids. " 824e20960c0SRobert Richter "Use --no-buildid to profile anyway.\n"); 8258d3eca20SDavid Ahern err = -1; 82645604710SNamhyung Kim goto out_child; 827e20960c0SRobert Richter } 828e20960c0SRobert Richter 82934ba5122SArnaldo Carvalho de Melo machine = &session->machines.host; 830743eb868SArnaldo Carvalho de Melo 831c45c86ebSWang Nan err = record__synthesize(rec); 832c45c86ebSWang Nan if (err < 0) 83345604710SNamhyung Kim goto out_child; 8348d3eca20SDavid Ahern 835d20deb64SArnaldo Carvalho de Melo if (rec->realtime_prio) { 83686470930SIngo Molnar struct sched_param param; 83786470930SIngo Molnar 838d20deb64SArnaldo Carvalho de Melo param.sched_priority = rec->realtime_prio; 83986470930SIngo Molnar if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { 8406beba7adSArnaldo Carvalho de Melo pr_err("Could not set realtime priority.\n"); 8418d3eca20SDavid Ahern err = -1; 84245604710SNamhyung Kim goto out_child; 84386470930SIngo Molnar } 84486470930SIngo Molnar } 84586470930SIngo Molnar 846774cb499SJiri Olsa /* 847774cb499SJiri Olsa * When perf is starting the traced process, all the events 848774cb499SJiri Olsa * (apart from group members) have enable_on_exec=1 set, 849774cb499SJiri Olsa * so don't spoil it by prematurely enabling them. 850774cb499SJiri Olsa */ 8516619a53eSAndi Kleen if (!target__none(&opts->target) && !opts->initial_delay) 8523e2be2daSArnaldo Carvalho de Melo perf_evlist__enable(rec->evlist); 853764e16a3SDavid Ahern 854856e9660SPeter Zijlstra /* 855856e9660SPeter Zijlstra * Let the child rip 856856e9660SPeter Zijlstra */ 857e803cf97SNamhyung Kim if (forks) { 858e5bed564SNamhyung Kim union perf_event *event; 859e5bed564SNamhyung Kim 860e5bed564SNamhyung Kim event = malloc(sizeof(event->comm) + machine->id_hdr_size); 861e5bed564SNamhyung Kim if (event == NULL) { 862e5bed564SNamhyung Kim err = -ENOMEM; 863e5bed564SNamhyung Kim goto out_child; 864e5bed564SNamhyung Kim } 865e5bed564SNamhyung Kim 866e803cf97SNamhyung Kim /* 867e803cf97SNamhyung Kim * Some H/W events are generated before COMM event 868e803cf97SNamhyung Kim * which is emitted during exec(), so perf script 869e803cf97SNamhyung Kim * cannot see a correct process name for those events. 870e803cf97SNamhyung Kim * Synthesize COMM event to prevent it. 871e803cf97SNamhyung Kim */ 872e5bed564SNamhyung Kim perf_event__synthesize_comm(tool, event, 873e803cf97SNamhyung Kim rec->evlist->workload.pid, 874e803cf97SNamhyung Kim process_synthesized_event, 875e803cf97SNamhyung Kim machine); 876e5bed564SNamhyung Kim free(event); 877e803cf97SNamhyung Kim 8783e2be2daSArnaldo Carvalho de Melo perf_evlist__start_workload(rec->evlist); 879e803cf97SNamhyung Kim } 880856e9660SPeter Zijlstra 8816619a53eSAndi Kleen if (opts->initial_delay) { 8826619a53eSAndi Kleen usleep(opts->initial_delay * 1000); 8836619a53eSAndi Kleen perf_evlist__enable(rec->evlist); 8846619a53eSAndi Kleen } 8856619a53eSAndi Kleen 8865f9cf599SWang Nan trigger_ready(&auxtrace_snapshot_trigger); 8873c1cb7e3SWang Nan trigger_ready(&switch_output_trigger); 888649c48a9SPeter Zijlstra for (;;) { 8899f065194SYang Shi unsigned long long hits = rec->samples; 89086470930SIngo Molnar 8918c6f45a7SArnaldo Carvalho de Melo if (record__mmap_read_all(rec) < 0) { 8925f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 8933c1cb7e3SWang Nan trigger_error(&switch_output_trigger); 8948d3eca20SDavid Ahern err = -1; 89545604710SNamhyung Kim goto out_child; 8968d3eca20SDavid Ahern } 89786470930SIngo Molnar 8982dd6d8a1SAdrian Hunter if (auxtrace_record__snapshot_started) { 8992dd6d8a1SAdrian Hunter auxtrace_record__snapshot_started = 0; 9005f9cf599SWang Nan if (!trigger_is_error(&auxtrace_snapshot_trigger)) 9012dd6d8a1SAdrian Hunter record__read_auxtrace_snapshot(rec); 9025f9cf599SWang Nan if (trigger_is_error(&auxtrace_snapshot_trigger)) { 9032dd6d8a1SAdrian Hunter pr_err("AUX area tracing snapshot failed\n"); 9042dd6d8a1SAdrian Hunter err = -1; 9052dd6d8a1SAdrian Hunter goto out_child; 9062dd6d8a1SAdrian Hunter } 9072dd6d8a1SAdrian Hunter } 9082dd6d8a1SAdrian Hunter 9093c1cb7e3SWang Nan if (trigger_is_hit(&switch_output_trigger)) { 9103c1cb7e3SWang Nan trigger_ready(&switch_output_trigger); 9113c1cb7e3SWang Nan 9123c1cb7e3SWang Nan if (!quiet) 9133c1cb7e3SWang Nan fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n", 9143c1cb7e3SWang Nan waking); 9153c1cb7e3SWang Nan waking = 0; 9163c1cb7e3SWang Nan fd = record__switch_output(rec, false); 9173c1cb7e3SWang Nan if (fd < 0) { 9183c1cb7e3SWang Nan pr_err("Failed to switch to new file\n"); 9193c1cb7e3SWang Nan trigger_error(&switch_output_trigger); 9203c1cb7e3SWang Nan err = fd; 9213c1cb7e3SWang Nan goto out_child; 9223c1cb7e3SWang Nan } 9233c1cb7e3SWang Nan } 9243c1cb7e3SWang Nan 925d20deb64SArnaldo Carvalho de Melo if (hits == rec->samples) { 9266dcf45efSArnaldo Carvalho de Melo if (done || draining) 927649c48a9SPeter Zijlstra break; 928f66a889dSArnaldo Carvalho de Melo err = perf_evlist__poll(rec->evlist, -1); 929a515114fSJiri Olsa /* 930a515114fSJiri Olsa * Propagate error, only if there's any. Ignore positive 931a515114fSJiri Olsa * number of returned events and interrupt error. 932a515114fSJiri Olsa */ 933a515114fSJiri Olsa if (err > 0 || (err < 0 && errno == EINTR)) 93445604710SNamhyung Kim err = 0; 9358b412664SPeter Zijlstra waking++; 9366dcf45efSArnaldo Carvalho de Melo 9376dcf45efSArnaldo Carvalho de Melo if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0) 9386dcf45efSArnaldo Carvalho de Melo draining = true; 9398b412664SPeter Zijlstra } 9408b412664SPeter Zijlstra 941774cb499SJiri Olsa /* 942774cb499SJiri Olsa * When perf is starting the traced process, at the end events 943774cb499SJiri Olsa * die with the process and we wait for that. Thus no need to 944774cb499SJiri Olsa * disable events in this case. 945774cb499SJiri Olsa */ 946602ad878SArnaldo Carvalho de Melo if (done && !disabled && !target__none(&opts->target)) { 9475f9cf599SWang Nan trigger_off(&auxtrace_snapshot_trigger); 9483e2be2daSArnaldo Carvalho de Melo perf_evlist__disable(rec->evlist); 9492711926aSJiri Olsa disabled = true; 9502711926aSJiri Olsa } 9518b412664SPeter Zijlstra } 9525f9cf599SWang Nan trigger_off(&auxtrace_snapshot_trigger); 9533c1cb7e3SWang Nan trigger_off(&switch_output_trigger); 9548b412664SPeter Zijlstra 955f33cbe72SArnaldo Carvalho de Melo if (forks && workload_exec_errno) { 95635550da3SMasami Hiramatsu char msg[STRERR_BUFSIZE]; 957f33cbe72SArnaldo Carvalho de Melo const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg)); 958f33cbe72SArnaldo Carvalho de Melo pr_err("Workload failed: %s\n", emsg); 959f33cbe72SArnaldo Carvalho de Melo err = -1; 96045604710SNamhyung Kim goto out_child; 961f33cbe72SArnaldo Carvalho de Melo } 962f33cbe72SArnaldo Carvalho de Melo 963e3d59112SNamhyung Kim if (!quiet) 9648b412664SPeter Zijlstra fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); 96586470930SIngo Molnar 96645604710SNamhyung Kim out_child: 96745604710SNamhyung Kim if (forks) { 96845604710SNamhyung Kim int exit_status; 96945604710SNamhyung Kim 97045604710SNamhyung Kim if (!child_finished) 97145604710SNamhyung Kim kill(rec->evlist->workload.pid, SIGTERM); 97245604710SNamhyung Kim 97345604710SNamhyung Kim wait(&exit_status); 97445604710SNamhyung Kim 97545604710SNamhyung Kim if (err < 0) 97645604710SNamhyung Kim status = err; 97745604710SNamhyung Kim else if (WIFEXITED(exit_status)) 97845604710SNamhyung Kim status = WEXITSTATUS(exit_status); 97945604710SNamhyung Kim else if (WIFSIGNALED(exit_status)) 98045604710SNamhyung Kim signr = WTERMSIG(exit_status); 98145604710SNamhyung Kim } else 98245604710SNamhyung Kim status = err; 98345604710SNamhyung Kim 984e3d59112SNamhyung Kim /* this will be recalculated during process_buildids() */ 985e3d59112SNamhyung Kim rec->samples = 0; 986e3d59112SNamhyung Kim 987ecfd7a9cSWang Nan if (!err) { 988ecfd7a9cSWang Nan if (!rec->timestamp_filename) { 989e1ab48baSWang Nan record__finish_output(rec); 990ecfd7a9cSWang Nan } else { 991ecfd7a9cSWang Nan fd = record__switch_output(rec, true); 992ecfd7a9cSWang Nan if (fd < 0) { 993ecfd7a9cSWang Nan status = fd; 994ecfd7a9cSWang Nan goto out_delete_session; 995ecfd7a9cSWang Nan } 996ecfd7a9cSWang Nan } 997ecfd7a9cSWang Nan } 99839d17dacSArnaldo Carvalho de Melo 999e3d59112SNamhyung Kim if (!err && !quiet) { 1000e3d59112SNamhyung Kim char samples[128]; 1001ecfd7a9cSWang Nan const char *postfix = rec->timestamp_filename ? 1002ecfd7a9cSWang Nan ".<timestamp>" : ""; 1003e3d59112SNamhyung Kim 1004ef149c25SAdrian Hunter if (rec->samples && !rec->opts.full_auxtrace) 1005e3d59112SNamhyung Kim scnprintf(samples, sizeof(samples), 1006e3d59112SNamhyung Kim " (%" PRIu64 " samples)", rec->samples); 1007e3d59112SNamhyung Kim else 1008e3d59112SNamhyung Kim samples[0] = '\0'; 1009e3d59112SNamhyung Kim 1010ecfd7a9cSWang Nan fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n", 1011e3d59112SNamhyung Kim perf_data_file__size(file) / 1024.0 / 1024.0, 1012ecfd7a9cSWang Nan file->path, postfix, samples); 1013e3d59112SNamhyung Kim } 1014e3d59112SNamhyung Kim 101539d17dacSArnaldo Carvalho de Melo out_delete_session: 101639d17dacSArnaldo Carvalho de Melo perf_session__delete(session); 101745604710SNamhyung Kim return status; 101886470930SIngo Molnar } 101986470930SIngo Molnar 10200883e820SArnaldo Carvalho de Melo static void callchain_debug(struct callchain_param *callchain) 102109b0fd45SJiri Olsa { 1022aad2b21cSKan Liang static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" }; 1023a601fdffSJiri Olsa 10240883e820SArnaldo Carvalho de Melo pr_debug("callchain: type %s\n", str[callchain->record_mode]); 102526d33022SJiri Olsa 10260883e820SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_DWARF) 102709b0fd45SJiri Olsa pr_debug("callchain: stack dump size %d\n", 10280883e820SArnaldo Carvalho de Melo callchain->dump_size); 10290883e820SArnaldo Carvalho de Melo } 10300883e820SArnaldo Carvalho de Melo 10310883e820SArnaldo Carvalho de Melo int record_opts__parse_callchain(struct record_opts *record, 10320883e820SArnaldo Carvalho de Melo struct callchain_param *callchain, 10330883e820SArnaldo Carvalho de Melo const char *arg, bool unset) 10340883e820SArnaldo Carvalho de Melo { 10350883e820SArnaldo Carvalho de Melo int ret; 10360883e820SArnaldo Carvalho de Melo callchain->enabled = !unset; 10370883e820SArnaldo Carvalho de Melo 10380883e820SArnaldo Carvalho de Melo /* --no-call-graph */ 10390883e820SArnaldo Carvalho de Melo if (unset) { 10400883e820SArnaldo Carvalho de Melo callchain->record_mode = CALLCHAIN_NONE; 10410883e820SArnaldo Carvalho de Melo pr_debug("callchain: disabled\n"); 10420883e820SArnaldo Carvalho de Melo return 0; 10430883e820SArnaldo Carvalho de Melo } 10440883e820SArnaldo Carvalho de Melo 10450883e820SArnaldo Carvalho de Melo ret = parse_callchain_record_opt(arg, callchain); 10460883e820SArnaldo Carvalho de Melo if (!ret) { 10470883e820SArnaldo Carvalho de Melo /* Enable data address sampling for DWARF unwind. */ 10480883e820SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_DWARF) 10490883e820SArnaldo Carvalho de Melo record->sample_address = true; 10500883e820SArnaldo Carvalho de Melo callchain_debug(callchain); 10510883e820SArnaldo Carvalho de Melo } 10520883e820SArnaldo Carvalho de Melo 10530883e820SArnaldo Carvalho de Melo return ret; 105409b0fd45SJiri Olsa } 105509b0fd45SJiri Olsa 1056c421e80bSKan Liang int record_parse_callchain_opt(const struct option *opt, 105709b0fd45SJiri Olsa const char *arg, 105809b0fd45SJiri Olsa int unset) 105909b0fd45SJiri Olsa { 10600883e820SArnaldo Carvalho de Melo return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset); 106126d33022SJiri Olsa } 106226d33022SJiri Olsa 1063c421e80bSKan Liang int record_callchain_opt(const struct option *opt, 106409b0fd45SJiri Olsa const char *arg __maybe_unused, 106509b0fd45SJiri Olsa int unset __maybe_unused) 106609b0fd45SJiri Olsa { 10672ddd5c04SArnaldo Carvalho de Melo struct callchain_param *callchain = opt->value; 1068c421e80bSKan Liang 10692ddd5c04SArnaldo Carvalho de Melo callchain->enabled = true; 107009b0fd45SJiri Olsa 10712ddd5c04SArnaldo Carvalho de Melo if (callchain->record_mode == CALLCHAIN_NONE) 10722ddd5c04SArnaldo Carvalho de Melo callchain->record_mode = CALLCHAIN_FP; 1073eb853e80SJiri Olsa 10742ddd5c04SArnaldo Carvalho de Melo callchain_debug(callchain); 107509b0fd45SJiri Olsa return 0; 107609b0fd45SJiri Olsa } 107709b0fd45SJiri Olsa 1078eb853e80SJiri Olsa static int perf_record_config(const char *var, const char *value, void *cb) 1079eb853e80SJiri Olsa { 10807a29c087SNamhyung Kim struct record *rec = cb; 10817a29c087SNamhyung Kim 10827a29c087SNamhyung Kim if (!strcmp(var, "record.build-id")) { 10837a29c087SNamhyung Kim if (!strcmp(value, "cache")) 10847a29c087SNamhyung Kim rec->no_buildid_cache = false; 10857a29c087SNamhyung Kim else if (!strcmp(value, "no-cache")) 10867a29c087SNamhyung Kim rec->no_buildid_cache = true; 10877a29c087SNamhyung Kim else if (!strcmp(value, "skip")) 10887a29c087SNamhyung Kim rec->no_buildid = true; 10897a29c087SNamhyung Kim else 10907a29c087SNamhyung Kim return -1; 10917a29c087SNamhyung Kim return 0; 10927a29c087SNamhyung Kim } 1093eb853e80SJiri Olsa if (!strcmp(var, "record.call-graph")) 10945a2e5e85SNamhyung Kim var = "call-graph.record-mode"; /* fall-through */ 1095eb853e80SJiri Olsa 1096eb853e80SJiri Olsa return perf_default_config(var, value, cb); 1097eb853e80SJiri Olsa } 1098eb853e80SJiri Olsa 1099814c8c38SPeter Zijlstra struct clockid_map { 1100814c8c38SPeter Zijlstra const char *name; 1101814c8c38SPeter Zijlstra int clockid; 1102814c8c38SPeter Zijlstra }; 1103814c8c38SPeter Zijlstra 1104814c8c38SPeter Zijlstra #define CLOCKID_MAP(n, c) \ 1105814c8c38SPeter Zijlstra { .name = n, .clockid = (c), } 1106814c8c38SPeter Zijlstra 1107814c8c38SPeter Zijlstra #define CLOCKID_END { .name = NULL, } 1108814c8c38SPeter Zijlstra 1109814c8c38SPeter Zijlstra 1110814c8c38SPeter Zijlstra /* 1111814c8c38SPeter Zijlstra * Add the missing ones, we need to build on many distros... 1112814c8c38SPeter Zijlstra */ 1113814c8c38SPeter Zijlstra #ifndef CLOCK_MONOTONIC_RAW 1114814c8c38SPeter Zijlstra #define CLOCK_MONOTONIC_RAW 4 1115814c8c38SPeter Zijlstra #endif 1116814c8c38SPeter Zijlstra #ifndef CLOCK_BOOTTIME 1117814c8c38SPeter Zijlstra #define CLOCK_BOOTTIME 7 1118814c8c38SPeter Zijlstra #endif 1119814c8c38SPeter Zijlstra #ifndef CLOCK_TAI 1120814c8c38SPeter Zijlstra #define CLOCK_TAI 11 1121814c8c38SPeter Zijlstra #endif 1122814c8c38SPeter Zijlstra 1123814c8c38SPeter Zijlstra static const struct clockid_map clockids[] = { 1124814c8c38SPeter Zijlstra /* available for all events, NMI safe */ 1125814c8c38SPeter Zijlstra CLOCKID_MAP("monotonic", CLOCK_MONOTONIC), 1126814c8c38SPeter Zijlstra CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW), 1127814c8c38SPeter Zijlstra 1128814c8c38SPeter Zijlstra /* available for some events */ 1129814c8c38SPeter Zijlstra CLOCKID_MAP("realtime", CLOCK_REALTIME), 1130814c8c38SPeter Zijlstra CLOCKID_MAP("boottime", CLOCK_BOOTTIME), 1131814c8c38SPeter Zijlstra CLOCKID_MAP("tai", CLOCK_TAI), 1132814c8c38SPeter Zijlstra 1133814c8c38SPeter Zijlstra /* available for the lazy */ 1134814c8c38SPeter Zijlstra CLOCKID_MAP("mono", CLOCK_MONOTONIC), 1135814c8c38SPeter Zijlstra CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW), 1136814c8c38SPeter Zijlstra CLOCKID_MAP("real", CLOCK_REALTIME), 1137814c8c38SPeter Zijlstra CLOCKID_MAP("boot", CLOCK_BOOTTIME), 1138814c8c38SPeter Zijlstra 1139814c8c38SPeter Zijlstra CLOCKID_END, 1140814c8c38SPeter Zijlstra }; 1141814c8c38SPeter Zijlstra 1142814c8c38SPeter Zijlstra static int parse_clockid(const struct option *opt, const char *str, int unset) 1143814c8c38SPeter Zijlstra { 1144814c8c38SPeter Zijlstra struct record_opts *opts = (struct record_opts *)opt->value; 1145814c8c38SPeter Zijlstra const struct clockid_map *cm; 1146814c8c38SPeter Zijlstra const char *ostr = str; 1147814c8c38SPeter Zijlstra 1148814c8c38SPeter Zijlstra if (unset) { 1149814c8c38SPeter Zijlstra opts->use_clockid = 0; 1150814c8c38SPeter Zijlstra return 0; 1151814c8c38SPeter Zijlstra } 1152814c8c38SPeter Zijlstra 1153814c8c38SPeter Zijlstra /* no arg passed */ 1154814c8c38SPeter Zijlstra if (!str) 1155814c8c38SPeter Zijlstra return 0; 1156814c8c38SPeter Zijlstra 1157814c8c38SPeter Zijlstra /* no setting it twice */ 1158814c8c38SPeter Zijlstra if (opts->use_clockid) 1159814c8c38SPeter Zijlstra return -1; 1160814c8c38SPeter Zijlstra 1161814c8c38SPeter Zijlstra opts->use_clockid = true; 1162814c8c38SPeter Zijlstra 1163814c8c38SPeter Zijlstra /* if its a number, we're done */ 1164814c8c38SPeter Zijlstra if (sscanf(str, "%d", &opts->clockid) == 1) 1165814c8c38SPeter Zijlstra return 0; 1166814c8c38SPeter Zijlstra 1167814c8c38SPeter Zijlstra /* allow a "CLOCK_" prefix to the name */ 1168814c8c38SPeter Zijlstra if (!strncasecmp(str, "CLOCK_", 6)) 1169814c8c38SPeter Zijlstra str += 6; 1170814c8c38SPeter Zijlstra 1171814c8c38SPeter Zijlstra for (cm = clockids; cm->name; cm++) { 1172814c8c38SPeter Zijlstra if (!strcasecmp(str, cm->name)) { 1173814c8c38SPeter Zijlstra opts->clockid = cm->clockid; 1174814c8c38SPeter Zijlstra return 0; 1175814c8c38SPeter Zijlstra } 1176814c8c38SPeter Zijlstra } 1177814c8c38SPeter Zijlstra 1178814c8c38SPeter Zijlstra opts->use_clockid = false; 1179814c8c38SPeter Zijlstra ui__warning("unknown clockid %s, check man page\n", ostr); 1180814c8c38SPeter Zijlstra return -1; 1181814c8c38SPeter Zijlstra } 1182814c8c38SPeter Zijlstra 1183e9db1310SAdrian Hunter static int record__parse_mmap_pages(const struct option *opt, 1184e9db1310SAdrian Hunter const char *str, 1185e9db1310SAdrian Hunter int unset __maybe_unused) 1186e9db1310SAdrian Hunter { 1187e9db1310SAdrian Hunter struct record_opts *opts = opt->value; 1188e9db1310SAdrian Hunter char *s, *p; 1189e9db1310SAdrian Hunter unsigned int mmap_pages; 1190e9db1310SAdrian Hunter int ret; 1191e9db1310SAdrian Hunter 1192e9db1310SAdrian Hunter if (!str) 1193e9db1310SAdrian Hunter return -EINVAL; 1194e9db1310SAdrian Hunter 1195e9db1310SAdrian Hunter s = strdup(str); 1196e9db1310SAdrian Hunter if (!s) 1197e9db1310SAdrian Hunter return -ENOMEM; 1198e9db1310SAdrian Hunter 1199e9db1310SAdrian Hunter p = strchr(s, ','); 1200e9db1310SAdrian Hunter if (p) 1201e9db1310SAdrian Hunter *p = '\0'; 1202e9db1310SAdrian Hunter 1203e9db1310SAdrian Hunter if (*s) { 1204e9db1310SAdrian Hunter ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s); 1205e9db1310SAdrian Hunter if (ret) 1206e9db1310SAdrian Hunter goto out_free; 1207e9db1310SAdrian Hunter opts->mmap_pages = mmap_pages; 1208e9db1310SAdrian Hunter } 1209e9db1310SAdrian Hunter 1210e9db1310SAdrian Hunter if (!p) { 1211e9db1310SAdrian Hunter ret = 0; 1212e9db1310SAdrian Hunter goto out_free; 1213e9db1310SAdrian Hunter } 1214e9db1310SAdrian Hunter 1215e9db1310SAdrian Hunter ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1); 1216e9db1310SAdrian Hunter if (ret) 1217e9db1310SAdrian Hunter goto out_free; 1218e9db1310SAdrian Hunter 1219e9db1310SAdrian Hunter opts->auxtrace_mmap_pages = mmap_pages; 1220e9db1310SAdrian Hunter 1221e9db1310SAdrian Hunter out_free: 1222e9db1310SAdrian Hunter free(s); 1223e9db1310SAdrian Hunter return ret; 1224e9db1310SAdrian Hunter } 1225e9db1310SAdrian Hunter 1226e5b2c207SNamhyung Kim static const char * const __record_usage[] = { 122786470930SIngo Molnar "perf record [<options>] [<command>]", 122886470930SIngo Molnar "perf record [<options>] -- <command> [<options>]", 122986470930SIngo Molnar NULL 123086470930SIngo Molnar }; 1231e5b2c207SNamhyung Kim const char * const *record_usage = __record_usage; 123286470930SIngo Molnar 1233d20deb64SArnaldo Carvalho de Melo /* 12348c6f45a7SArnaldo Carvalho de Melo * XXX Ideally would be local to cmd_record() and passed to a record__new 12358c6f45a7SArnaldo Carvalho de Melo * because we need to have access to it in record__exit, that is called 1236d20deb64SArnaldo Carvalho de Melo * after cmd_record() exits, but since record_options need to be accessible to 1237d20deb64SArnaldo Carvalho de Melo * builtin-script, leave it here. 1238d20deb64SArnaldo Carvalho de Melo * 1239d20deb64SArnaldo Carvalho de Melo * At least we don't ouch it in all the other functions here directly. 1240d20deb64SArnaldo Carvalho de Melo * 1241d20deb64SArnaldo Carvalho de Melo * Just say no to tons of global variables, sigh. 1242d20deb64SArnaldo Carvalho de Melo */ 12438c6f45a7SArnaldo Carvalho de Melo static struct record record = { 1244d20deb64SArnaldo Carvalho de Melo .opts = { 12458affc2b8SAndi Kleen .sample_time = true, 1246d20deb64SArnaldo Carvalho de Melo .mmap_pages = UINT_MAX, 1247d20deb64SArnaldo Carvalho de Melo .user_freq = UINT_MAX, 1248d20deb64SArnaldo Carvalho de Melo .user_interval = ULLONG_MAX, 1249447a6013SArnaldo Carvalho de Melo .freq = 4000, 1250d1cb9fceSNamhyung Kim .target = { 1251d1cb9fceSNamhyung Kim .uses_mmap = true, 12523aa5939dSAdrian Hunter .default_per_cpu = true, 1253d1cb9fceSNamhyung Kim }, 12549d9cad76SKan Liang .proc_map_timeout = 500, 1255d20deb64SArnaldo Carvalho de Melo }, 1256e3d59112SNamhyung Kim .tool = { 1257e3d59112SNamhyung Kim .sample = process_sample_event, 1258e3d59112SNamhyung Kim .fork = perf_event__process_fork, 1259cca8482cSAdrian Hunter .exit = perf_event__process_exit, 1260e3d59112SNamhyung Kim .comm = perf_event__process_comm, 1261e3d59112SNamhyung Kim .mmap = perf_event__process_mmap, 1262e3d59112SNamhyung Kim .mmap2 = perf_event__process_mmap2, 1263cca8482cSAdrian Hunter .ordered_events = true, 1264e3d59112SNamhyung Kim }, 1265d20deb64SArnaldo Carvalho de Melo }; 12667865e817SFrederic Weisbecker 126776a26549SNamhyung Kim const char record_callchain_help[] = CALLCHAIN_RECORD_HELP 126876a26549SNamhyung Kim "\n\t\t\t\tDefault: fp"; 126961eaa3beSArnaldo Carvalho de Melo 1270d20deb64SArnaldo Carvalho de Melo /* 1271d20deb64SArnaldo Carvalho de Melo * XXX Will stay a global variable till we fix builtin-script.c to stop messing 1272d20deb64SArnaldo Carvalho de Melo * with it and switch to use the library functions in perf_evlist that came 1273b4006796SArnaldo Carvalho de Melo * from builtin-record.c, i.e. use record_opts, 1274d20deb64SArnaldo Carvalho de Melo * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record', 1275d20deb64SArnaldo Carvalho de Melo * using pipes, etc. 1276d20deb64SArnaldo Carvalho de Melo */ 1277e5b2c207SNamhyung Kim struct option __record_options[] = { 1278d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &record.evlist, "event", 127986470930SIngo Molnar "event selector. use 'perf list' to list available events", 1280f120f9d5SJiri Olsa parse_events_option), 1281d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK(0, "filter", &record.evlist, "filter", 1282c171b552SLi Zefan "event filter", parse_filter), 12834ba1faa1SWang Nan OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist, 12844ba1faa1SWang Nan NULL, "don't record events from perf itself", 12854ba1faa1SWang Nan exclude_perf), 1286bea03405SNamhyung Kim OPT_STRING('p', "pid", &record.opts.target.pid, "pid", 1287d6d901c2SZhang, Yanmin "record events on existing process id"), 1288bea03405SNamhyung Kim OPT_STRING('t', "tid", &record.opts.target.tid, "tid", 1289d6d901c2SZhang, Yanmin "record events on existing thread id"), 1290d20deb64SArnaldo Carvalho de Melo OPT_INTEGER('r', "realtime", &record.realtime_prio, 129186470930SIngo Molnar "collect data with this RT SCHED_FIFO priority"), 1292509051eaSArnaldo Carvalho de Melo OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering, 1293acac03faSKirill Smelkov "collect data without buffering"), 1294d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples, 1295daac07b2SFrederic Weisbecker "collect raw sample records from all opened counters"), 1296bea03405SNamhyung Kim OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide, 129786470930SIngo Molnar "system-wide collection from all CPUs"), 1298bea03405SNamhyung Kim OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", 1299c45c6ea2SStephane Eranian "list of cpus to monitor"), 1300d20deb64SArnaldo Carvalho de Melo OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"), 1301f5fc1412SJiri Olsa OPT_STRING('o', "output", &record.file.path, "file", 130286470930SIngo Molnar "output file name"), 130369e7e5b0SAdrian Hunter OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit, 130469e7e5b0SAdrian Hunter &record.opts.no_inherit_set, 13052e6cdf99SStephane Eranian "child tasks do not inherit counters"), 1306d20deb64SArnaldo Carvalho de Melo OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"), 1307e9db1310SAdrian Hunter OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]", 1308e9db1310SAdrian Hunter "number of mmap data pages and AUX area tracing mmap pages", 1309e9db1310SAdrian Hunter record__parse_mmap_pages), 1310d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "group", &record.opts.group, 131143bece79SLin Ming "put the counters into a counter group"), 13122ddd5c04SArnaldo Carvalho de Melo OPT_CALLBACK_NOOPT('g', NULL, &callchain_param, 131309b0fd45SJiri Olsa NULL, "enables call-graph recording" , 131409b0fd45SJiri Olsa &record_callchain_opt), 131509b0fd45SJiri Olsa OPT_CALLBACK(0, "call-graph", &record.opts, 131676a26549SNamhyung Kim "record_mode[,record_size]", record_callchain_help, 131709b0fd45SJiri Olsa &record_parse_callchain_opt), 1318c0555642SIan Munsie OPT_INCR('v', "verbose", &verbose, 13193da297a6SIngo Molnar "be more verbose (show counter open errors, etc)"), 1320b44308f5SArnaldo Carvalho de Melo OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"), 1321d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat, 1322649c48a9SPeter Zijlstra "per thread counts"), 132356100321SPeter Zijlstra OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"), 13243abebc55SAdrian Hunter OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time, 13253abebc55SAdrian Hunter &record.opts.sample_time_set, 13263abebc55SAdrian Hunter "Record the sample timestamps"), 132756100321SPeter Zijlstra OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"), 1328d20deb64SArnaldo Carvalho de Melo OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples, 1329649c48a9SPeter Zijlstra "don't sample"), 1330d2db9a98SWang Nan OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache, 1331d2db9a98SWang Nan &record.no_buildid_cache_set, 1332a1ac1d3cSStephane Eranian "do not update the buildid cache"), 1333d2db9a98SWang Nan OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid, 1334d2db9a98SWang Nan &record.no_buildid_set, 1335baa2f6ceSArnaldo Carvalho de Melo "do not collect buildids in perf.data"), 1336d20deb64SArnaldo Carvalho de Melo OPT_CALLBACK('G', "cgroup", &record.evlist, "name", 1337023695d9SStephane Eranian "monitor event in cgroup name only", 1338023695d9SStephane Eranian parse_cgroups), 1339a6205a35SArnaldo Carvalho de Melo OPT_UINTEGER('D', "delay", &record.opts.initial_delay, 13406619a53eSAndi Kleen "ms to wait before starting measurement after program start"), 1341bea03405SNamhyung Kim OPT_STRING('u', "uid", &record.opts.target.uid_str, "user", 1342bea03405SNamhyung Kim "user to profile"), 1343a5aabdacSStephane Eranian 1344a5aabdacSStephane Eranian OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack, 1345a5aabdacSStephane Eranian "branch any", "sample any taken branches", 1346a5aabdacSStephane Eranian parse_branch_stack), 1347a5aabdacSStephane Eranian 1348a5aabdacSStephane Eranian OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack, 1349a5aabdacSStephane Eranian "branch filter mask", "branch stack filter modes", 1350bdfebd84SRoberto Agostino Vitillo parse_branch_stack), 135105484298SAndi Kleen OPT_BOOLEAN('W', "weight", &record.opts.sample_weight, 135205484298SAndi Kleen "sample by weight (on special events only)"), 1353475eeab9SAndi Kleen OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction, 1354475eeab9SAndi Kleen "sample transaction flags (special events only)"), 13553aa5939dSAdrian Hunter OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread, 13563aa5939dSAdrian Hunter "use per-thread mmaps"), 1357bcc84ec6SStephane Eranian OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register", 1358bcc84ec6SStephane Eranian "sample selected machine registers on interrupt," 1359bcc84ec6SStephane Eranian " use -I ? to list register names", parse_regs), 136085c273d2SAndi Kleen OPT_BOOLEAN(0, "running-time", &record.opts.running_time, 136185c273d2SAndi Kleen "Record running/enabled time of read (:S) events"), 1362814c8c38SPeter Zijlstra OPT_CALLBACK('k', "clockid", &record.opts, 1363814c8c38SPeter Zijlstra "clockid", "clockid to use for events, see clock_gettime()", 1364814c8c38SPeter Zijlstra parse_clockid), 13652dd6d8a1SAdrian Hunter OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts, 13662dd6d8a1SAdrian Hunter "opts", "AUX area tracing Snapshot Mode", ""), 13679d9cad76SKan Liang OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout, 13689d9cad76SKan Liang "per thread proc mmap processing timeout in ms"), 1369b757bb09SAdrian Hunter OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events, 1370b757bb09SAdrian Hunter "Record context switch events"), 137185723885SJiri Olsa OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel, 137285723885SJiri Olsa "Configure all used events to run in kernel space.", 137385723885SJiri Olsa PARSE_OPT_EXCLUSIVE), 137485723885SJiri Olsa OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user, 137585723885SJiri Olsa "Configure all used events to run in user space.", 137685723885SJiri Olsa PARSE_OPT_EXCLUSIVE), 137771dc2326SWang Nan OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", 137871dc2326SWang Nan "clang binary to use for compiling BPF scriptlets"), 137971dc2326SWang Nan OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", 138071dc2326SWang Nan "options passed to clang when compiling BPF scriptlets"), 13817efe0e03SHe Kuang OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, 13827efe0e03SHe Kuang "file", "vmlinux pathname"), 13836156681bSNamhyung Kim OPT_BOOLEAN(0, "buildid-all", &record.buildid_all, 13846156681bSNamhyung Kim "Record build-id of all DSOs regardless of hits"), 1385ecfd7a9cSWang Nan OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename, 1386ecfd7a9cSWang Nan "append timestamp to output filename"), 13873c1cb7e3SWang Nan OPT_BOOLEAN(0, "switch-output", &record.switch_output, 13883c1cb7e3SWang Nan "Switch output when receive SIGUSR2"), 138986470930SIngo Molnar OPT_END() 139086470930SIngo Molnar }; 139186470930SIngo Molnar 1392e5b2c207SNamhyung Kim struct option *record_options = __record_options; 1393e5b2c207SNamhyung Kim 13941d037ca1SIrina Tirdea int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) 139586470930SIngo Molnar { 1396ef149c25SAdrian Hunter int err; 13978c6f45a7SArnaldo Carvalho de Melo struct record *rec = &record; 139816ad2ffbSNamhyung Kim char errbuf[BUFSIZ]; 139986470930SIngo Molnar 140048e1cab1SWang Nan #ifndef HAVE_LIBBPF_SUPPORT 140148e1cab1SWang Nan # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c) 140248e1cab1SWang Nan set_nobuild('\0', "clang-path", true); 140348e1cab1SWang Nan set_nobuild('\0', "clang-opt", true); 140448e1cab1SWang Nan # undef set_nobuild 140548e1cab1SWang Nan #endif 140648e1cab1SWang Nan 14077efe0e03SHe Kuang #ifndef HAVE_BPF_PROLOGUE 14087efe0e03SHe Kuang # if !defined (HAVE_DWARF_SUPPORT) 14097efe0e03SHe Kuang # define REASON "NO_DWARF=1" 14107efe0e03SHe Kuang # elif !defined (HAVE_LIBBPF_SUPPORT) 14117efe0e03SHe Kuang # define REASON "NO_LIBBPF=1" 14127efe0e03SHe Kuang # else 14137efe0e03SHe Kuang # define REASON "this architecture doesn't support BPF prologue" 14147efe0e03SHe Kuang # endif 14157efe0e03SHe Kuang # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c) 14167efe0e03SHe Kuang set_nobuild('\0', "vmlinux", true); 14177efe0e03SHe Kuang # undef set_nobuild 14187efe0e03SHe Kuang # undef REASON 14197efe0e03SHe Kuang #endif 14207efe0e03SHe Kuang 14213e2be2daSArnaldo Carvalho de Melo rec->evlist = perf_evlist__new(); 14223e2be2daSArnaldo Carvalho de Melo if (rec->evlist == NULL) 1423361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1424361c99a6SArnaldo Carvalho de Melo 1425eb853e80SJiri Olsa perf_config(perf_record_config, rec); 1426eb853e80SJiri Olsa 1427bca647aaSTom Zanussi argc = parse_options(argc, argv, record_options, record_usage, 1428a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 1429602ad878SArnaldo Carvalho de Melo if (!argc && target__none(&rec->opts.target)) 1430bca647aaSTom Zanussi usage_with_options(record_usage, record_options); 143186470930SIngo Molnar 1432bea03405SNamhyung Kim if (nr_cgroups && !rec->opts.target.system_wide) { 1433c7118369SNamhyung Kim usage_with_options_msg(record_usage, record_options, 1434c7118369SNamhyung Kim "cgroup monitoring only available in system-wide mode"); 1435c7118369SNamhyung Kim 1436023695d9SStephane Eranian } 1437b757bb09SAdrian Hunter if (rec->opts.record_switch_events && 1438b757bb09SAdrian Hunter !perf_can_record_switch_events()) { 1439c7118369SNamhyung Kim ui__error("kernel does not support recording context switch events\n"); 1440c7118369SNamhyung Kim parse_options_usage(record_usage, record_options, "switch-events", 0); 1441c7118369SNamhyung Kim return -EINVAL; 1442b757bb09SAdrian Hunter } 1443023695d9SStephane Eranian 1444eca857abSWang Nan if (rec->switch_output) 1445eca857abSWang Nan rec->timestamp_filename = true; 1446eca857abSWang Nan 1447ef149c25SAdrian Hunter if (!rec->itr) { 1448ef149c25SAdrian Hunter rec->itr = auxtrace_record__init(rec->evlist, &err); 1449ef149c25SAdrian Hunter if (err) 1450ef149c25SAdrian Hunter return err; 1451ef149c25SAdrian Hunter } 1452ef149c25SAdrian Hunter 14532dd6d8a1SAdrian Hunter err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts, 14542dd6d8a1SAdrian Hunter rec->opts.auxtrace_snapshot_opts); 14552dd6d8a1SAdrian Hunter if (err) 14562dd6d8a1SAdrian Hunter return err; 14572dd6d8a1SAdrian Hunter 1458d7888573SWang Nan err = bpf__setup_stdout(rec->evlist); 1459d7888573SWang Nan if (err) { 1460d7888573SWang Nan bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf)); 1461d7888573SWang Nan pr_err("ERROR: Setup BPF stdout failed: %s\n", 1462d7888573SWang Nan errbuf); 1463d7888573SWang Nan return err; 1464d7888573SWang Nan } 1465d7888573SWang Nan 1466ef149c25SAdrian Hunter err = -ENOMEM; 1467ef149c25SAdrian Hunter 14680a7e6d1bSNamhyung Kim symbol__init(NULL); 1469baa2f6ceSArnaldo Carvalho de Melo 1470ec80fde7SArnaldo Carvalho de Melo if (symbol_conf.kptr_restrict) 1471646aaea6SArnaldo Carvalho de Melo pr_warning( 1472646aaea6SArnaldo Carvalho de Melo "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" 1473ec80fde7SArnaldo Carvalho de Melo "check /proc/sys/kernel/kptr_restrict.\n\n" 1474646aaea6SArnaldo Carvalho de Melo "Samples in kernel functions may not be resolved if a suitable vmlinux\n" 1475646aaea6SArnaldo Carvalho de Melo "file is not found in the buildid cache or in the vmlinux path.\n\n" 1476646aaea6SArnaldo Carvalho de Melo "Samples in kernel modules won't be resolved at all.\n\n" 1477646aaea6SArnaldo Carvalho de Melo "If some relocation was applied (e.g. kexec) symbols may be misresolved\n" 1478646aaea6SArnaldo Carvalho de Melo "even with a suitable vmlinux or kallsyms file.\n\n"); 1479ec80fde7SArnaldo Carvalho de Melo 14800c1d46a8SWang Nan if (rec->no_buildid_cache || rec->no_buildid) { 1481a1ac1d3cSStephane Eranian disable_buildid_cache(); 14820c1d46a8SWang Nan } else if (rec->switch_output) { 14830c1d46a8SWang Nan /* 14840c1d46a8SWang Nan * In 'perf record --switch-output', disable buildid 14850c1d46a8SWang Nan * generation by default to reduce data file switching 14860c1d46a8SWang Nan * overhead. Still generate buildid if they are required 14870c1d46a8SWang Nan * explicitly using 14880c1d46a8SWang Nan * 14890c1d46a8SWang Nan * perf record --signal-trigger --no-no-buildid \ 14900c1d46a8SWang Nan * --no-no-buildid-cache 14910c1d46a8SWang Nan * 14920c1d46a8SWang Nan * Following code equals to: 14930c1d46a8SWang Nan * 14940c1d46a8SWang Nan * if ((rec->no_buildid || !rec->no_buildid_set) && 14950c1d46a8SWang Nan * (rec->no_buildid_cache || !rec->no_buildid_cache_set)) 14960c1d46a8SWang Nan * disable_buildid_cache(); 14970c1d46a8SWang Nan */ 14980c1d46a8SWang Nan bool disable = true; 14990c1d46a8SWang Nan 15000c1d46a8SWang Nan if (rec->no_buildid_set && !rec->no_buildid) 15010c1d46a8SWang Nan disable = false; 15020c1d46a8SWang Nan if (rec->no_buildid_cache_set && !rec->no_buildid_cache) 15030c1d46a8SWang Nan disable = false; 15040c1d46a8SWang Nan if (disable) { 15050c1d46a8SWang Nan rec->no_buildid = true; 15060c1d46a8SWang Nan rec->no_buildid_cache = true; 15070c1d46a8SWang Nan disable_buildid_cache(); 15080c1d46a8SWang Nan } 15090c1d46a8SWang Nan } 1510655000e7SArnaldo Carvalho de Melo 15113e2be2daSArnaldo Carvalho de Melo if (rec->evlist->nr_entries == 0 && 15123e2be2daSArnaldo Carvalho de Melo perf_evlist__add_default(rec->evlist) < 0) { 151369aad6f1SArnaldo Carvalho de Melo pr_err("Not enough memory for event selector list\n"); 151469aad6f1SArnaldo Carvalho de Melo goto out_symbol_exit; 1515bbd36e5eSPeter Zijlstra } 151686470930SIngo Molnar 151769e7e5b0SAdrian Hunter if (rec->opts.target.tid && !rec->opts.no_inherit_set) 151869e7e5b0SAdrian Hunter rec->opts.no_inherit = true; 151969e7e5b0SAdrian Hunter 1520602ad878SArnaldo Carvalho de Melo err = target__validate(&rec->opts.target); 152116ad2ffbSNamhyung Kim if (err) { 1522602ad878SArnaldo Carvalho de Melo target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); 152316ad2ffbSNamhyung Kim ui__warning("%s", errbuf); 152416ad2ffbSNamhyung Kim } 15254bd0f2d2SNamhyung Kim 1526602ad878SArnaldo Carvalho de Melo err = target__parse_uid(&rec->opts.target); 152716ad2ffbSNamhyung Kim if (err) { 152816ad2ffbSNamhyung Kim int saved_errno = errno; 152916ad2ffbSNamhyung Kim 1530602ad878SArnaldo Carvalho de Melo target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); 15313780f488SNamhyung Kim ui__error("%s", errbuf); 153216ad2ffbSNamhyung Kim 153316ad2ffbSNamhyung Kim err = -saved_errno; 15348fa60e1fSNamhyung Kim goto out_symbol_exit; 153516ad2ffbSNamhyung Kim } 15360d37aa34SArnaldo Carvalho de Melo 153716ad2ffbSNamhyung Kim err = -ENOMEM; 15383e2be2daSArnaldo Carvalho de Melo if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0) 1539dd7927f4SArnaldo Carvalho de Melo usage_with_options(record_usage, record_options); 154069aad6f1SArnaldo Carvalho de Melo 1541ef149c25SAdrian Hunter err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts); 1542ef149c25SAdrian Hunter if (err) 1543ef149c25SAdrian Hunter goto out_symbol_exit; 1544ef149c25SAdrian Hunter 15456156681bSNamhyung Kim /* 15466156681bSNamhyung Kim * We take all buildids when the file contains 15476156681bSNamhyung Kim * AUX area tracing data because we do not decode the 15486156681bSNamhyung Kim * trace because it would take too long. 15496156681bSNamhyung Kim */ 15506156681bSNamhyung Kim if (rec->opts.full_auxtrace) 15516156681bSNamhyung Kim rec->buildid_all = true; 15526156681bSNamhyung Kim 1553b4006796SArnaldo Carvalho de Melo if (record_opts__config(&rec->opts)) { 155439d17dacSArnaldo Carvalho de Melo err = -EINVAL; 155503ad9747SArnaldo Carvalho de Melo goto out_symbol_exit; 15567e4ff9e3SMike Galbraith } 15577e4ff9e3SMike Galbraith 1558d20deb64SArnaldo Carvalho de Melo err = __cmd_record(&record, argc, argv); 1559d65a458bSArnaldo Carvalho de Melo out_symbol_exit: 156045604710SNamhyung Kim perf_evlist__delete(rec->evlist); 1561d65a458bSArnaldo Carvalho de Melo symbol__exit(); 1562ef149c25SAdrian Hunter auxtrace_record__free(rec->itr); 156339d17dacSArnaldo Carvalho de Melo return err; 156486470930SIngo Molnar } 15652dd6d8a1SAdrian Hunter 15662dd6d8a1SAdrian Hunter static void snapshot_sig_handler(int sig __maybe_unused) 15672dd6d8a1SAdrian Hunter { 15685f9cf599SWang Nan if (trigger_is_ready(&auxtrace_snapshot_trigger)) { 15695f9cf599SWang Nan trigger_hit(&auxtrace_snapshot_trigger); 15702dd6d8a1SAdrian Hunter auxtrace_record__snapshot_started = 1; 15715f9cf599SWang Nan if (auxtrace_record__snapshot_start(record.itr)) 15725f9cf599SWang Nan trigger_error(&auxtrace_snapshot_trigger); 15735f9cf599SWang Nan } 15743c1cb7e3SWang Nan 15753c1cb7e3SWang Nan if (trigger_is_ready(&switch_output_trigger)) 15763c1cb7e3SWang Nan trigger_hit(&switch_output_trigger); 15772dd6d8a1SAdrian Hunter } 1578