]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - tools/perf/builtin-record.c
perf tools: Rename perf_evlist__mmap() to evlist__mmap()
[linux.git] / tools / perf / builtin-record.c
index d4f0430c2f497a30bf848edf2dc9a5ccc0d7c331..093d9ab5633eb0d2691882aa8d6f002fcccafdcc 100644 (file)
@@ -8,8 +8,6 @@
  */
 #include "builtin.h"
 
-#include "perf.h"
-
 #include "util/build-id.h"
 #include <subcmd/parse-options.h>
 #include "util/parse-events.h"
 #include "util/evlist.h"
 #include "util/evsel.h"
 #include "util/debug.h"
+#include "util/target.h"
 #include "util/session.h"
 #include "util/tool.h"
 #include "util/symbol.h"
+#include "util/record.h"
 #include "util/cpumap.h"
 #include "util/thread_map.h"
 #include "util/data.h"
 #include "util/trigger.h"
 #include "util/perf-hooks.h"
 #include "util/cpu-set-sched.h"
+#include "util/synthetic-events.h"
 #include "util/time-utils.h"
 #include "util/units.h"
 #include "util/bpf-event.h"
 #include "asm/bug.h"
+#include "perf.h"
 
 #include <errno.h>
 #include <inttypes.h>
@@ -52,6 +54,8 @@
 #include <signal.h>
 #include <sys/mman.h>
 #include <sys/wait.h>
+#include <linux/err.h>
+#include <linux/string.h>
 #include <linux/time64.h>
 #include <linux/zalloc.h>
 
@@ -115,7 +119,7 @@ static bool switch_output_time(struct record *rec)
               trigger_is_ready(&switch_output_trigger);
 }
 
-static int record__write(struct record *rec, struct perf_mmap *map __maybe_unused,
+static int record__write(struct record *rec, struct mmap *map __maybe_unused,
                         void *bf, size_t size)
 {
        struct perf_data_file *file = &rec->session->data->file;
@@ -164,7 +168,7 @@ static int record__aio_write(struct aiocb *cblock, int trace_fd,
        return rc;
 }
 
-static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock)
+static int record__aio_complete(struct mmap *md, struct aiocb *cblock)
 {
        void *rem_buf;
        off_t rem_off;
@@ -210,7 +214,7 @@ static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock)
        return rc;
 }
 
