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 */ 8b8f46c5aSXiao Guangrong #define _FILE_OFFSET_BITS 64 9b8f46c5aSXiao Guangrong 1086470930SIngo Molnar #include "builtin.h" 1186470930SIngo Molnar 1286470930SIngo Molnar #include "perf.h" 1386470930SIngo Molnar 146122e4e4SArnaldo Carvalho de Melo #include "util/build-id.h" 1586470930SIngo Molnar #include "util/util.h" 1686470930SIngo Molnar #include "util/parse-options.h" 1786470930SIngo Molnar #include "util/parse-events.h" 1886470930SIngo Molnar 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" 258d06367fSArnaldo Carvalho de Melo #include "util/symbol.h" 26a12b51c4SPaul Mackerras #include "util/cpumap.h" 27fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 287c6a1c65SPeter Zijlstra 2986470930SIngo Molnar #include <unistd.h> 3086470930SIngo Molnar #include <sched.h> 31a41794cdSArnaldo Carvalho de Melo #include <sys/mman.h> 3286470930SIngo Molnar 337865e817SFrederic Weisbecker enum write_mode_t { 347865e817SFrederic Weisbecker WRITE_FORCE, 357865e817SFrederic Weisbecker WRITE_APPEND 367865e817SFrederic Weisbecker }; 377865e817SFrederic Weisbecker 38*01c2d99bSArnaldo Carvalho de Melo struct perf_record_opts record_opts = { 390f82ebc4SArnaldo Carvalho de Melo .target_pid = -1, 400f82ebc4SArnaldo Carvalho de Melo .target_tid = -1, 41*01c2d99bSArnaldo Carvalho de Melo .mmap_pages = UINT_MAX, 420f82ebc4SArnaldo Carvalho de Melo .user_freq = UINT_MAX, 430f82ebc4SArnaldo Carvalho de Melo .user_interval = ULLONG_MAX, 440f82ebc4SArnaldo Carvalho de Melo .freq = 1000, 450f82ebc4SArnaldo Carvalho de Melo .sample_id_all_avail = true, 460f82ebc4SArnaldo Carvalho de Melo }; 4786470930SIngo Molnar 4886470930SIngo Molnar static unsigned int page_size; 4986470930SIngo Molnar static int output; 50d7065adbSFranck Bui-Huu static const char *output_name = NULL; 5143bece79SLin Ming static bool group = false; 521967936dSArnaldo Carvalho de Melo static int realtime_prio = 0; 537865e817SFrederic Weisbecker static enum write_mode_t write_mode = WRITE_FORCE; 54a1ac1d3cSStephane Eranian static bool no_buildid = false; 55baa2f6ceSArnaldo Carvalho de Melo static bool no_buildid_cache = false; 56361c99a6SArnaldo Carvalho de Melo static struct perf_evlist *evsel_list; 5786470930SIngo Molnar 5842e59d7dSIngo Molnar static long samples = 0; 5942e59d7dSIngo Molnar static u64 bytes_written = 0; 6086470930SIngo Molnar 61f5970550SPeter Zijlstra static int file_new = 1; 626122e4e4SArnaldo Carvalho de Melo static off_t post_processing_offset; 637c6a1c65SPeter Zijlstra 6494c744b6SArnaldo Carvalho de Melo static struct perf_session *session; 6533e49ea7SAndi Kleen static const char *progname; 66f5970550SPeter Zijlstra 679215545eSTom Zanussi static void advance_output(size_t size) 689215545eSTom Zanussi { 699215545eSTom Zanussi bytes_written += size; 709215545eSTom Zanussi } 719215545eSTom Zanussi 72f5970550SPeter Zijlstra static void write_output(void *buf, size_t size) 73f5970550SPeter Zijlstra { 74f5970550SPeter Zijlstra while (size) { 75f5970550SPeter Zijlstra int ret = write(output, buf, size); 76f5970550SPeter Zijlstra 77f5970550SPeter Zijlstra if (ret < 0) 78f5970550SPeter Zijlstra die("failed to write"); 79f5970550SPeter Zijlstra 80f5970550SPeter Zijlstra size -= ret; 81f5970550SPeter Zijlstra buf += ret; 82f5970550SPeter Zijlstra 83f5970550SPeter Zijlstra bytes_written += ret; 84f5970550SPeter Zijlstra } 85f5970550SPeter Zijlstra } 86f5970550SPeter Zijlstra 878115d60cSArnaldo Carvalho de Melo static int process_synthesized_event(union perf_event *event, 888d50e5b4SArnaldo Carvalho de Melo struct perf_sample *sample __used, 89d8f66248SArnaldo Carvalho de Melo struct perf_session *self __used) 90234fbbf5SArnaldo Carvalho de Melo { 916122e4e4SArnaldo Carvalho de Melo write_output(event, event->header.size); 92234fbbf5SArnaldo Carvalho de Melo return 0; 93234fbbf5SArnaldo Carvalho de Melo } 94234fbbf5SArnaldo Carvalho de Melo 95744bd8aaSArnaldo Carvalho de Melo static void mmap_read(struct perf_mmap *md) 9686470930SIngo Molnar { 97744bd8aaSArnaldo Carvalho de Melo unsigned int head = perf_mmap__read_head(md); 9886470930SIngo Molnar unsigned int old = md->prev; 9986470930SIngo Molnar unsigned char *data = md->base + page_size; 10086470930SIngo Molnar unsigned long size; 10186470930SIngo Molnar void *buf; 10286470930SIngo Molnar 103dc82009aSArnaldo Carvalho de Melo if (old == head) 104dc82009aSArnaldo Carvalho de Melo return; 10586470930SIngo Molnar 10686470930SIngo Molnar samples++; 10786470930SIngo Molnar 10886470930SIngo Molnar size = head - old; 10986470930SIngo Molnar 11086470930SIngo Molnar if ((old & md->mask) + size != (head & md->mask)) { 11186470930SIngo Molnar buf = &data[old & md->mask]; 11286470930SIngo Molnar size = md->mask + 1 - (old & md->mask); 11386470930SIngo Molnar old += size; 11486470930SIngo Molnar 1156122e4e4SArnaldo Carvalho de Melo write_output(buf, size); 11686470930SIngo Molnar } 11786470930SIngo Molnar 11886470930SIngo Molnar buf = &data[old & md->mask]; 11986470930SIngo Molnar size = head - old; 12086470930SIngo Molnar old += size; 12186470930SIngo Molnar 1226122e4e4SArnaldo Carvalho de Melo write_output(buf, size); 12386470930SIngo Molnar 12486470930SIngo Molnar md->prev = old; 125115d2d89SArnaldo Carvalho de Melo perf_mmap__write_tail(md, old); 12686470930SIngo Molnar } 12786470930SIngo Molnar 12886470930SIngo Molnar static volatile int done = 0; 129f7b7c26eSPeter Zijlstra static volatile int signr = -1; 13033e49ea7SAndi Kleen static volatile int child_finished = 0; 13186470930SIngo Molnar 13286470930SIngo Molnar static void sig_handler(int sig) 13386470930SIngo Molnar { 13433e49ea7SAndi Kleen if (sig == SIGCHLD) 13533e49ea7SAndi Kleen child_finished = 1; 13633e49ea7SAndi Kleen 13786470930SIngo Molnar done = 1; 138f7b7c26eSPeter Zijlstra signr = sig; 139f7b7c26eSPeter Zijlstra } 140f7b7c26eSPeter Zijlstra 141f7b7c26eSPeter Zijlstra static void sig_atexit(void) 142f7b7c26eSPeter Zijlstra { 14333e49ea7SAndi Kleen int status; 14433e49ea7SAndi Kleen 14535b9d88eSArnaldo Carvalho de Melo if (evsel_list->workload.pid > 0) { 14633e49ea7SAndi Kleen if (!child_finished) 14735b9d88eSArnaldo Carvalho de Melo kill(evsel_list->workload.pid, SIGTERM); 148933da83aSChris Wilson 14933e49ea7SAndi Kleen wait(&status); 15033e49ea7SAndi Kleen if (WIFSIGNALED(status)) 15133e49ea7SAndi Kleen psignal(WTERMSIG(status), progname); 15233e49ea7SAndi Kleen } 15333e49ea7SAndi Kleen 15418483b81SArnaldo Carvalho de Melo if (signr == -1 || signr == SIGUSR1) 155f7b7c26eSPeter Zijlstra return; 156f7b7c26eSPeter Zijlstra 157f7b7c26eSPeter Zijlstra signal(signr, SIG_DFL); 158f7b7c26eSPeter Zijlstra kill(getpid(), signr); 15986470930SIngo Molnar } 16086470930SIngo Molnar 161a91e5431SArnaldo Carvalho de Melo static bool perf_evlist__equal(struct perf_evlist *evlist, 162a91e5431SArnaldo Carvalho de Melo struct perf_evlist *other) 163a91e5431SArnaldo Carvalho de Melo { 164a91e5431SArnaldo Carvalho de Melo struct perf_evsel *pos, *pair; 165a91e5431SArnaldo Carvalho de Melo 166a91e5431SArnaldo Carvalho de Melo if (evlist->nr_entries != other->nr_entries) 167a91e5431SArnaldo Carvalho de Melo return false; 168a91e5431SArnaldo Carvalho de Melo 169a91e5431SArnaldo Carvalho de Melo pair = list_entry(other->entries.next, struct perf_evsel, node); 170a91e5431SArnaldo Carvalho de Melo 171a91e5431SArnaldo Carvalho de Melo list_for_each_entry(pos, &evlist->entries, node) { 172a91e5431SArnaldo Carvalho de Melo if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0)) 173a91e5431SArnaldo Carvalho de Melo return false; 174a91e5431SArnaldo Carvalho de Melo pair = list_entry(pair->node.next, struct perf_evsel, node); 175a91e5431SArnaldo Carvalho de Melo } 176a91e5431SArnaldo Carvalho de Melo 177a91e5431SArnaldo Carvalho de Melo return true; 178a91e5431SArnaldo Carvalho de Melo } 179a91e5431SArnaldo Carvalho de Melo 180dd7927f4SArnaldo Carvalho de Melo static void open_counters(struct perf_evlist *evlist) 181dd7927f4SArnaldo Carvalho de Melo { 182727ab04eSArnaldo Carvalho de Melo struct perf_evsel *pos, *first; 183dd7927f4SArnaldo Carvalho de Melo 184727ab04eSArnaldo Carvalho de Melo first = list_entry(evlist->entries.next, struct perf_evsel, node); 185727ab04eSArnaldo Carvalho de Melo 1860f82ebc4SArnaldo Carvalho de Melo perf_evlist__config_attrs(evlist, &record_opts); 1870f82ebc4SArnaldo Carvalho de Melo 188dd7927f4SArnaldo Carvalho de Melo list_for_each_entry(pos, &evlist->entries, node) { 189dd7927f4SArnaldo Carvalho de Melo struct perf_event_attr *attr = &pos->attr; 190727ab04eSArnaldo Carvalho de Melo struct xyarray *group_fd = NULL; 191dd7927f4SArnaldo Carvalho de Melo /* 192dd7927f4SArnaldo Carvalho de Melo * Check if parse_single_tracepoint_event has already asked for 193dd7927f4SArnaldo Carvalho de Melo * PERF_SAMPLE_TIME. 194dd7927f4SArnaldo Carvalho de Melo * 195dd7927f4SArnaldo Carvalho de Melo * XXX this is kludgy but short term fix for problems introduced by 196dd7927f4SArnaldo Carvalho de Melo * eac23d1c that broke 'perf script' by having different sample_types 197dd7927f4SArnaldo Carvalho de Melo * when using multiple tracepoint events when we use a perf binary 198dd7927f4SArnaldo Carvalho de Melo * that tries to use sample_id_all on an older kernel. 199dd7927f4SArnaldo Carvalho de Melo * 200dd7927f4SArnaldo Carvalho de Melo * We need to move counter creation to perf_session, support 201dd7927f4SArnaldo Carvalho de Melo * different sample_types, etc. 202dd7927f4SArnaldo Carvalho de Melo */ 203dd7927f4SArnaldo Carvalho de Melo bool time_needed = attr->sample_type & PERF_SAMPLE_TIME; 204dd7927f4SArnaldo Carvalho de Melo 205727ab04eSArnaldo Carvalho de Melo if (group && pos != first) 206727ab04eSArnaldo Carvalho de Melo group_fd = first->fd; 2079c90a61cSArnaldo Carvalho de Melo retry_sample_id: 2080f82ebc4SArnaldo Carvalho de Melo attr->sample_id_all = record_opts.sample_id_all_avail ? 1 : 0; 2093da297a6SIngo Molnar try_again: 210727ab04eSArnaldo Carvalho de Melo if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group, 211727ab04eSArnaldo Carvalho de Melo group_fd) < 0) { 21286470930SIngo Molnar int err = errno; 21386470930SIngo Molnar 214c286c419SArnaldo Carvalho de Melo if (err == EPERM || err == EACCES) { 215b8631e6eSArnaldo Carvalho de Melo ui__error_paranoid(); 216c286c419SArnaldo Carvalho de Melo exit(EXIT_FAILURE); 2170f82ebc4SArnaldo Carvalho de Melo } else if (err == ENODEV && record_opts.cpu_list) { 218d6d901c2SZhang, Yanmin die("No such device - did you specify" 219d6d901c2SZhang, Yanmin " an out-of-range profile CPU?\n"); 2200f82ebc4SArnaldo Carvalho de Melo } else if (err == EINVAL && record_opts.sample_id_all_avail) { 2219c90a61cSArnaldo Carvalho de Melo /* 2229c90a61cSArnaldo Carvalho de Melo * Old kernel, no attr->sample_id_type_all field 2239c90a61cSArnaldo Carvalho de Melo */ 2240f82ebc4SArnaldo Carvalho de Melo record_opts.sample_id_all_avail = false; 2250f82ebc4SArnaldo Carvalho de Melo if (!record_opts.sample_time && !record_opts.raw_samples && !time_needed) 226eac23d1cSIan Munsie attr->sample_type &= ~PERF_SAMPLE_TIME; 227eac23d1cSIan Munsie 2289c90a61cSArnaldo Carvalho de Melo goto retry_sample_id; 229d6d901c2SZhang, Yanmin } 2303da297a6SIngo Molnar 2313da297a6SIngo Molnar /* 2323da297a6SIngo Molnar * If it's cycles then fall back to hrtimer 2333da297a6SIngo Molnar * based cpu-clock-tick sw counter, which 2343da297a6SIngo Molnar * is always available even if no PMU support: 2353da297a6SIngo Molnar */ 2363da297a6SIngo Molnar if (attr->type == PERF_TYPE_HARDWARE 237f4dbfa8fSPeter Zijlstra && attr->config == PERF_COUNT_HW_CPU_CYCLES) { 2383da297a6SIngo Molnar 2393da297a6SIngo Molnar if (verbose) 240ca6a4258SDavid Ahern ui__warning("The cycles event is not supported, " 241ca6a4258SDavid Ahern "trying to fall back to cpu-clock-ticks\n"); 2423da297a6SIngo Molnar attr->type = PERF_TYPE_SOFTWARE; 243f4dbfa8fSPeter Zijlstra attr->config = PERF_COUNT_SW_CPU_CLOCK; 2443da297a6SIngo Molnar goto try_again; 2453da297a6SIngo Molnar } 246ca6a4258SDavid Ahern 247ca6a4258SDavid Ahern if (err == ENOENT) { 248ca6a4258SDavid Ahern ui__warning("The %s event is not supported.\n", 249ca6a4258SDavid Ahern event_name(pos)); 250ca6a4258SDavid Ahern exit(EXIT_FAILURE); 251ca6a4258SDavid Ahern } 252ca6a4258SDavid Ahern 25330c806a0SIngo Molnar printf("\n"); 254d9cf837eSCorey Ashford error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", 255dd7927f4SArnaldo Carvalho de Melo err, strerror(err)); 256bfd45118SSimon Kaempflein 257bfd45118SSimon Kaempflein #if defined(__i386__) || defined(__x86_64__) 258bfd45118SSimon Kaempflein if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP) 259d6d901c2SZhang, Yanmin die("No hardware sampling interrupt available." 260d6d901c2SZhang, Yanmin " No APIC? If so then you can boot the kernel" 261d6d901c2SZhang, Yanmin " with the \"lapic\" boot parameter to" 262d6d901c2SZhang, Yanmin " force-enable it.\n"); 263bfd45118SSimon Kaempflein #endif 264bfd45118SSimon Kaempflein 265cdd6c482SIngo Molnar die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 2667c6a1c65SPeter Zijlstra } 2677c6a1c65SPeter Zijlstra } 2687c6a1c65SPeter Zijlstra 2690a102479SFrederic Weisbecker if (perf_evlist__set_filters(evlist)) { 2700a102479SFrederic Weisbecker error("failed to set filter with %d (%s)\n", errno, 2710a102479SFrederic Weisbecker strerror(errno)); 2720a102479SFrederic Weisbecker exit(-1); 2730a102479SFrederic Weisbecker } 2740a102479SFrederic Weisbecker 275*01c2d99bSArnaldo Carvalho de Melo if (perf_evlist__mmap(evlist, record_opts.mmap_pages, false) < 0) 2760a27d7f9SArnaldo Carvalho de Melo die("failed to mmap with %d (%s)\n", errno, strerror(errno)); 2770a27d7f9SArnaldo Carvalho de Melo 278a91e5431SArnaldo Carvalho de Melo if (file_new) 279a91e5431SArnaldo Carvalho de Melo session->evlist = evlist; 280a91e5431SArnaldo Carvalho de Melo else { 281a91e5431SArnaldo Carvalho de Melo if (!perf_evlist__equal(session->evlist, evlist)) { 282a91e5431SArnaldo Carvalho de Melo fprintf(stderr, "incompatible append\n"); 283a91e5431SArnaldo Carvalho de Melo exit(-1); 284dd7927f4SArnaldo Carvalho de Melo } 28586470930SIngo Molnar } 28686470930SIngo Molnar 287a91e5431SArnaldo Carvalho de Melo perf_session__update_sample_type(session); 288a91e5431SArnaldo Carvalho de Melo } 289a91e5431SArnaldo Carvalho de Melo 2906122e4e4SArnaldo Carvalho de Melo static int process_buildids(void) 2916122e4e4SArnaldo Carvalho de Melo { 2926122e4e4SArnaldo Carvalho de Melo u64 size = lseek(output, 0, SEEK_CUR); 2936122e4e4SArnaldo Carvalho de Melo 2949f591fd7SArnaldo Carvalho de Melo if (size == 0) 2959f591fd7SArnaldo Carvalho de Melo return 0; 2969f591fd7SArnaldo Carvalho de Melo 2976122e4e4SArnaldo Carvalho de Melo session->fd = output; 2986122e4e4SArnaldo Carvalho de Melo return __perf_session__process_events(session, post_processing_offset, 2996122e4e4SArnaldo Carvalho de Melo size - post_processing_offset, 3006122e4e4SArnaldo Carvalho de Melo size, &build_id__mark_dso_hit_ops); 3016122e4e4SArnaldo Carvalho de Melo } 3026122e4e4SArnaldo Carvalho de Melo 303f5970550SPeter Zijlstra static void atexit_header(void) 304f5970550SPeter Zijlstra { 30535b9d88eSArnaldo Carvalho de Melo if (!record_opts.pipe_output) { 30694c744b6SArnaldo Carvalho de Melo session->header.data_size += bytes_written; 307f5970550SPeter Zijlstra 308baa2f6ceSArnaldo Carvalho de Melo if (!no_buildid) 3096122e4e4SArnaldo Carvalho de Melo process_buildids(); 310a91e5431SArnaldo Carvalho de Melo perf_session__write_header(session, evsel_list, output, true); 31139d17dacSArnaldo Carvalho de Melo perf_session__delete(session); 312361c99a6SArnaldo Carvalho de Melo perf_evlist__delete(evsel_list); 313d65a458bSArnaldo Carvalho de Melo symbol__exit(); 314c7929e47STom Zanussi } 315f5970550SPeter Zijlstra } 316f5970550SPeter Zijlstra 3178115d60cSArnaldo Carvalho de Melo static void perf_event__synthesize_guest_os(struct machine *machine, void *data) 318a1645ce1SZhang, Yanmin { 319a1645ce1SZhang, Yanmin int err; 32023346f21SArnaldo Carvalho de Melo struct perf_session *psession = data; 321a1645ce1SZhang, Yanmin 32223346f21SArnaldo Carvalho de Melo if (machine__is_host(machine)) 323a1645ce1SZhang, Yanmin return; 324a1645ce1SZhang, Yanmin 325a1645ce1SZhang, Yanmin /* 326a1645ce1SZhang, Yanmin *As for guest kernel when processing subcommand record&report, 327a1645ce1SZhang, Yanmin *we arrange module mmap prior to guest kernel mmap and trigger 328a1645ce1SZhang, Yanmin *a preload dso because default guest module symbols are loaded 329a1645ce1SZhang, Yanmin *from guest kallsyms instead of /lib/modules/XXX/XXX. This 330a1645ce1SZhang, Yanmin *method is used to avoid symbol missing when the first addr is 331a1645ce1SZhang, Yanmin *in module instead of in guest kernel. 332a1645ce1SZhang, Yanmin */ 3338115d60cSArnaldo Carvalho de Melo err = perf_event__synthesize_modules(process_synthesized_event, 33423346f21SArnaldo Carvalho de Melo psession, machine); 335a1645ce1SZhang, Yanmin if (err < 0) 336a1645ce1SZhang, Yanmin pr_err("Couldn't record guest kernel [%d]'s reference" 33723346f21SArnaldo Carvalho de Melo " relocation symbol.\n", machine->pid); 338a1645ce1SZhang, Yanmin 339a1645ce1SZhang, Yanmin /* 340a1645ce1SZhang, Yanmin * We use _stext for guest kernel because guest kernel's /proc/kallsyms 341a1645ce1SZhang, Yanmin * have no _text sometimes. 342a1645ce1SZhang, Yanmin */ 3438115d60cSArnaldo Carvalho de Melo err = perf_event__synthesize_kernel_mmap(process_synthesized_event, 34423346f21SArnaldo Carvalho de Melo psession, machine, "_text"); 345a1645ce1SZhang, Yanmin if (err < 0) 3468115d60cSArnaldo Carvalho de Melo err = perf_event__synthesize_kernel_mmap(process_synthesized_event, 3478115d60cSArnaldo Carvalho de Melo psession, machine, 3488115d60cSArnaldo Carvalho de Melo "_stext"); 349a1645ce1SZhang, Yanmin if (err < 0) 350a1645ce1SZhang, Yanmin pr_err("Couldn't record guest kernel [%d]'s reference" 35123346f21SArnaldo Carvalho de Melo " relocation symbol.\n", machine->pid); 352a1645ce1SZhang, Yanmin } 353a1645ce1SZhang, Yanmin 35498402807SFrederic Weisbecker static struct perf_event_header finished_round_event = { 35598402807SFrederic Weisbecker .size = sizeof(struct perf_event_header), 35698402807SFrederic Weisbecker .type = PERF_RECORD_FINISHED_ROUND, 35798402807SFrederic Weisbecker }; 35898402807SFrederic Weisbecker 35998402807SFrederic Weisbecker static void mmap_read_all(void) 36098402807SFrederic Weisbecker { 3610e2e63ddSPeter Zijlstra int i; 36298402807SFrederic Weisbecker 363aece948fSArnaldo Carvalho de Melo for (i = 0; i < evsel_list->nr_mmaps; i++) { 3640a27d7f9SArnaldo Carvalho de Melo if (evsel_list->mmap[i].base) 3650a27d7f9SArnaldo Carvalho de Melo mmap_read(&evsel_list->mmap[i]); 36698402807SFrederic Weisbecker } 36798402807SFrederic Weisbecker 36898402807SFrederic Weisbecker if (perf_header__has_feat(&session->header, HEADER_TRACE_INFO)) 36998402807SFrederic Weisbecker write_output(&finished_round_event, sizeof(finished_round_event)); 37098402807SFrederic Weisbecker } 37198402807SFrederic Weisbecker 372d4db3f16SArnaldo Carvalho de Melo static int __cmd_record(int argc, const char **argv) 37386470930SIngo Molnar { 37486470930SIngo Molnar struct stat st; 37586470930SIngo Molnar int flags; 3764dc0a04bSArnaldo Carvalho de Melo int err; 3778b412664SPeter Zijlstra unsigned long waking = 0; 37846be604bSZhang, Yanmin const bool forks = argc > 0; 37923346f21SArnaldo Carvalho de Melo struct machine *machine; 38086470930SIngo Molnar 38133e49ea7SAndi Kleen progname = argv[0]; 38233e49ea7SAndi Kleen 38386470930SIngo Molnar page_size = sysconf(_SC_PAGE_SIZE); 38486470930SIngo Molnar 385f5970550SPeter Zijlstra atexit(sig_atexit); 386f5970550SPeter Zijlstra signal(SIGCHLD, sig_handler); 387f5970550SPeter Zijlstra signal(SIGINT, sig_handler); 38818483b81SArnaldo Carvalho de Melo signal(SIGUSR1, sig_handler); 389f5970550SPeter Zijlstra 390d7065adbSFranck Bui-Huu if (!output_name) { 391d7065adbSFranck Bui-Huu if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode)) 39235b9d88eSArnaldo Carvalho de Melo record_opts.pipe_output = true; 393d7065adbSFranck Bui-Huu else 394d7065adbSFranck Bui-Huu output_name = "perf.data"; 395d7065adbSFranck Bui-Huu } 396d7065adbSFranck Bui-Huu if (output_name) { 397529870e3STom Zanussi if (!strcmp(output_name, "-")) 39835b9d88eSArnaldo Carvalho de Melo record_opts.pipe_output = true; 399529870e3STom Zanussi else if (!stat(output_name, &st) && st.st_size) { 4007865e817SFrederic Weisbecker if (write_mode == WRITE_FORCE) { 401b38d3464SArnaldo Carvalho de Melo char oldname[PATH_MAX]; 402b38d3464SArnaldo Carvalho de Melo snprintf(oldname, sizeof(oldname), "%s.old", 403b38d3464SArnaldo Carvalho de Melo output_name); 404b38d3464SArnaldo Carvalho de Melo unlink(oldname); 405b38d3464SArnaldo Carvalho de Melo rename(output_name, oldname); 406b38d3464SArnaldo Carvalho de Melo } 4077865e817SFrederic Weisbecker } else if (write_mode == WRITE_APPEND) { 4087865e817SFrederic Weisbecker write_mode = WRITE_FORCE; 409266e0e21SPierre Habouzit } 410d7065adbSFranck Bui-Huu } 41186470930SIngo Molnar 412f887f301SXiao Guangrong flags = O_CREAT|O_RDWR; 4137865e817SFrederic Weisbecker if (write_mode == WRITE_APPEND) 414f5970550SPeter Zijlstra file_new = 0; 41586470930SIngo Molnar else 41686470930SIngo Molnar flags |= O_TRUNC; 41786470930SIngo Molnar 41835b9d88eSArnaldo Carvalho de Melo if (record_opts.pipe_output) 419529870e3STom Zanussi output = STDOUT_FILENO; 420529870e3STom Zanussi else 42186470930SIngo Molnar output = open(output_name, flags, S_IRUSR | S_IWUSR); 42286470930SIngo Molnar if (output < 0) { 42386470930SIngo Molnar perror("failed to create output file"); 42486470930SIngo Molnar exit(-1); 42586470930SIngo Molnar } 42686470930SIngo Molnar 4277865e817SFrederic Weisbecker session = perf_session__new(output_name, O_WRONLY, 42821ef97f0SIan Munsie write_mode == WRITE_FORCE, false, NULL); 42994c744b6SArnaldo Carvalho de Melo if (session == NULL) { 430a9a70bbcSArnaldo Carvalho de Melo pr_err("Not enough memory for reading perf file header\n"); 431a9a70bbcSArnaldo Carvalho de Melo return -1; 432a9a70bbcSArnaldo Carvalho de Melo } 433a9a70bbcSArnaldo Carvalho de Melo 434baa2f6ceSArnaldo Carvalho de Melo if (!no_buildid) 435baa2f6ceSArnaldo Carvalho de Melo perf_header__set_feat(&session->header, HEADER_BUILD_ID); 436baa2f6ceSArnaldo Carvalho de Melo 4374dc0a04bSArnaldo Carvalho de Melo if (!file_new) { 438a91e5431SArnaldo Carvalho de Melo err = perf_session__read_header(session, output); 4394dc0a04bSArnaldo Carvalho de Melo if (err < 0) 44039d17dacSArnaldo Carvalho de Melo goto out_delete_session; 4414dc0a04bSArnaldo Carvalho de Melo } 4424dc0a04bSArnaldo Carvalho de Melo 443361c99a6SArnaldo Carvalho de Melo if (have_tracepoints(&evsel_list->entries)) 44494c744b6SArnaldo Carvalho de Melo perf_header__set_feat(&session->header, HEADER_TRACE_INFO); 44503456a15SFrederic Weisbecker 446fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_HOSTNAME); 447fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_OSRELEASE); 448fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_ARCH); 449fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_CPUDESC); 450fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_NRCPUS); 451fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_EVENT_DESC); 452fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_CMDLINE); 453fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_VERSION); 454fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY); 455fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_TOTAL_MEM); 456fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_NUMA_TOPOLOGY); 457fbe96f29SStephane Eranian perf_header__set_feat(&session->header, HEADER_CPUID); 458fbe96f29SStephane Eranian 459d4db3f16SArnaldo Carvalho de Melo if (forks) { 46035b9d88eSArnaldo Carvalho de Melo err = perf_evlist__prepare_workload(evsel_list, &record_opts, argv); 46135b9d88eSArnaldo Carvalho de Melo if (err < 0) { 46235b9d88eSArnaldo Carvalho de Melo pr_err("Couldn't run the workload!\n"); 46335b9d88eSArnaldo Carvalho de Melo goto out_delete_session; 464856e9660SPeter Zijlstra } 465856e9660SPeter Zijlstra } 466856e9660SPeter Zijlstra 467dd7927f4SArnaldo Carvalho de Melo open_counters(evsel_list); 46886470930SIngo Molnar 469712a4b60SArnaldo Carvalho de Melo /* 470712a4b60SArnaldo Carvalho de Melo * perf_session__delete(session) will be called at atexit_header() 471712a4b60SArnaldo Carvalho de Melo */ 472712a4b60SArnaldo Carvalho de Melo atexit(atexit_header); 473712a4b60SArnaldo Carvalho de Melo 47435b9d88eSArnaldo Carvalho de Melo if (record_opts.pipe_output) { 475529870e3STom Zanussi err = perf_header__write_pipe(output); 476529870e3STom Zanussi if (err < 0) 477529870e3STom Zanussi return err; 478529870e3STom Zanussi } else if (file_new) { 479a91e5431SArnaldo Carvalho de Melo err = perf_session__write_header(session, evsel_list, 480361c99a6SArnaldo Carvalho de Melo output, false); 481d5eed904SArnaldo Carvalho de Melo if (err < 0) 482d5eed904SArnaldo Carvalho de Melo return err; 483d5eed904SArnaldo Carvalho de Melo } 4847c6a1c65SPeter Zijlstra 4856122e4e4SArnaldo Carvalho de Melo post_processing_offset = lseek(output, 0, SEEK_CUR); 4866122e4e4SArnaldo Carvalho de Melo 48735b9d88eSArnaldo Carvalho de Melo if (record_opts.pipe_output) { 488a91e5431SArnaldo Carvalho de Melo err = perf_session__synthesize_attrs(session, 489a91e5431SArnaldo Carvalho de Melo process_synthesized_event); 4902c46dbb5STom Zanussi if (err < 0) { 4912c46dbb5STom Zanussi pr_err("Couldn't synthesize attrs.\n"); 4922c46dbb5STom Zanussi return err; 4932c46dbb5STom Zanussi } 494cd19a035STom Zanussi 4958115d60cSArnaldo Carvalho de Melo err = perf_event__synthesize_event_types(process_synthesized_event, 496cd19a035STom Zanussi session); 497cd19a035STom Zanussi if (err < 0) { 498cd19a035STom Zanussi pr_err("Couldn't synthesize event_types.\n"); 499cd19a035STom Zanussi return err; 500cd19a035STom Zanussi } 5019215545eSTom Zanussi 502361c99a6SArnaldo Carvalho de Melo if (have_tracepoints(&evsel_list->entries)) { 50363e0c771STom Zanussi /* 50463e0c771STom Zanussi * FIXME err <= 0 here actually means that 50563e0c771STom Zanussi * there were no tracepoints so its not really 50663e0c771STom Zanussi * an error, just that we don't need to 50763e0c771STom Zanussi * synthesize anything. We really have to 50863e0c771STom Zanussi * return this more properly and also 50963e0c771STom Zanussi * propagate errors that now are calling die() 51063e0c771STom Zanussi */ 5118115d60cSArnaldo Carvalho de Melo err = perf_event__synthesize_tracing_data(output, evsel_list, 5129215545eSTom Zanussi process_synthesized_event, 5139215545eSTom Zanussi session); 51463e0c771STom Zanussi if (err <= 0) { 51563e0c771STom Zanussi pr_err("Couldn't record tracing data.\n"); 51663e0c771STom Zanussi return err; 51763e0c771STom Zanussi } 5189215545eSTom Zanussi advance_output(err); 5192c46dbb5STom Zanussi } 52063e0c771STom Zanussi } 5212c46dbb5STom Zanussi 52223346f21SArnaldo Carvalho de Melo machine = perf_session__find_host_machine(session); 52323346f21SArnaldo Carvalho de Melo if (!machine) { 524a1645ce1SZhang, Yanmin pr_err("Couldn't find native kernel information.\n"); 525a1645ce1SZhang, Yanmin return -1; 526a1645ce1SZhang, Yanmin } 527a1645ce1SZhang, Yanmin 5288115d60cSArnaldo Carvalho de Melo err = perf_event__synthesize_kernel_mmap(process_synthesized_event, 52923346f21SArnaldo Carvalho de Melo session, machine, "_text"); 53070162138SArnaldo Carvalho de Melo if (err < 0) 5318115d60cSArnaldo Carvalho de Melo err = perf_event__synthesize_kernel_mmap(process_synthesized_event, 53223346f21SArnaldo Carvalho de Melo session, machine, "_stext"); 533c1a3a4b9SArnaldo Carvalho de Melo if (err < 0) 534c1a3a4b9SArnaldo Carvalho de Melo pr_err("Couldn't record kernel reference relocation symbol\n" 535c1a3a4b9SArnaldo Carvalho de Melo "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 536c1a3a4b9SArnaldo Carvalho de Melo "Check /proc/kallsyms permission or run as root.\n"); 53756b03f3cSArnaldo Carvalho de Melo 5388115d60cSArnaldo Carvalho de Melo err = perf_event__synthesize_modules(process_synthesized_event, 53923346f21SArnaldo Carvalho de Melo session, machine); 540c1a3a4b9SArnaldo Carvalho de Melo if (err < 0) 541c1a3a4b9SArnaldo Carvalho de Melo pr_err("Couldn't record kernel module information.\n" 542c1a3a4b9SArnaldo Carvalho de Melo "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 543c1a3a4b9SArnaldo Carvalho de Melo "Check /proc/modules permission or run as root.\n"); 544c1a3a4b9SArnaldo Carvalho de Melo 545a1645ce1SZhang, Yanmin if (perf_guest) 5468115d60cSArnaldo Carvalho de Melo perf_session__process_machines(session, 5478115d60cSArnaldo Carvalho de Melo perf_event__synthesize_guest_os); 548b7cece76SArnaldo Carvalho de Melo 5490f82ebc4SArnaldo Carvalho de Melo if (!record_opts.system_wide) 5507c940c18SArnaldo Carvalho de Melo perf_event__synthesize_thread_map(evsel_list->threads, 5518115d60cSArnaldo Carvalho de Melo process_synthesized_event, 552d8f66248SArnaldo Carvalho de Melo session); 553234fbbf5SArnaldo Carvalho de Melo else 5548115d60cSArnaldo Carvalho de Melo perf_event__synthesize_threads(process_synthesized_event, 5558115d60cSArnaldo Carvalho de Melo session); 5567c6a1c65SPeter Zijlstra 55786470930SIngo Molnar if (realtime_prio) { 55886470930SIngo Molnar struct sched_param param; 55986470930SIngo Molnar 56086470930SIngo Molnar param.sched_priority = realtime_prio; 56186470930SIngo Molnar if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { 5626beba7adSArnaldo Carvalho de Melo pr_err("Could not set realtime priority.\n"); 56386470930SIngo Molnar exit(-1); 56486470930SIngo Molnar } 56586470930SIngo Molnar } 56686470930SIngo Molnar 567764e16a3SDavid Ahern perf_evlist__enable(evsel_list); 568764e16a3SDavid Ahern 569856e9660SPeter Zijlstra /* 570856e9660SPeter Zijlstra * Let the child rip 571856e9660SPeter Zijlstra */ 572d4db3f16SArnaldo Carvalho de Melo if (forks) 57335b9d88eSArnaldo Carvalho de Melo perf_evlist__start_workload(evsel_list); 574856e9660SPeter Zijlstra 575649c48a9SPeter Zijlstra for (;;) { 57686470930SIngo Molnar int hits = samples; 57786470930SIngo Molnar 57898402807SFrederic Weisbecker mmap_read_all(); 57986470930SIngo Molnar 580649c48a9SPeter Zijlstra if (hits == samples) { 581649c48a9SPeter Zijlstra if (done) 582649c48a9SPeter Zijlstra break; 5835c581041SArnaldo Carvalho de Melo err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1); 5848b412664SPeter Zijlstra waking++; 5858b412664SPeter Zijlstra } 5868b412664SPeter Zijlstra 5874152ab37SArnaldo Carvalho de Melo if (done) 5884152ab37SArnaldo Carvalho de Melo perf_evlist__disable(evsel_list); 5898b412664SPeter Zijlstra } 5908b412664SPeter Zijlstra 59118483b81SArnaldo Carvalho de Melo if (quiet || signr == SIGUSR1) 592b44308f5SArnaldo Carvalho de Melo return 0; 593b44308f5SArnaldo Carvalho de Melo 5948b412664SPeter Zijlstra fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); 59586470930SIngo Molnar 59686470930SIngo Molnar /* 59786470930SIngo Molnar * Approximate RIP event size: 24 bytes. 59886470930SIngo Molnar */ 59986470930SIngo Molnar fprintf(stderr, 6009486aa38SArnaldo Carvalho de Melo "[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64 " samples) ]\n", 60186470930SIngo Molnar (double)bytes_written / 1024.0 / 1024.0, 60286470930SIngo Molnar output_name, 60386470930SIngo Molnar bytes_written / 24); 60486470930SIngo Molnar 60586470930SIngo Molnar return 0; 60639d17dacSArnaldo Carvalho de Melo 60739d17dacSArnaldo Carvalho de Melo out_delete_session: 60839d17dacSArnaldo Carvalho de Melo perf_session__delete(session); 60939d17dacSArnaldo Carvalho de Melo return err; 61086470930SIngo Molnar } 61186470930SIngo Molnar 61286470930SIngo Molnar static const char * const record_usage[] = { 61386470930SIngo Molnar "perf record [<options>] [<command>]", 61486470930SIngo Molnar "perf record [<options>] -- <command> [<options>]", 61586470930SIngo Molnar NULL 61686470930SIngo Molnar }; 61786470930SIngo Molnar 6187865e817SFrederic Weisbecker static bool force, append_file; 6197865e817SFrederic Weisbecker 620bca647aaSTom Zanussi const struct option record_options[] = { 621361c99a6SArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &evsel_list, "event", 62286470930SIngo Molnar "event selector. use 'perf list' to list available events", 623f120f9d5SJiri Olsa parse_events_option), 624361c99a6SArnaldo Carvalho de Melo OPT_CALLBACK(0, "filter", &evsel_list, "filter", 625c171b552SLi Zefan "event filter", parse_filter), 6260f82ebc4SArnaldo Carvalho de Melo OPT_INTEGER('p', "pid", &record_opts.target_pid, 627d6d901c2SZhang, Yanmin "record events on existing process id"), 6280f82ebc4SArnaldo Carvalho de Melo OPT_INTEGER('t', "tid", &record_opts.target_tid, 629d6d901c2SZhang, Yanmin "record events on existing thread id"), 63086470930SIngo Molnar OPT_INTEGER('r', "realtime", &realtime_prio, 63186470930SIngo Molnar "collect data with this RT SCHED_FIFO priority"), 6320f82ebc4SArnaldo Carvalho de Melo OPT_BOOLEAN('D', "no-delay", &record_opts.no_delay, 633acac03faSKirill Smelkov "collect data without buffering"), 6340f82ebc4SArnaldo Carvalho de Melo OPT_BOOLEAN('R', "raw-samples", &record_opts.raw_samples, 635daac07b2SFrederic Weisbecker "collect raw sample records from all opened counters"), 6360f82ebc4SArnaldo Carvalho de Melo OPT_BOOLEAN('a', "all-cpus", &record_opts.system_wide, 63786470930SIngo Molnar "system-wide collection from all CPUs"), 63886470930SIngo Molnar OPT_BOOLEAN('A', "append", &append_file, 63986470930SIngo Molnar "append to the output file to do incremental profiling"), 6400f82ebc4SArnaldo Carvalho de Melo OPT_STRING('C', "cpu", &record_opts.cpu_list, "cpu", 641c45c6ea2SStephane Eranian "list of cpus to monitor"), 64286470930SIngo Molnar OPT_BOOLEAN('f', "force", &force, 6437865e817SFrederic Weisbecker "overwrite existing data file (deprecated)"), 6440f82ebc4SArnaldo Carvalho de Melo OPT_U64('c', "count", &record_opts.user_interval, "event period to sample"), 64586470930SIngo Molnar OPT_STRING('o', "output", &output_name, "file", 64686470930SIngo Molnar "output file name"), 6470f82ebc4SArnaldo Carvalho de Melo OPT_BOOLEAN('i', "no-inherit", &record_opts.no_inherit, 6482e6cdf99SStephane Eranian "child tasks do not inherit counters"), 6490f82ebc4SArnaldo Carvalho de Melo OPT_UINTEGER('F', "freq", &record_opts.user_freq, "profile at this frequency"), 650*01c2d99bSArnaldo Carvalho de Melo OPT_UINTEGER('m', "mmap-pages", &record_opts.mmap_pages, 651*01c2d99bSArnaldo Carvalho de Melo "number of mmap data pages"), 65243bece79SLin Ming OPT_BOOLEAN(0, "group", &group, 65343bece79SLin Ming "put the counters into a counter group"), 6540f82ebc4SArnaldo Carvalho de Melo OPT_BOOLEAN('g', "call-graph", &record_opts.call_graph, 6553efa1cc9SIngo Molnar "do call-graph (stack chain/backtrace) recording"), 656c0555642SIan Munsie OPT_INCR('v', "verbose", &verbose, 6573da297a6SIngo Molnar "be more verbose (show counter open errors, etc)"), 658b44308f5SArnaldo Carvalho de Melo OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"), 6590f82ebc4SArnaldo Carvalho de Melo OPT_BOOLEAN('s', "stat", &record_opts.inherit_stat, 660649c48a9SPeter Zijlstra "per thread counts"), 6610f82ebc4SArnaldo Carvalho de Melo OPT_BOOLEAN('d', "data", &record_opts.sample_address, 6624bba828dSAnton Blanchard "Sample addresses"), 6630f82ebc4SArnaldo Carvalho de Melo OPT_BOOLEAN('T', "timestamp", &record_opts.sample_time, "Sample timestamps"), 6640f82ebc4SArnaldo Carvalho de Melo OPT_BOOLEAN('n', "no-samples", &record_opts.no_samples, 665649c48a9SPeter Zijlstra "don't sample"), 666baa2f6ceSArnaldo Carvalho de Melo OPT_BOOLEAN('N', "no-buildid-cache", &no_buildid_cache, 667a1ac1d3cSStephane Eranian "do not update the buildid cache"), 668baa2f6ceSArnaldo Carvalho de Melo OPT_BOOLEAN('B', "no-buildid", &no_buildid, 669baa2f6ceSArnaldo Carvalho de Melo "do not collect buildids in perf.data"), 670023695d9SStephane Eranian OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 671023695d9SStephane Eranian "monitor event in cgroup name only", 672023695d9SStephane Eranian parse_cgroups), 67386470930SIngo Molnar OPT_END() 67486470930SIngo Molnar }; 67586470930SIngo Molnar 676f37a291cSIngo Molnar int cmd_record(int argc, const char **argv, const char *prefix __used) 67786470930SIngo Molnar { 67869aad6f1SArnaldo Carvalho de Melo int err = -ENOMEM; 67969aad6f1SArnaldo Carvalho de Melo struct perf_evsel *pos; 68086470930SIngo Molnar 681fbe96f29SStephane Eranian perf_header__set_cmdline(argc, argv); 682fbe96f29SStephane Eranian 6837e2ed097SArnaldo Carvalho de Melo evsel_list = perf_evlist__new(NULL, NULL); 684361c99a6SArnaldo Carvalho de Melo if (evsel_list == NULL) 685361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 686361c99a6SArnaldo Carvalho de Melo 687bca647aaSTom Zanussi argc = parse_options(argc, argv, record_options, record_usage, 688a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 6890f82ebc4SArnaldo Carvalho de Melo if (!argc && record_opts.target_pid == -1 && record_opts.target_tid == -1 && 6900f82ebc4SArnaldo Carvalho de Melo !record_opts.system_wide && !record_opts.cpu_list) 691bca647aaSTom Zanussi usage_with_options(record_usage, record_options); 69286470930SIngo Molnar 6937865e817SFrederic Weisbecker if (force && append_file) { 6947865e817SFrederic Weisbecker fprintf(stderr, "Can't overwrite and append at the same time." 6957865e817SFrederic Weisbecker " You need to choose between -f and -A"); 696bca647aaSTom Zanussi usage_with_options(record_usage, record_options); 6977865e817SFrederic Weisbecker } else if (append_file) { 6987865e817SFrederic Weisbecker write_mode = WRITE_APPEND; 6997865e817SFrederic Weisbecker } else { 7007865e817SFrederic Weisbecker write_mode = WRITE_FORCE; 7017865e817SFrederic Weisbecker } 7027865e817SFrederic Weisbecker 7030f82ebc4SArnaldo Carvalho de Melo if (nr_cgroups && !record_opts.system_wide) { 704023695d9SStephane Eranian fprintf(stderr, "cgroup monitoring only available in" 705023695d9SStephane Eranian " system-wide mode\n"); 706023695d9SStephane Eranian usage_with_options(record_usage, record_options); 707023695d9SStephane Eranian } 708023695d9SStephane Eranian 709655000e7SArnaldo Carvalho de Melo symbol__init(); 710baa2f6ceSArnaldo Carvalho de Melo 711ec80fde7SArnaldo Carvalho de Melo if (symbol_conf.kptr_restrict) 712646aaea6SArnaldo Carvalho de Melo pr_warning( 713646aaea6SArnaldo Carvalho de Melo "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" 714ec80fde7SArnaldo Carvalho de Melo "check /proc/sys/kernel/kptr_restrict.\n\n" 715646aaea6SArnaldo Carvalho de Melo "Samples in kernel functions may not be resolved if a suitable vmlinux\n" 716646aaea6SArnaldo Carvalho de Melo "file is not found in the buildid cache or in the vmlinux path.\n\n" 717646aaea6SArnaldo Carvalho de Melo "Samples in kernel modules won't be resolved at all.\n\n" 718646aaea6SArnaldo Carvalho de Melo "If some relocation was applied (e.g. kexec) symbols may be misresolved\n" 719646aaea6SArnaldo Carvalho de Melo "even with a suitable vmlinux or kallsyms file.\n\n"); 720ec80fde7SArnaldo Carvalho de Melo 721baa2f6ceSArnaldo Carvalho de Melo if (no_buildid_cache || no_buildid) 722a1ac1d3cSStephane Eranian disable_buildid_cache(); 723655000e7SArnaldo Carvalho de Melo 724361c99a6SArnaldo Carvalho de Melo if (evsel_list->nr_entries == 0 && 725361c99a6SArnaldo Carvalho de Melo perf_evlist__add_default(evsel_list) < 0) { 72669aad6f1SArnaldo Carvalho de Melo pr_err("Not enough memory for event selector list\n"); 72769aad6f1SArnaldo Carvalho de Melo goto out_symbol_exit; 728bbd36e5eSPeter Zijlstra } 72986470930SIngo Molnar 7300f82ebc4SArnaldo Carvalho de Melo if (record_opts.target_pid != -1) 7310f82ebc4SArnaldo Carvalho de Melo record_opts.target_tid = record_opts.target_pid; 732d6d901c2SZhang, Yanmin 7330f82ebc4SArnaldo Carvalho de Melo if (perf_evlist__create_maps(evsel_list, record_opts.target_pid, 7340f82ebc4SArnaldo Carvalho de Melo record_opts.target_tid, record_opts.cpu_list) < 0) 735dd7927f4SArnaldo Carvalho de Melo usage_with_options(record_usage, record_options); 73669aad6f1SArnaldo Carvalho de Melo 737361c99a6SArnaldo Carvalho de Melo list_for_each_entry(pos, &evsel_list->entries, node) { 7387e2ed097SArnaldo Carvalho de Melo if (perf_evsel__alloc_fd(pos, evsel_list->cpus->nr, 7397e2ed097SArnaldo Carvalho de Melo evsel_list->threads->nr) < 0) 74069aad6f1SArnaldo Carvalho de Melo goto out_free_fd; 741ad7f4e3fSArnaldo Carvalho de Melo if (perf_header__push_event(pos->attr.config, event_name(pos))) 742ad7f4e3fSArnaldo Carvalho de Melo goto out_free_fd; 743d6d901c2SZhang, Yanmin } 7445c581041SArnaldo Carvalho de Melo 7457e2ed097SArnaldo Carvalho de Melo if (perf_evlist__alloc_pollfd(evsel_list) < 0) 74639d17dacSArnaldo Carvalho de Melo goto out_free_fd; 747d6d901c2SZhang, Yanmin 7480f82ebc4SArnaldo Carvalho de Melo if (record_opts.user_interval != ULLONG_MAX) 7490f82ebc4SArnaldo Carvalho de Melo record_opts.default_interval = record_opts.user_interval; 7500f82ebc4SArnaldo Carvalho de Melo if (record_opts.user_freq != UINT_MAX) 7510f82ebc4SArnaldo Carvalho de Melo record_opts.freq = record_opts.user_freq; 752f9212819SFrederic Weisbecker 7537e4ff9e3SMike Galbraith /* 7547e4ff9e3SMike Galbraith * User specified count overrides default frequency. 7557e4ff9e3SMike Galbraith */ 7560f82ebc4SArnaldo Carvalho de Melo if (record_opts.default_interval) 7570f82ebc4SArnaldo Carvalho de Melo record_opts.freq = 0; 7580f82ebc4SArnaldo Carvalho de Melo else if (record_opts.freq) { 7590f82ebc4SArnaldo Carvalho de Melo record_opts.default_interval = record_opts.freq; 7607e4ff9e3SMike Galbraith } else { 7617e4ff9e3SMike Galbraith fprintf(stderr, "frequency and count are zero, aborting\n"); 76239d17dacSArnaldo Carvalho de Melo err = -EINVAL; 7635c581041SArnaldo Carvalho de Melo goto out_free_fd; 7647e4ff9e3SMike Galbraith } 7657e4ff9e3SMike Galbraith 76639d17dacSArnaldo Carvalho de Melo err = __cmd_record(argc, argv); 76739d17dacSArnaldo Carvalho de Melo out_free_fd: 7687e2ed097SArnaldo Carvalho de Melo perf_evlist__delete_maps(evsel_list); 769d65a458bSArnaldo Carvalho de Melo out_symbol_exit: 770d65a458bSArnaldo Carvalho de Melo symbol__exit(); 77139d17dacSArnaldo Carvalho de Melo return err; 77286470930SIngo Molnar } 773