-static int record__aio_sync(struct perf_mmap *md, bool sync_all)
+static int record__aio_sync(struct mmap *md, bool sync_all)
 {
        struct aiocb **aiocb = md->aio.aiocb;
        struct aiocb *cblocks = md->aio.cblocks;
@@ -251,7 +255,7 @@ struct record_aio {
        size_t          size;
 };
 
-static int record__aio_pushfn(struct perf_mmap *map, void *to, void *buf, size_t size)
+static int record__aio_pushfn(struct mmap *map, void *to, void *buf, size_t size)
 {
        struct record_aio *aio = to;
 
@@ -296,7 +300,7 @@ static int record__aio_pushfn(struct perf_mmap *map, void *to, void *buf, size_t
        return size;
 }
 
-static int record__aio_push(struct record *rec, struct perf_mmap *map, off_t *off)
+static int record__aio_push(struct record *rec, struct mmap *map, off_t *off)
 {
        int ret, idx;
        int trace_fd = rec->session->data->file.fd;
@@ -347,13 +351,13 @@ static void record__aio_mmap_read_sync(struct record *rec)
 {
        int i;
        struct evlist *evlist = rec->evlist;
-       struct perf_mmap *maps = evlist->mmap;
+       struct mmap *maps = evlist->mmap;
 
        if (!record__aio_enabled(rec))
                return;
 
        for (i = 0; i < evlist->nr_mmaps; i++) {
-               struct perf_mmap *map = &maps[i];
+               struct mmap *map = &maps[i];
 
                if (map->base)
                        record__aio_sync(map, true);
@@ -383,7 +387,7 @@ static int record__aio_parse(const struct option *opt,
 #else /* HAVE_AIO_SUPPORT */
 static int nr_cblocks_max = 0;
 
-static int record__aio_push(struct record *rec __maybe_unused, struct perf_mmap *map __maybe_unused,
+static int record__aio_push(struct record *rec __maybe_unused, struct mmap *map __maybe_unused,
                            off_t *off __maybe_unused)
 {
        return -1;
@@ -435,7 +439,7 @@ static int record__mmap_flush_parse(const struct option *opt,
        if (!opts->mmap_flush)
                opts->mmap_flush = MMAP_FLUSH_DEFAULT;
 
-       flush_max = perf_evlist__mmap_size(opts->mmap_pages);
+       flush_max = evlist__mmap_size(opts->mmap_pages);
        flush_max /= 4;
        if (opts->mmap_flush > flush_max)
                opts->mmap_flush = flush_max;
@@ -478,7 +482,7 @@ static int process_synthesized_event(struct perf_tool *tool,
        return record__write(rec, NULL, event, event->header.size);
 }
 
-static int record__pushfn(struct perf_mmap *map, void *to, void *bf, size_t size)
+static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size)
 {
        struct record *rec = to;
 
@@ -523,7 +527,7 @@ static void record__sig_exit(void)
 #ifdef HAVE_AUXTRACE_SUPPORT
 
 static int record__process_auxtrace(struct perf_tool *tool,
-                                   struct perf_mmap *map,
+                                   struct mmap *map,
                                    union perf_event *event, void *data1,
                                    size_t len1, void *data2, size_t len2)
 {
@@ -561,7 +565,7 @@ static int record__process_auxtrace(struct perf_tool *tool,
 }
 
 static int record__auxtrace_mmap_read(struct record *rec,
-                                     struct perf_mmap *map)
+                                     struct mmap *map)
 {
        int ret;
 
@@ -577,7 +581,7 @@ static int record__auxtrace_mmap_read(struct record *rec,
 }
 
 static int record__auxtrace_mmap_read_snapshot(struct record *rec,
-                                              struct perf_mmap *map)
+                                              struct mmap *map)
 {
        int ret;
 
@@ -599,7 +603,7 @@ static int record__auxtrace_read_snapshot_all(struct record *rec)
        int rc = 0;
 
        for (i = 0; i < rec->evlist->nr_mmaps; i++) {
-               struct perf_mmap *map = &rec->evlist->mmap[i];
+               struct mmap *map = &rec->evlist->mmap[i];
 
                if (!map->auxtrace_mmap.base)
                        continue;
@@ -613,19 +617,35 @@ static int record__auxtrace_read_snapshot_all(struct record *rec)
        return rc;
 }
 
-static void record__read_auxtrace_snapshot(struct record *rec)
+static void record__read_auxtrace_snapshot(struct record *rec, bool on_exit)
 {
        pr_debug("Recording AUX area tracing snapshot\n");
        if (record__auxtrace_read_snapshot_all(rec) < 0) {
                trigger_error(&auxtrace_snapshot_trigger);
        } else {
-               if (auxtrace_record__snapshot_finish(rec->itr))
+               if (auxtrace_record__snapshot_finish(rec->itr, on_exit))
                        trigger_error(&auxtrace_snapshot_trigger);
                else
                        trigger_ready(&auxtrace_snapshot_trigger);
        }
 }
 
+static int record__auxtrace_snapshot_exit(struct record *rec)
+{
+       if (trigger_is_error(&auxtrace_snapshot_trigger))
+               return 0;
+
+       if (!auxtrace_record__snapshot_started &&
+           auxtrace_record__snapshot_start(rec->itr))
+               return -1;
+
+       record__read_auxtrace_snapshot(rec, true);
+       if (trigger_is_error(&auxtrace_snapshot_trigger))
+               return -1;
+
+       return 0;
+}
+
 static int record__auxtrace_init(struct record *rec)
 {
        int err;
@@ -648,13 +668,14 @@ static int record__auxtrace_init(struct record *rec)
 
 static inline
 int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
-                              struct perf_mmap *map __maybe_unused)
+                              struct mmap *map __maybe_unused)
 {
        return 0;
 }
 
 static inline
-void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
+void record__read_auxtrace_snapshot(struct record *rec __maybe_unused,
+                                   bool on_exit __maybe_unused)
 {
 }
 
@@ -664,6 +685,12 @@ int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
        return 0;
 }
 
+static inline
+int record__auxtrace_snapshot_exit(struct record *rec __maybe_unused)
+{
+       return 0;
+}
+
 static int record__auxtrace_init(struct record *rec __maybe_unused)
 {
        return 0;
@@ -680,7 +707,7 @@ static int record__mmap_evlist(struct record *rec,
        if (opts->affinity != PERF_AFFINITY_SYS)
                cpu__setup_cpunode_map();
 
-       if (perf_evlist__mmap_ex(evlist, opts->mmap_pages,
+       if (evlist__mmap_ex(evlist, opts->mmap_pages,
                                 opts->auxtrace_mmap_pages,
                                 opts->auxtrace_snapshot_mode,
                                 opts->nr_cblocks, opts->affinity,
@@ -761,6 +788,17 @@ static int record__open(struct record *rec)
                pos->supported = true;
        }
 
+       if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(evlist)) {
+               pr_warning(
+"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
+"check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\n\n"
+"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
+"file is not found in the buildid cache or in the vmlinux path.\n\n"
+"Samples in kernel modules won't be resolved at all.\n\n"
+"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
+"even with a suitable vmlinux or kallsyms file.\n\n");
+       }
+
        if (perf_evlist__apply_filters(evlist, &pos)) {
                pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
                        pos->filter, perf_evsel__name(pos), errno,
@@ -863,7 +901,7 @@ static struct perf_event_header finished_round_event = {
        .type = PERF_RECORD_FINISHED_ROUND,
 };
 
-static void record__adjust_affinity(struct record *rec, struct perf_mmap *map)
+static void record__adjust_affinity(struct record *rec, struct mmap *map)
 {
        if (rec->opts.affinity != PERF_AFFINITY_SYS &&
            !CPU_EQUAL(&rec->affinity_mask, &map->affinity_mask)) {
@@ -875,7 +913,7 @@ static void record__adjust_affinity(struct record *rec, struct perf_mmap *map)
 
 static size_t process_comp_header(void *record, size_t increment)
 {
-       struct compressed_event *event = record;
+       struct perf_record_compressed *event = record;
        size_t size = sizeof(*event);
 
        if (increment) {
@@ -893,7 +931,7 @@ static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_
                            void *src, size_t src_size)
 {
        size_t compressed;
-       size_t max_record_size = PERF_SAMPLE_MAX_SIZE - sizeof(struct compressed_event) - 1;
+       size_t max_record_size = PERF_SAMPLE_MAX_SIZE - sizeof(struct perf_record_compressed) - 1;
 
        compressed = zstd_compress_stream_to_records(&session->zstd_data, dst, dst_size, src, src_size,
                                                     max_record_size, process_comp_header);
@@ -910,7 +948,7 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist,
        u64 bytes_written = rec->bytes_written;
        int i;
        int rc = 0;
-       struct perf_mmap *maps;
+       struct mmap *maps;
        int trace_fd = rec->data.file.fd;
        off_t off = 0;
 
@@ -929,7 +967,7 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist,
 
        for (i = 0; i < evlist->nr_mmaps; i++) {
                u64 flush = 0;
-               struct perf_mmap *map = &maps[i];
+               struct mmap *map = &maps[i];
 
                if (map->base) {
                        record__adjust_affinity(rec, map);
@@ -1155,15 +1193,6 @@ static void workload_exec_failed_signal(int signo __maybe_unused,
 static void snapshot_sig_handler(int sig);
 static void alarm_sig_handler(int sig);
 
-int __weak
-perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
-                           struct perf_tool *tool __maybe_unused,
-                           perf_event__handler_t process __maybe_unused,
-                           struct machine *machine __maybe_unused)
-{
-       return 0;
-}
-
 static const struct perf_event_mmap_page *
 perf_evlist__pick_pc(struct evlist *evlist)
 {
@@ -1275,7 +1304,7 @@ static int record__synthesize(struct record *rec, bool tail)
        if (err)
                goto out;
 
-       err = perf_event__synthesize_thread_map2(&rec->tool, rec->evlist->threads,
+       err = perf_event__synthesize_thread_map2(&rec->tool, rec->evlist->core.threads,
                                                 process_synthesized_event,
                                                NULL);
        if (err < 0) {
@@ -1295,7 +1324,7 @@ static int record__synthesize(struct record *rec, bool tail)
        if (err < 0)
                pr_warning("Couldn't synthesize bpf events.\n");
 
-       err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
+       err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->core.threads,
                                            process_synthesized_event, opts->sample_address,
                                            1);
 out:
@@ -1337,9 +1366,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
        }
 
        session = perf_session__new(data, false, tool);
-       if (session == NULL) {
+       if (IS_ERR(session)) {
                pr_err("Perf session creation failed.\n");
-               return -1;
+               return PTR_ERR(session);
        }
 
        fd = perf_data__fd(data);
@@ -1536,7 +1565,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                if (auxtrace_record__snapshot_started) {
                        auxtrace_record__snapshot_started = 0;
                        if (!trigger_is_error(&auxtrace_snapshot_trigger))
-                               record__read_auxtrace_snapshot(rec);
+                               record__read_auxtrace_snapshot(rec, false);
                        if (trigger_is_error(&auxtrace_snapshot_trigger)) {
                                pr_err("AUX area tracing snapshot failed\n");
                                err = -1;
@@ -1609,9 +1638,13 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                        disabled = true;
                }
        }
+
        trigger_off(&auxtrace_snapshot_trigger);
        trigger_off(&switch_output_trigger);
 
+       if (opts->auxtrace_snapshot_on_exit)
+               record__auxtrace_snapshot_exit(rec);
+
        if (forks && workload_exec_errno) {
                char msg[STRERR_BUFSIZE];
                const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
@@ -1947,7 +1980,7 @@ static int record__parse_mmap_pages(const struct option *opt,
 
 static void switch_output_size_warn(struct record *rec)
 {
-       u64 wakeup_size = perf_evlist__mmap_size(rec->opts.mmap_pages);
+       u64 wakeup_size = evlist__mmap_size(rec->opts.mmap_pages);
        struct switch_output *s = &rec->switch_output;
 
        wakeup_size /= 2;
@@ -2342,16 +2375,6 @@ int cmd_record(int argc, const char **argv)
 
        err = -ENOMEM;
 
-       if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(rec->evlist))
-               pr_warning(
-"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
-"check /proc/sys/kernel/kptr_restrict.\n\n"
-"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
-"file is not found in the buildid cache or in the vmlinux path.\n\n"
-"Samples in kernel modules won't be resolved at all.\n\n"
-"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
-"even with a suitable vmlinux or kallsyms file.\n\n");
-
        if (rec->no_buildid_cache || rec->no_buildid) {
                disable_buildid_cache();
        } else if (rec->switch_output.enabled) {