^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include "builtin.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include "util/counts.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include "util/debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "util/dso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <subcmd/exec-cmd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "util/header.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <subcmd/parse-options.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "util/perf_regs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "util/session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "util/tool.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "util/map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "util/srcline.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "util/symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "util/thread.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "util/trace-event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "util/evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "util/evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "util/evsel_fprintf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "util/evswitch.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "util/sort.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "util/data.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "util/auxtrace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "util/cpumap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "util/thread_map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "util/stat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "util/color.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "util/string2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "util/thread-stack.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "util/time-utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "util/path.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "ui/ui.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "print_binary.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "archinsn.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/stringify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/time64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <sys/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "asm/bug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "util/mem-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "util/dump-insn.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <dirent.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <sys/param.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <subcmd/pager.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <perf/evlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include "util/record.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include "util/util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include "perf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static char const *script_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static char const *generate_script_lang;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static bool reltime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static bool deltatime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static u64 initial_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static u64 previous_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static bool debug_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static u64 last_timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static u64 nr_unordered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static bool no_callchain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static bool latency_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static bool system_wide;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static bool print_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static const char *cpu_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static struct perf_stat_config stat_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static int max_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static bool native_arch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) enum perf_output_field {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) PERF_OUTPUT_COMM = 1ULL << 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) PERF_OUTPUT_TID = 1ULL << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) PERF_OUTPUT_PID = 1ULL << 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) PERF_OUTPUT_TIME = 1ULL << 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) PERF_OUTPUT_CPU = 1ULL << 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) PERF_OUTPUT_EVNAME = 1ULL << 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) PERF_OUTPUT_TRACE = 1ULL << 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) PERF_OUTPUT_IP = 1ULL << 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) PERF_OUTPUT_SYM = 1ULL << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) PERF_OUTPUT_DSO = 1ULL << 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) PERF_OUTPUT_ADDR = 1ULL << 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) PERF_OUTPUT_SYMOFFSET = 1ULL << 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) PERF_OUTPUT_SRCLINE = 1ULL << 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) PERF_OUTPUT_PERIOD = 1ULL << 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) PERF_OUTPUT_IREGS = 1ULL << 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) PERF_OUTPUT_BRSTACK = 1ULL << 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) PERF_OUTPUT_BRSTACKSYM = 1ULL << 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) PERF_OUTPUT_DATA_SRC = 1ULL << 17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) PERF_OUTPUT_WEIGHT = 1ULL << 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) PERF_OUTPUT_BPF_OUTPUT = 1ULL << 19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) PERF_OUTPUT_CALLINDENT = 1ULL << 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) PERF_OUTPUT_INSN = 1ULL << 21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) PERF_OUTPUT_INSNLEN = 1ULL << 22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) PERF_OUTPUT_BRSTACKINSN = 1ULL << 23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) PERF_OUTPUT_BRSTACKOFF = 1ULL << 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) PERF_OUTPUT_SYNTH = 1ULL << 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) PERF_OUTPUT_PHYS_ADDR = 1ULL << 26,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) PERF_OUTPUT_UREGS = 1ULL << 27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) PERF_OUTPUT_METRIC = 1ULL << 28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) PERF_OUTPUT_MISC = 1ULL << 29,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) PERF_OUTPUT_SRCCODE = 1ULL << 30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) PERF_OUTPUT_IPC = 1ULL << 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) PERF_OUTPUT_TOD = 1ULL << 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct perf_script {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct perf_tool tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct perf_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) bool show_task_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) bool show_mmap_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) bool show_switch_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) bool show_namespace_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) bool show_lost_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) bool show_round_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) bool show_bpf_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) bool show_cgroup_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) bool show_text_poke_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) bool allocated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) bool per_event_dump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) bool stitch_lbr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct evswitch evswitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct perf_cpu_map *cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct perf_thread_map *threads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int name_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) const char *time_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct perf_time_interval *ptime_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int range_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int range_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct output_option {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) const char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) enum perf_output_field field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) } all_output_options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {.str = "comm", .field = PERF_OUTPUT_COMM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {.str = "tid", .field = PERF_OUTPUT_TID},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {.str = "pid", .field = PERF_OUTPUT_PID},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {.str = "time", .field = PERF_OUTPUT_TIME},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {.str = "cpu", .field = PERF_OUTPUT_CPU},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {.str = "event", .field = PERF_OUTPUT_EVNAME},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {.str = "trace", .field = PERF_OUTPUT_TRACE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {.str = "ip", .field = PERF_OUTPUT_IP},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {.str = "sym", .field = PERF_OUTPUT_SYM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {.str = "dso", .field = PERF_OUTPUT_DSO},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {.str = "addr", .field = PERF_OUTPUT_ADDR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {.str = "period", .field = PERF_OUTPUT_PERIOD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {.str = "iregs", .field = PERF_OUTPUT_IREGS},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {.str = "uregs", .field = PERF_OUTPUT_UREGS},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {.str = "weight", .field = PERF_OUTPUT_WEIGHT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {.str = "bpf-output", .field = PERF_OUTPUT_BPF_OUTPUT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {.str = "insn", .field = PERF_OUTPUT_INSN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {.str = "synth", .field = PERF_OUTPUT_SYNTH},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {.str = "metric", .field = PERF_OUTPUT_METRIC},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {.str = "misc", .field = PERF_OUTPUT_MISC},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {.str = "srccode", .field = PERF_OUTPUT_SRCCODE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {.str = "ipc", .field = PERF_OUTPUT_IPC},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {.str = "tod", .field = PERF_OUTPUT_TOD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) OUTPUT_TYPE_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* default set to maintain compatibility with current format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) bool user_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) bool wildcard_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) unsigned int print_ip_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u64 fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u64 invalid_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u64 user_set_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u64 user_unset_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) } output[OUTPUT_TYPE_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) [PERF_TYPE_HARDWARE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .user_set = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) [PERF_TYPE_SOFTWARE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .user_set = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) PERF_OUTPUT_BPF_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .invalid_fields = PERF_OUTPUT_TRACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) [PERF_TYPE_TRACEPOINT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .user_set = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) [PERF_TYPE_HW_CACHE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .user_set = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) [PERF_TYPE_RAW] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .user_set = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) [PERF_TYPE_BREAKPOINT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .user_set = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) [OUTPUT_TYPE_SYNTH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .user_set = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) PERF_OUTPUT_DSO | PERF_OUTPUT_SYNTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct evsel_script {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) char *filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) u64 samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* For metric output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int gnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static inline struct evsel_script *evsel_script(struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return (struct evsel_script *)evsel->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static struct evsel_script *perf_evsel_script__new(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct perf_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct evsel_script *es = zalloc(sizeof(*es));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (es != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (asprintf(&es->filename, "%s.%s.dump", data->file.path, evsel__name(evsel)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) es->fp = fopen(es->filename, "w");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (es->fp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) goto out_free_filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return es;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) out_free_filename:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) zfree(&es->filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) free(es);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static void perf_evsel_script__delete(struct evsel_script *es)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) zfree(&es->filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) fclose(es->fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) es->fp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) free(es);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int perf_evsel_script__fprintf(struct evsel_script *es, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct stat st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) fstat(fileno(es->fp), &st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return fprintf(fp, "[ perf script: Wrote %.3f MB %s (%" PRIu64 " samples) ]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) st.st_size / 1024.0 / 1024.0, es->filename, es->samples);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static inline int output_type(unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) case PERF_TYPE_SYNTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return OUTPUT_TYPE_SYNTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static inline unsigned int attr_type(unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case OUTPUT_TYPE_SYNTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return PERF_TYPE_SYNTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static bool output_set_by_user(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (output[j].user_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static const char *output_field2str(enum perf_output_field field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int i, imax = ARRAY_SIZE(all_output_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) const char *str = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) for (i = 0; i < imax; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (all_output_options[i].field == field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) str = all_output_options[i].str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) #define PRINT_FIELD(x) (output[output_type(attr->type)].fields & PERF_OUTPUT_##x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static int evsel__do_check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) enum perf_output_field field, bool allow_user_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct perf_event_attr *attr = &evsel->core.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int type = output_type(attr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) const char *evname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (attr->sample_type & sample_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (output[type].user_set_fields & field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (allow_user_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) evname = evsel__name(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) pr_err("Samples for '%s' event do not have %s attribute set. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) "Cannot print '%s' field.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) evname, sample_msg, output_field2str(field));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* user did not ask for it explicitly so remove from the default list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) output[type].fields &= ~field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) evname = evsel__name(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) pr_debug("Samples for '%s' event do not have %s attribute set. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) "Skipping '%s' field.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) evname, sample_msg, output_field2str(field));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) enum perf_output_field field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return evsel__do_check_stype(evsel, sample_type, sample_msg, field, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static int evsel__check_attr(struct evsel *evsel, struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct perf_event_attr *attr = &evsel->core.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) bool allow_user_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (perf_header__has_feat(&session->header, HEADER_STAT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) allow_user_set = perf_header__has_feat(&session->header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) HEADER_AUXTRACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (PRINT_FIELD(TRACE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) !perf_session__has_traces(session, "record -R"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (PRINT_FIELD(IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", PERF_OUTPUT_IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (PRINT_FIELD(ADDR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", PERF_OUTPUT_ADDR, allow_user_set))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (PRINT_FIELD(DATA_SRC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) evsel__check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", PERF_OUTPUT_DATA_SRC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (PRINT_FIELD(WEIGHT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT, "WEIGHT", PERF_OUTPUT_WEIGHT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (PRINT_FIELD(SYM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) pr_err("Display of symbols requested but neither sample IP nor "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) "sample address\navailable. Hence, no addresses to convert "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) "to symbols.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) pr_err("Display of offsets requested but symbol is not"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) "selected.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (PRINT_FIELD(DSO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) pr_err("Display of DSO requested but no address to convert.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) pr_err("Display of source line number requested but sample IP is not\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) "selected. Hence, no address to lookup the source line number.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (PRINT_FIELD(BRSTACKINSN) && !allow_user_set &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) pr_err("Display of branch stack assembler requested, but non all-branch filter set\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) "Hint: run 'perf record -b ...'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", PERF_OUTPUT_TID|PERF_OUTPUT_PID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (PRINT_FIELD(TIME) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", PERF_OUTPUT_TIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (PRINT_FIELD(CPU) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", PERF_OUTPUT_CPU, allow_user_set))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (PRINT_FIELD(IREGS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) evsel__do_check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS, allow_user_set))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (PRINT_FIELD(UREGS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS", PERF_OUTPUT_UREGS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (PRINT_FIELD(PHYS_ADDR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static void set_print_ip_opts(struct perf_event_attr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned int type = output_type(attr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) output[type].print_ip_opts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (PRINT_FIELD(IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) output[type].print_ip_opts |= EVSEL__PRINT_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (PRINT_FIELD(SYM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) output[type].print_ip_opts |= EVSEL__PRINT_SYM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (PRINT_FIELD(DSO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) output[type].print_ip_opts |= EVSEL__PRINT_DSO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (PRINT_FIELD(SYMOFFSET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (PRINT_FIELD(SRCLINE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * verify all user requested events exist and the samples
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * have the expected data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static int perf_session__check_output_opt(struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) bool tod = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) unsigned int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) evsel = perf_session__find_first_evtype(session, attr_type(j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * even if fields is set to 0 (ie., show nothing) event must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * exist if user explicitly includes it on the command line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!evsel && output[j].user_set && !output[j].wildcard_set &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) j != OUTPUT_TYPE_SYNTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) pr_err("%s events do not exist. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) "Remove corresponding -F option to proceed.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) event_type(j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (evsel && output[j].fields &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) evsel__check_attr(evsel, session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (evsel == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) set_print_ip_opts(&evsel->core.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) tod |= output[j].fields & PERF_OUTPUT_TOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (!no_callchain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) bool use_callchain = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) bool not_pipe = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) evlist__for_each_entry(session->evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) not_pipe = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (evsel__has_callchain(evsel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) use_callchain = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (not_pipe && !use_callchain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) symbol_conf.use_callchain = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * set default for tracepoints to print symbols only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * if callchains are present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (symbol_conf.use_callchain &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) !output[PERF_TYPE_TRACEPOINT].user_set) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) j = PERF_TYPE_TRACEPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) evlist__for_each_entry(session->evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (evsel->core.attr.type != j)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (evsel__has_callchain(evsel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) output[j].fields |= PERF_OUTPUT_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) output[j].fields |= PERF_OUTPUT_SYM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) output[j].fields |= PERF_OUTPUT_SYMOFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) output[j].fields |= PERF_OUTPUT_DSO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) set_print_ip_opts(&evsel->core.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (tod && !session->header.env.clock.enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) pr_err("Can't provide 'tod' time, missing clock data. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) "Please record with -k/--clockid option.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) unsigned i = 0, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) int printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (!regs || !regs->regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) u64 val = regs->regs[i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) #define DEFAULT_TOD_FMT "%F %H:%M:%S"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static char*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) tod_scnprintf(struct perf_script *script, char *buf, int buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) u64 timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) u64 tod_ns, clockid_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct perf_env *env;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) unsigned long nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct tm ltime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) char date[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) time_t sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) buf[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (buflen < 64 || !script)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) env = &script->session->header.env;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (!env->clock.enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) scnprintf(buf, buflen, "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) clockid_ns = env->clock.clockid_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) tod_ns = env->clock.tod_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (timestamp > clockid_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) tod_ns += timestamp - clockid_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) tod_ns -= clockid_ns - timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) sec = (time_t) (tod_ns / NSEC_PER_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) nsec = tod_ns - sec * NSEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (localtime_r(&sec, <ime) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) scnprintf(buf, buflen, "failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) strftime(date, sizeof(date), DEFAULT_TOD_FMT, <ime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (symbol_conf.nanosecs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) snprintf(buf, buflen, "%s.%09lu", date, nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) snprintf(buf, buflen, "%s.%06lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) date, nsec / NSEC_PER_USEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int perf_sample__fprintf_iregs(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct perf_event_attr *attr, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return perf_sample__fprintf_regs(&sample->intr_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) attr->sample_regs_intr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static int perf_sample__fprintf_uregs(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct perf_event_attr *attr, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return perf_sample__fprintf_regs(&sample->user_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) attr->sample_regs_user, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int perf_sample__fprintf_start(struct perf_script *script,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) u32 type, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct perf_event_attr *attr = &evsel->core.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) unsigned long secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) unsigned long long nsecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) char tstr[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (PRINT_FIELD(COMM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) const char *comm = thread ? thread__comm_str(thread) : ":-1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (latency_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) printed += fprintf(fp, "%8.8s ", comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) else if (PRINT_FIELD(IP) && evsel__has_callchain(evsel) && symbol_conf.use_callchain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) printed += fprintf(fp, "%s ", comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) printed += fprintf(fp, "%16s ", comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) printed += fprintf(fp, "%5d/%-5d ", sample->pid, sample->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) else if (PRINT_FIELD(PID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) printed += fprintf(fp, "%5d ", sample->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) else if (PRINT_FIELD(TID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) printed += fprintf(fp, "%5d ", sample->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (PRINT_FIELD(CPU)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (latency_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) printed += fprintf(fp, "%3d ", sample->cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) printed += fprintf(fp, "[%03d] ", sample->cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (PRINT_FIELD(MISC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) #define has(m) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) (sample->misc & PERF_RECORD_MISC_##m) == PERF_RECORD_MISC_##m
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (has(KERNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ret += fprintf(fp, "K");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (has(USER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ret += fprintf(fp, "U");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (has(HYPERVISOR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ret += fprintf(fp, "H");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (has(GUEST_KERNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ret += fprintf(fp, "G");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (has(GUEST_USER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ret += fprintf(fp, "g");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) case PERF_RECORD_MMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case PERF_RECORD_MMAP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (has(MMAP_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) ret += fprintf(fp, "M");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case PERF_RECORD_COMM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (has(COMM_EXEC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) ret += fprintf(fp, "E");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) case PERF_RECORD_SWITCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) case PERF_RECORD_SWITCH_CPU_WIDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (has(SWITCH_OUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ret += fprintf(fp, "S");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) ret += fprintf(fp, "p");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) #undef has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ret += fprintf(fp, "%*s", 6 - ret, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) printed += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (PRINT_FIELD(TOD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) tod_scnprintf(script, tstr, sizeof(tstr), sample->time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) printed += fprintf(fp, "%s ", tstr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (PRINT_FIELD(TIME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) u64 t = sample->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (reltime) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (!initial_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) initial_time = sample->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) t = sample->time - initial_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) } else if (deltatime) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (previous_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) t = sample->time - previous_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) t = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) previous_time = sample->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) nsecs = t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) secs = nsecs / NSEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) nsecs -= secs * NSEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (symbol_conf.nanosecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) char sample_time[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) timestamp__scnprintf_usec(t, sample_time, sizeof(sample_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) printed += fprintf(fp, "%12s: ", sample_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) static inline char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) mispred_str(struct branch_entry *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (!(br->flags.mispred || br->flags.predicted))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return br->flags.predicted ? 'P' : 'M';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static int perf_sample__fprintf_brstack(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct perf_event_attr *attr, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) struct branch_stack *br = sample->branch_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct branch_entry *entries = perf_sample__branch_entries(sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct addr_location alf, alt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) u64 i, from, to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) int printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (!(br && br->nr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) for (i = 0; i < br->nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) from = entries[i].from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) to = entries[i].to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (PRINT_FIELD(DSO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) memset(&alf, 0, sizeof(alf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) memset(&alt, 0, sizeof(alt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) thread__find_map_fb(thread, sample->cpumode, from, &alf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) thread__find_map_fb(thread, sample->cpumode, to, &alt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) printed += fprintf(fp, " 0x%"PRIx64, from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (PRINT_FIELD(DSO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) printed += fprintf(fp, "(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) printed += map__fprintf_dsoname(alf.map, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) printed += fprintf(fp, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) printed += fprintf(fp, "/0x%"PRIx64, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (PRINT_FIELD(DSO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) printed += fprintf(fp, "(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) printed += map__fprintf_dsoname(alt.map, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) printed += fprintf(fp, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) printed += fprintf(fp, "/%c/%c/%c/%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) mispred_str(entries + i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) entries[i].flags.in_tx ? 'X' : '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) entries[i].flags.abort ? 'A' : '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) entries[i].flags.cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct perf_event_attr *attr, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct branch_stack *br = sample->branch_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct branch_entry *entries = perf_sample__branch_entries(sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct addr_location alf, alt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) u64 i, from, to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) int printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (!(br && br->nr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) for (i = 0; i < br->nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) memset(&alf, 0, sizeof(alf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) memset(&alt, 0, sizeof(alt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) from = entries[i].from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) to = entries[i].to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (PRINT_FIELD(DSO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) printed += fprintf(fp, "(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) printed += map__fprintf_dsoname(alf.map, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) printed += fprintf(fp, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) printed += fprintf(fp, "%c", '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (PRINT_FIELD(DSO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) printed += fprintf(fp, "(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) printed += map__fprintf_dsoname(alt.map, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) printed += fprintf(fp, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) printed += fprintf(fp, "/%c/%c/%c/%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) mispred_str(entries + i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) entries[i].flags.in_tx ? 'X' : '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) entries[i].flags.abort ? 'A' : '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) entries[i].flags.cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) struct perf_event_attr *attr, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct branch_stack *br = sample->branch_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct branch_entry *entries = perf_sample__branch_entries(sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct addr_location alf, alt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) u64 i, from, to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) int printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (!(br && br->nr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) for (i = 0; i < br->nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) memset(&alf, 0, sizeof(alf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) memset(&alt, 0, sizeof(alt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) from = entries[i].from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) to = entries[i].to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) !alf.map->dso->adjust_symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) from = map__map_ip(alf.map, from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) !alt.map->dso->adjust_symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) to = map__map_ip(alt.map, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) printed += fprintf(fp, " 0x%"PRIx64, from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (PRINT_FIELD(DSO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) printed += fprintf(fp, "(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) printed += map__fprintf_dsoname(alf.map, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) printed += fprintf(fp, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) printed += fprintf(fp, "/0x%"PRIx64, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (PRINT_FIELD(DSO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) printed += fprintf(fp, "(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) printed += map__fprintf_dsoname(alt.map, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) printed += fprintf(fp, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) printed += fprintf(fp, "/%c/%c/%c/%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) mispred_str(entries + i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) entries[i].flags.in_tx ? 'X' : '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) entries[i].flags.abort ? 'A' : '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) entries[i].flags.cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) #define MAXBB 16384UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) static int grab_bb(u8 *buffer, u64 start, u64 end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) struct machine *machine, struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) bool *is64bit, u8 *cpumode, bool last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) long offset, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct addr_location al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) bool kernel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (!start || !end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) kernel = machine__kernel_ip(machine, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) *cpumode = PERF_RECORD_MISC_KERNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) *cpumode = PERF_RECORD_MISC_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * Block overlaps between kernel and user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * This can happen due to ring filtering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) * On Intel CPUs the entry into the kernel is filtered,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * but the exit is not. Let the caller patch it up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (kernel != machine__kernel_ip(machine, end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) memset(&al, 0, sizeof(al));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (end - start > MAXBB - MAXINSN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (!thread__find_map(thread, *cpumode, start, &al) || !al.map->dso) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /* Load maps to ensure dso->is_64_bit has been updated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) map__load(al.map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) offset = al.map->map_ip(al.map, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) len = dso__data_read_offset(al.map->dso, machine, offset, (u8 *)buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) end - start + MAXINSN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) *is64bit = al.map->dso->is_64_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (len <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static int map__fprintf_srccode(struct map *map, u64 addr, FILE *fp, struct srccode_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) char *srcfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) unsigned line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) char *srccode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (!map || !map->dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) srcfile = get_srcline_split(map->dso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) map__rip_2objdump(map, addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) &line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (!srcfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) /* Avoid redundant printing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (state &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) state->srcfile &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) !strcmp(state->srcfile, srcfile) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) state->line == line) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) free(srcfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) srccode = find_sourceline(srcfile, line, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (!srccode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) goto out_free_line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) ret = fprintf(fp, "|%-8d %.*s", line, len, srccode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) state->srcfile = srcfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) state->line = line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) out_free_line:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) free(srcfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct addr_location al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) memset(&al, 0, sizeof(al));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) thread__find_map(thread, cpumode, addr, &al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (!al.map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) ret = map__fprintf_srccode(al.map, al.addr, stdout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) &thread->srccode_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) ret += printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct perf_insn *x, u8 *inbuf, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) int insn, FILE *fp, int *total_cycles)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) int printed = fprintf(fp, "\t%016" PRIx64 "\t%-30s\t#%s%s%s%s", ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) dump_insn(x, ip, inbuf, len, NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) en->flags.predicted ? " PRED" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) en->flags.mispred ? " MISPRED" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) en->flags.in_tx ? " INTX" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) en->flags.abort ? " ABORT" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (en->flags.cycles) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) *total_cycles += en->flags.cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) printed += fprintf(fp, " %d cycles [%d]", en->flags.cycles, *total_cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return printed + fprintf(fp, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int ip__fprintf_sym(uint64_t addr, struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) u8 cpumode, int cpu, struct symbol **lastsym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct perf_event_attr *attr, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct addr_location al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) int off, printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) memset(&al, 0, sizeof(al));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) thread__find_map(thread, cpumode, addr, &al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) al.cpu = cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) al.sym = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (al.map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) al.sym = map__find_symbol(al.map, al.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (!al.sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (al.addr < al.sym->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) off = al.addr - al.sym->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) off = al.addr - al.map->start - al.sym->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) printed += fprintf(fp, "\t%s", al.sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) printed += fprintf(fp, "%+d", off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) printed += fprintf(fp, ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (PRINT_FIELD(SRCLINE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) printed += map__fprintf_srcline(al.map, al.addr, "\t", fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) printed += fprintf(fp, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) *lastsym = al.sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) struct machine *machine, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) struct branch_stack *br = sample->branch_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) struct branch_entry *entries = perf_sample__branch_entries(sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) u64 start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) int i, insn, len, nr, ilen, printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) struct perf_insn x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) u8 buffer[MAXBB];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) unsigned off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct symbol *lastsym = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) int total_cycles = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (!(br && br->nr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) nr = br->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (max_blocks && nr > max_blocks + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) nr = max_blocks + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) x.thread = thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) x.cpu = sample->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) printed += fprintf(fp, "%c", '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) /* Handle first from jump, of which we don't know the entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) len = grab_bb(buffer, entries[nr-1].from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) entries[nr-1].from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) machine, thread, &x.is64bit, &x.cpumode, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) printed += ip__fprintf_sym(entries[nr - 1].from, thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) x.cpumode, x.cpu, &lastsym, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) &x, buffer, len, 0, fp, &total_cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (PRINT_FIELD(SRCCODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) printed += print_srccode(thread, x.cpumode, entries[nr - 1].from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /* Print all blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) for (i = nr - 2; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (entries[i].from || entries[i].to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) entries[i].from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) entries[i].to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) start = entries[i + 1].to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) end = entries[i].from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /* Patch up missing kernel transfers due to ring filters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (len == -ENXIO && i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) end = entries[--i].from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) pr_debug("\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (len <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) insn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) for (off = 0; off < (unsigned)len; off += ilen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) uint64_t ip = start + off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (ip == end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) &total_cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (PRINT_FIELD(SRCCODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) printed += print_srccode(thread, x.cpumode, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) ilen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) dump_insn(&x, ip, buffer + off, len - off, &ilen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (ilen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (PRINT_FIELD(SRCCODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) print_srccode(thread, x.cpumode, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) insn++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (off != end - start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) printed += fprintf(fp, "\tmismatch of LBR data and executable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) * Hit the branch? In this case we are already done, and the target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * has not been executed yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (entries[0].from == sample->ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (entries[0].flags.abort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * Print final block upto sample
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * Due to pipeline delays the LBRs might be missing a branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) * or two, which can result in very large or negative blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * between final branch and sample. When this happens just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * continue walking after the last TO until we hit a branch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) start = entries[0].to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) end = sample->ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (end < start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) /* Missing jump. Scan 128 bytes for the next branch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) end = start + 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) /* Print at least last IP if basic block did not work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) len = grab_bb(buffer, sample->ip, sample->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) machine, thread, &x.is64bit, &x.cpumode, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (len <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) dump_insn(&x, sample->ip, buffer, len, NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (PRINT_FIELD(SRCCODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) print_srccode(thread, x.cpumode, sample->ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) for (off = 0; off <= end - start; off += ilen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) ilen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", start + off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) dump_insn(&x, start + off, buffer + off, len - off, &ilen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (ilen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) if (arch_is_branch(buffer + off, len - off, x.is64bit) && start + off != sample->ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * Hit a missing branch. Just stop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) printed += fprintf(fp, "\t... not reaching sample ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (PRINT_FIELD(SRCCODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) print_srccode(thread, x.cpumode, start + off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) static int perf_sample__fprintf_addr(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct perf_event_attr *attr, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct addr_location al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) int printed = fprintf(fp, "%16" PRIx64, sample->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) if (!sample_addr_correlates_sym(attr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) thread__resolve(thread, &al, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (PRINT_FIELD(SYM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) printed += fprintf(fp, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (PRINT_FIELD(SYMOFFSET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) printed += symbol__fprintf_symname(al.sym, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (PRINT_FIELD(DSO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) printed += fprintf(fp, " (");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) printed += map__fprintf_dsoname(al.map, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) printed += fprintf(fp, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) static const char *resolve_branch_sym(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) struct addr_location *al,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) u64 *ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) struct addr_location addr_al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) struct perf_event_attr *attr = &evsel->core.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) const char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (sample_addr_correlates_sym(attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) thread__resolve(thread, &addr_al, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (addr_al.sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) name = addr_al.sym->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) *ip = sample->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) *ip = sample->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) } else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (al->sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) name = al->sym->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) *ip = sample->ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static int perf_sample__fprintf_callindent(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) struct addr_location *al, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) struct perf_event_attr *attr = &evsel->core.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) size_t depth = thread_stack__depth(thread, sample->cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) const char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) static int spacing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) int dlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) u64 ip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) * The 'return' has already been popped off the stack so the depth has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) * to be adjusted to match the 'call'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) if (thread->ts && sample->flags & PERF_IP_FLAG_RETURN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) depth += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) name = resolve_branch_sym(sample, evsel, thread, al, &ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (PRINT_FIELD(DSO) && !(PRINT_FIELD(IP) || PRINT_FIELD(ADDR))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) dlen += fprintf(fp, "(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) dlen += map__fprintf_dsoname(al->map, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) dlen += fprintf(fp, ")\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) if (name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) else if (ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) * Try to keep the output length from changing frequently so that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) * output lines up more nicely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (len > spacing || (len && len < spacing - 52))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) spacing = round_up(len + 4, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (len < spacing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) len += fprintf(fp, "%*s", spacing - len, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return len + dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) __weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) struct thread *thread __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) struct machine *machine __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) static int perf_sample__fprintf_insn(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) struct machine *machine, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) int printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) if (sample->insn_len == 0 && native_arch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) arch_fetch_insn(sample, thread, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (PRINT_FIELD(INSNLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) printed += fprintf(fp, " ilen: %d", sample->insn_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (PRINT_FIELD(INSN) && sample->insn_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) printed += fprintf(fp, " insn:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) for (i = 0; i < sample->insn_len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) printed += fprintf(fp, " %02x", (unsigned char)sample->insn[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (PRINT_FIELD(BRSTACKINSN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) printed += perf_sample__fprintf_brstackinsn(sample, thread, attr, machine, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static int perf_sample__fprintf_ipc(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct perf_event_attr *attr, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) unsigned int ipc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) if (!PRINT_FIELD(IPC) || !sample->cyc_cnt || !sample->insn_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) ipc = (sample->insn_cnt * 100) / sample->cyc_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return fprintf(fp, " \t IPC: %u.%02u (%" PRIu64 "/%" PRIu64 ") ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) ipc / 100, ipc % 100, sample->insn_cnt, sample->cyc_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) static int perf_sample__fprintf_bts(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) struct addr_location *al,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct machine *machine, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) struct perf_event_attr *attr = &evsel->core.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) unsigned int type = output_type(attr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) bool print_srcline_last = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) int printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if (PRINT_FIELD(CALLINDENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) /* print branch_from information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (PRINT_FIELD(IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) unsigned int print_opts = output[type].print_ip_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) struct callchain_cursor *cursor = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (symbol_conf.use_callchain && sample->callchain &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) sample, NULL, NULL, scripting_max_stack) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) cursor = &callchain_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (cursor == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) printed += fprintf(fp, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (print_opts & EVSEL__PRINT_SRCLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) print_srcline_last = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) print_opts &= ~EVSEL__PRINT_SRCLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) printed += fprintf(fp, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) symbol_conf.bt_stop_list, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) /* print branch_to information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (PRINT_FIELD(ADDR) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) !output[type].user_set)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) printed += fprintf(fp, " => ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) printed += perf_sample__fprintf_addr(sample, thread, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) printed += perf_sample__fprintf_ipc(sample, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (print_srcline_last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) printed += perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) printed += fprintf(fp, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (PRINT_FIELD(SRCCODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) int ret = map__fprintf_srccode(al->map, al->addr, stdout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) &thread->srccode_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) printed += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) printed += printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) } sample_flags[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) {PERF_IP_FLAG_BRANCH, "jmp"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, "hw int"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) {0, NULL}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) static const char *sample_flags_to_name(u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) for (i = 0; sample_flags[i].name ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (sample_flags[i].flags == flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) return sample_flags[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) const char *chars = PERF_IP_FLAG_CHARS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) const int n = strlen(PERF_IP_FLAG_CHARS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) bool in_tx = flags & PERF_IP_FLAG_IN_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) const char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) char str[33];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) int i, pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) name = sample_flags_to_name(flags & ~PERF_IP_FLAG_IN_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) return fprintf(fp, " %-15s%4s ", name, in_tx ? "(x)" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) if (flags & PERF_IP_FLAG_TRACE_BEGIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) name = sample_flags_to_name(flags & ~(PERF_IP_FLAG_IN_TX | PERF_IP_FLAG_TRACE_BEGIN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) if (name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) return fprintf(fp, " tr strt %-7s%4s ", name, in_tx ? "(x)" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (flags & PERF_IP_FLAG_TRACE_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) name = sample_flags_to_name(flags & ~(PERF_IP_FLAG_IN_TX | PERF_IP_FLAG_TRACE_END));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) if (name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return fprintf(fp, " tr end %-7s%4s ", name, in_tx ? "(x)" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) for (i = 0; i < n; i++, flags >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) if (flags & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) str[pos++] = chars[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) for (; i < 32; i++, flags >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (flags & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) str[pos++] = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) str[pos] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) return fprintf(fp, " %-19s ", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) struct printer_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) int line_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) bool hit_nul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) bool is_printable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) static int sample__fprintf_bpf_output(enum binary_printer_ops op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) unsigned int val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) void *extra, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) unsigned char ch = (unsigned char)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) struct printer_data *printer_data = extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) int printed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) case BINARY_PRINT_DATA_BEGIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) printed += fprintf(fp, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) case BINARY_PRINT_LINE_BEGIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) case BINARY_PRINT_ADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) printed += fprintf(fp, " %04x:", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) case BINARY_PRINT_NUM_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) printed += fprintf(fp, " %02x", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) case BINARY_PRINT_NUM_PAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) printed += fprintf(fp, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) case BINARY_PRINT_SEP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) printed += fprintf(fp, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) case BINARY_PRINT_CHAR_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (printer_data->hit_nul && ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) printer_data->is_printable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (!isprint(ch)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) printed += fprintf(fp, "%c", '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (!printer_data->is_printable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) if (ch == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) printer_data->hit_nul = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) printer_data->is_printable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) printed += fprintf(fp, "%c", ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) case BINARY_PRINT_CHAR_PAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) printed += fprintf(fp, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) case BINARY_PRINT_LINE_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) printed += fprintf(fp, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) printer_data->line_no++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) case BINARY_PRINT_DATA_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) unsigned int nr_bytes = sample->raw_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) struct printer_data printer_data = {0, false, true};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) int printed = binary__fprintf(sample->raw_data, nr_bytes, 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) sample__fprintf_bpf_output, &printer_data, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (printer_data.is_printable && printer_data.hit_nul)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) printed += fprintf(fp, "%17s \"%s\"\n", "BPF string:", (char *)(sample->raw_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (len > 0 && len < spacing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) return fprintf(fp, "%*s", spacing - len, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) return perf_sample__fprintf_spacing(len, 34, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (perf_sample__bad_synth_size(sample, *data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) len = fprintf(fp, " IP: %u payload: %#" PRIx64 " ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) data->ip, le64_to_cpu(data->payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) return len + perf_sample__fprintf_pt_spacing(len, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if (perf_sample__bad_synth_size(sample, *data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) len = fprintf(fp, " hints: %#x extensions: %#x ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) data->hints, data->extensions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) return len + perf_sample__fprintf_pt_spacing(len, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (perf_sample__bad_synth_size(sample, *data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) len = fprintf(fp, " hw: %u cstate: %u sub-cstate: %u ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) data->hw, data->cstate, data->subcstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) return len + perf_sample__fprintf_pt_spacing(len, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) if (perf_sample__bad_synth_size(sample, *data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) len = fprintf(fp, " IP: %u ", data->ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) return len + perf_sample__fprintf_pt_spacing(len, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (perf_sample__bad_synth_size(sample, *data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) data->deepest_cstate, data->last_cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) data->wake_reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) return len + perf_sample__fprintf_pt_spacing(len, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) unsigned int percent, freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if (perf_sample__bad_synth_size(sample, *data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) freq = (le32_to_cpu(data->freq) + 500) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) if (data->max_nonturbo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) len += fprintf(fp, "(%3u%%) ", percent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) return len + perf_sample__fprintf_pt_spacing(len, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) static int perf_sample__fprintf_synth(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) struct evsel *evsel, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) switch (evsel->core.attr.config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) case PERF_SYNTH_INTEL_PTWRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) return perf_sample__fprintf_synth_ptwrite(sample, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) case PERF_SYNTH_INTEL_MWAIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) return perf_sample__fprintf_synth_mwait(sample, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) case PERF_SYNTH_INTEL_PWRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) return perf_sample__fprintf_synth_pwre(sample, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) case PERF_SYNTH_INTEL_EXSTOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) return perf_sample__fprintf_synth_exstop(sample, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) case PERF_SYNTH_INTEL_PWRX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) return perf_sample__fprintf_synth_pwrx(sample, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) case PERF_SYNTH_INTEL_CBR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) return perf_sample__fprintf_synth_cbr(sample, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) static int evlist__max_name_len(struct evlist *evlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) int max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) int len = strlen(evsel__name(evsel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) max = MAX(len, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) return max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) static int data_src__fprintf(u64 data_src, FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) struct mem_info mi = { .data_src.val = data_src };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) char decode[100];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) char out[100];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) static int maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) perf_script__meminfo_scnprintf(decode, 100, &mi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) if (maxlen < len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) maxlen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) return fprintf(fp, "%-*s", maxlen, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) struct metric_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) struct perf_sample *sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) struct thread *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) static void script_print_metric(struct perf_stat_config *config __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) void *ctx, const char *color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) const char *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) const char *unit, double val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) struct metric_ctx *mctx = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) if (!fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) PERF_RECORD_SAMPLE, mctx->fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) fputs("\tmetric: ", mctx->fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) if (color)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) color_fprintf(mctx->fp, color, fmt, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) printf(fmt, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) fprintf(mctx->fp, " %s\n", unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) static void script_new_line(struct perf_stat_config *config __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) void *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) struct metric_ctx *mctx = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) PERF_RECORD_SAMPLE, mctx->fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) fputs("\tmetric: ", mctx->fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) static void perf_sample__fprint_metric(struct perf_script *script,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) FILE *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) struct perf_stat_output_ctx ctx = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) .print_metric = script_print_metric,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) .new_line = script_new_line,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) .ctx = &(struct metric_ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) .sample = sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) .thread = thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) .evsel = evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) .fp = fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) .force_header = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) struct evsel *ev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if (!evsel->stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) perf_evlist__alloc_stats(script->session->evlist, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) if (evsel_script(evsel->leader)->gnum++ == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) perf_stat__reset_shadow_stats();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) val = sample->period * evsel->scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) perf_stat__update_shadow_stats(evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) sample->cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) &rt_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) evsel_script(evsel)->val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) if (evsel_script(evsel->leader)->gnum == evsel->leader->core.nr_members) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) for_each_group_member (ev2, evsel->leader) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) perf_stat__print_shadow_stats(&stat_config, ev2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) evsel_script(ev2)->val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) sample->cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) &ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) &rt_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) evsel_script(evsel->leader)->gnum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) static bool show_event(struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) struct addr_location *al)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) int depth = thread_stack__depth(thread, sample->cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) if (!symbol_conf.graph_function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if (thread->filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) if (depth <= thread->filter_entry_depth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) thread->filter = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) const char *s = symbol_conf.graph_function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) u64 ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) const char *name = resolve_branch_sym(sample, evsel, thread, al,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) &ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) unsigned nlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) nlen = strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) while (*s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) unsigned len = strcspn(s, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) if (nlen == len && !strncmp(name, s, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) thread->filter = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) thread->filter_entry_depth = depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) s += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) if (*s == ',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) static void process_event(struct perf_script *script,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) struct perf_sample *sample, struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) struct addr_location *al,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) struct thread *thread = al->thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) struct perf_event_attr *attr = &evsel->core.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) unsigned int type = output_type(attr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) struct evsel_script *es = evsel->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) FILE *fp = es->fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) if (output[type].fields == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) if (!show_event(sample, evsel, thread, al))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) if (evswitch__discard(&script->evswitch, evsel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) ++es->samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) perf_sample__fprintf_start(script, sample, thread, evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) PERF_RECORD_SAMPLE, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) if (PRINT_FIELD(PERIOD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) fprintf(fp, "%10" PRIu64 " ", sample->period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) if (PRINT_FIELD(EVNAME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) const char *evname = evsel__name(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) if (!script->name_width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) script->name_width = evlist__max_name_len(script->session->evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) if (print_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) perf_sample__fprintf_flags(sample->flags, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) if (is_bts_event(attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) perf_sample__fprintf_bts(sample, evsel, thread, al, machine, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) if (PRINT_FIELD(TRACE) && sample->raw_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) event_format__fprintf(evsel->tp_format, sample->cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) sample->raw_data, sample->raw_size, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) perf_sample__fprintf_synth(sample, evsel, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) if (PRINT_FIELD(ADDR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) perf_sample__fprintf_addr(sample, thread, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (PRINT_FIELD(DATA_SRC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) data_src__fprintf(sample->data_src, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) if (PRINT_FIELD(WEIGHT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) fprintf(fp, "%16" PRIu64, sample->weight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) if (PRINT_FIELD(IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) struct callchain_cursor *cursor = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) if (script->stitch_lbr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) al->thread->lbr_stitch_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) if (symbol_conf.use_callchain && sample->callchain &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) sample, NULL, NULL, scripting_max_stack) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) cursor = &callchain_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) fputc(cursor ? '\n' : ' ', fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) symbol_conf.bt_stop_list, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) if (PRINT_FIELD(IREGS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) perf_sample__fprintf_iregs(sample, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) if (PRINT_FIELD(UREGS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) perf_sample__fprintf_uregs(sample, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) if (PRINT_FIELD(BRSTACK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) perf_sample__fprintf_brstack(sample, thread, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) else if (PRINT_FIELD(BRSTACKSYM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) perf_sample__fprintf_brstacksym(sample, thread, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) else if (PRINT_FIELD(BRSTACKOFF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) perf_sample__fprintf_brstackoff(sample, thread, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) if (evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) perf_sample__fprintf_bpf_output(sample, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) if (PRINT_FIELD(PHYS_ADDR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) fprintf(fp, "%16" PRIx64, sample->phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) perf_sample__fprintf_ipc(sample, attr, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) fprintf(fp, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) if (PRINT_FIELD(SRCCODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) if (map__fprintf_srccode(al->map, al->addr, stdout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) &thread->srccode_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) if (PRINT_FIELD(METRIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) perf_sample__fprint_metric(script, thread, evsel, sample, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) if (verbose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) fflush(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) static struct scripting_ops *scripting_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) static void __process_stat(struct evsel *counter, u64 tstamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) int nthreads = perf_thread_map__nr(counter->core.threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) int ncpus = evsel__nr_cpus(counter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) int cpu, thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) static int header_printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) if (counter->core.system_wide)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) nthreads = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) if (!header_printed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) printf("%3s %8s %15s %15s %15s %15s %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) "CPU", "THREAD", "VAL", "ENA", "RUN", "TIME", "EVENT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) header_printed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) for (thread = 0; thread < nthreads; thread++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) for (cpu = 0; cpu < ncpus; cpu++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) struct perf_counts_values *counts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) counts = perf_counts(counter->counts, cpu, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) counter->core.cpus->map[cpu],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) perf_thread_map__pid(counter->core.threads, thread),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) counts->val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) counts->ena,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) counts->run,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) tstamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) evsel__name(counter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) static void process_stat(struct evsel *counter, u64 tstamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if (scripting_ops && scripting_ops->process_stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) scripting_ops->process_stat(&stat_config, counter, tstamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) __process_stat(counter, tstamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) static void process_stat_interval(u64 tstamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) if (scripting_ops && scripting_ops->process_stat_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) scripting_ops->process_stat_interval(tstamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) static void setup_scripting(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) setup_perl_scripting();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) setup_python_scripting();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) static int flush_scripting(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) return scripting_ops ? scripting_ops->flush_script() : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) static int cleanup_scripting(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) pr_debug("\nperf script stopped\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) return scripting_ops ? scripting_ops->stop_script() : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) static bool filter_cpu(struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) if (cpu_list && sample->cpu != (u32)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) return !test_bit(sample->cpu, cpu_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) static int process_sample_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) struct perf_script *scr = container_of(tool, struct perf_script, tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) struct addr_location al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) sample->time)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) if (debug_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) if (sample->time < last_timestamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) pr_err("Samples misordered, previous: %" PRIu64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) " this: %" PRIu64 "\n", last_timestamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) sample->time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) nr_unordered++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) last_timestamp = sample->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) if (machine__resolve(machine, &al, sample) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) pr_err("problem processing %d event, skipping it.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) event->header.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) if (al.filtered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) if (filter_cpu(sample))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) if (scripting_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) scripting_ops->process_event(event, sample, evsel, &al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) process_event(scr, sample, evsel, &al, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) addr_location__put(&al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) static int process_attr(struct perf_tool *tool, union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) struct evlist **pevlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) struct perf_script *scr = container_of(tool, struct perf_script, tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) struct evlist *evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) struct evsel *evsel, *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) u64 sample_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) static struct evsel_script *es;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) err = perf_event__process_attr(tool, event, pevlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) evlist = *pevlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) evsel = evlist__last(*pevlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) if (!evsel->priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) if (scr->per_event_dump) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) evsel->priv = perf_evsel_script__new(evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) scr->session->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) es = zalloc(sizeof(*es));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) if (!es)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) es->fp = stdout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) evsel->priv = es;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) if (evsel->core.attr.type >= PERF_TYPE_MAX &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) evsel->core.attr.type != PERF_TYPE_SYNTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) evlist__for_each_entry(evlist, pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) if (pos->core.attr.type == evsel->core.attr.type && pos != evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) if (evsel->core.attr.sample_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) err = evsel__check_attr(evsel, scr->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) * Check if we need to enable callchains based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) * on events sample_type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) sample_type = evlist__combined_sample_type(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) callchain_param_setup(sample_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) /* Enable fields for callchain entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) if (symbol_conf.use_callchain &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) (sample_type & PERF_SAMPLE_CALLCHAIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) sample_type & PERF_SAMPLE_BRANCH_STACK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) (sample_type & PERF_SAMPLE_REGS_USER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) sample_type & PERF_SAMPLE_STACK_USER))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) int type = output_type(evsel->core.attr.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (!(output[type].user_unset_fields & PERF_OUTPUT_IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) output[type].fields |= PERF_OUTPUT_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) if (!(output[type].user_unset_fields & PERF_OUTPUT_SYM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) output[type].fields |= PERF_OUTPUT_SYM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) set_print_ip_opts(&evsel->core.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) static int print_event_with_time(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) pid_t pid, pid_t tid, u64 timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) struct perf_script *script = container_of(tool, struct perf_script, tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) struct perf_session *session = script->session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) struct thread *thread = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) if (evsel && !evsel->core.attr.sample_id_all) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) sample->cpu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) sample->time = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) sample->pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) sample->tid = tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) if (filter_cpu(sample))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) if (tid != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) thread = machine__findnew_thread(machine, pid, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) if (evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) perf_sample__fprintf_start(script, sample, thread, evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) event->header.type, stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) perf_event__fprintf(event, machine, stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) thread__put(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) static int print_event(struct perf_tool *tool, union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) struct perf_sample *sample, struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) pid_t pid, pid_t tid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) return print_event_with_time(tool, event, sample, machine, pid, tid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) static int process_comm_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) if (perf_event__process_comm(tool, event, sample, machine) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) return print_event(tool, event, sample, machine, event->comm.pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) event->comm.tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) static int process_namespaces_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) if (perf_event__process_namespaces(tool, event, sample, machine) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) return print_event(tool, event, sample, machine, event->namespaces.pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) event->namespaces.tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) static int process_cgroup_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) if (perf_event__process_cgroup(tool, event, sample, machine) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) return print_event(tool, event, sample, machine, sample->pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) sample->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) static int process_fork_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) if (perf_event__process_fork(tool, event, sample, machine) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) return print_event_with_time(tool, event, sample, machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) event->fork.pid, event->fork.tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) event->fork.time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) static int process_exit_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) /* Print before 'exit' deletes anything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) if (print_event_with_time(tool, event, sample, machine, event->fork.pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) event->fork.tid, event->fork.time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) return perf_event__process_exit(tool, event, sample, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) static int process_mmap_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) if (perf_event__process_mmap(tool, event, sample, machine) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) return print_event(tool, event, sample, machine, event->mmap.pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) event->mmap.tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) static int process_mmap2_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) if (perf_event__process_mmap2(tool, event, sample, machine) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) return print_event(tool, event, sample, machine, event->mmap2.pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) event->mmap2.tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) static int process_switch_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) struct perf_script *script = container_of(tool, struct perf_script, tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) if (perf_event__process_switch(tool, event, sample, machine) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) if (scripting_ops && scripting_ops->process_switch && !filter_cpu(sample))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) scripting_ops->process_switch(event, sample, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) if (!script->show_switch_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) return print_event(tool, event, sample, machine, sample->pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) sample->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) process_lost_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) return print_event(tool, event, sample, machine, sample->pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) sample->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) process_finished_round_event(struct perf_tool *tool __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) struct ordered_events *oe __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) perf_event__fprintf(event, NULL, stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) process_bpf_events(struct perf_tool *tool __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) if (machine__process_ksymbol(machine, event, sample) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) return print_event(tool, event, sample, machine, sample->pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) sample->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) static int process_text_poke_events(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) if (perf_event__process_text_poke(tool, event, sample, machine) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) return print_event(tool, event, sample, machine, sample->pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) sample->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) static void sig_handler(int sig __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) session_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) static void perf_script__fclose_per_event_dump(struct perf_script *script)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) struct evlist *evlist = script->session->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) if (!evsel->priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) perf_evsel_script__delete(evsel->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) evsel->priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) static int perf_script__fopen_per_event_dump(struct perf_script *script)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) evlist__for_each_entry(script->session->evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) * Already setup? I.e. we may be called twice in cases like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) * Intel PT, one for the intel_pt// and dummy events, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) * for the evsels syntheized from the auxtrace info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) * Ses perf_script__process_auxtrace_info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) if (evsel->priv != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) evsel->priv = perf_evsel_script__new(evsel, script->session->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) if (evsel->priv == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) goto out_err_fclose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) out_err_fclose:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) perf_script__fclose_per_event_dump(script);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) static int perf_script__setup_per_event_dump(struct perf_script *script)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) static struct evsel_script es_stdout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) if (script->per_event_dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) return perf_script__fopen_per_event_dump(script);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) es_stdout.fp = stdout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) evlist__for_each_entry(script->session->evlist, evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) evsel->priv = &es_stdout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) evlist__for_each_entry(script->session->evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) struct evsel_script *es = evsel->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) perf_evsel_script__fprintf(es, stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) perf_evsel_script__delete(es);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) evsel->priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) static void perf_script__exit(struct perf_script *script)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) perf_thread_map__put(script->threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) perf_cpu_map__put(script->cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) static int __cmd_script(struct perf_script *script)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) signal(SIGINT, sig_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) perf_stat__init_shadow_stats();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) /* override event processing functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) if (script->show_task_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) script->tool.comm = process_comm_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) script->tool.fork = process_fork_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) script->tool.exit = process_exit_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) if (script->show_mmap_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) script->tool.mmap = process_mmap_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) script->tool.mmap2 = process_mmap2_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) script->tool.context_switch = process_switch_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) if (script->show_namespace_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) script->tool.namespaces = process_namespaces_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) if (script->show_cgroup_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) script->tool.cgroup = process_cgroup_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) if (script->show_lost_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) script->tool.lost = process_lost_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) if (script->show_round_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) script->tool.ordered_events = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) script->tool.finished_round = process_finished_round_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) if (script->show_bpf_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) script->tool.ksymbol = process_bpf_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) script->tool.bpf = process_bpf_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) if (script->show_text_poke_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) script->tool.ksymbol = process_bpf_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) script->tool.text_poke = process_text_poke_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) if (perf_script__setup_per_event_dump(script)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) pr_err("Couldn't create the per event dump files\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) ret = perf_session__process_events(script->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) if (script->per_event_dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) perf_script__exit_per_event_dump_stats(script);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) if (debug_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) struct script_spec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) struct scripting_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) char spec[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) static LIST_HEAD(script_specs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) static struct script_spec *script_spec__new(const char *spec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) struct scripting_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) if (s != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) strcpy(s->spec, spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) s->ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) static void script_spec__add(struct script_spec *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) list_add_tail(&s->node, &script_specs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) static struct script_spec *script_spec__find(const char *spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) struct script_spec *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) list_for_each_entry(s, &script_specs, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) if (strcasecmp(s->spec, spec) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) int script_spec_register(const char *spec, struct scripting_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) struct script_spec *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) s = script_spec__find(spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) if (s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) s = script_spec__new(spec, ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) script_spec__add(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) static struct scripting_ops *script_spec__lookup(const char *spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) struct script_spec *s = script_spec__find(spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) return s->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) static void list_available_languages(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) struct script_spec *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) fprintf(stderr, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) fprintf(stderr, "Scripting language extensions (used in "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) "perf script -s [spec:]script.[spec]):\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) list_for_each_entry(s, &script_specs, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) fprintf(stderr, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) static int parse_scriptname(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) char spec[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) const char *script, *ext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) if (strcmp(str, "lang") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) list_available_languages();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) script = strchr(str, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) if (script) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) len = script - str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) if (len >= PATH_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) fprintf(stderr, "invalid language specifier");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) strncpy(spec, str, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) spec[len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) scripting_ops = script_spec__lookup(spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) if (!scripting_ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) fprintf(stderr, "invalid language specifier");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) script++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) script = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) ext = strrchr(script, '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) if (!ext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) fprintf(stderr, "invalid script extension");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) scripting_ops = script_spec__lookup(++ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) if (!scripting_ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) fprintf(stderr, "invalid script extension");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) script_name = strdup(script);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) static int parse_output_fields(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) const char *arg, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) char *tok, *strtok_saveptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) int i, imax = ARRAY_SIZE(all_output_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) char *str = strdup(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) int type = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) /* first word can state for which event type the user is specifying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) * the fields. If no type exists, the specified fields apply to all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) * event types found in the file minus the invalid fields for a type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) tok = strchr(str, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) if (tok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) *tok = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) tok++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) if (!strcmp(str, "hw"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) type = PERF_TYPE_HARDWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) else if (!strcmp(str, "sw"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) type = PERF_TYPE_SOFTWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) else if (!strcmp(str, "trace"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) type = PERF_TYPE_TRACEPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) else if (!strcmp(str, "raw"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) type = PERF_TYPE_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) else if (!strcmp(str, "break"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) type = PERF_TYPE_BREAKPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) else if (!strcmp(str, "synth"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) type = OUTPUT_TYPE_SYNTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) fprintf(stderr, "Invalid event type in field string.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) if (output[type].user_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) pr_warning("Overriding previous field request for %s events.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) event_type(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) /* Don't override defaults for +- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) if (strchr(tok, '+') || strchr(tok, '-'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) goto parse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) output[type].fields = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) output[type].user_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) output[type].wildcard_set = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) tok = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) if (strlen(str) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) "Cannot set fields to 'none' for all event types.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) /* Don't override defaults for +- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) if (strchr(str, '+') || strchr(str, '-'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) goto parse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) if (output_set_by_user())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) pr_warning("Overriding previous field request for all events.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) output[j].fields = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) output[j].user_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) output[j].wildcard_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) parse:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) if (*tok == '+') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) if (change == SET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) goto out_badmix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) change = ADD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) tok++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) } else if (*tok == '-') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) if (change == SET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) goto out_badmix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) change = REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) tok++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) if (change != SET && change != DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) goto out_badmix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) change = SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) for (i = 0; i < imax; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) if (strcmp(tok, all_output_options[i].str) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) if (i == imax && strcmp(tok, "flags") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) print_flags = change == REMOVE ? false : true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) if (i == imax) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) fprintf(stderr, "Invalid field requested.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) if (type == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) /* add user option to all events types for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) * which it is valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) if (output[j].invalid_fields & all_output_options[i].field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) all_output_options[i].str, event_type(j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) if (change == REMOVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) output[j].fields &= ~all_output_options[i].field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) output[j].user_set_fields &= ~all_output_options[i].field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) output[j].user_unset_fields |= all_output_options[i].field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) output[j].fields |= all_output_options[i].field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) output[j].user_set_fields |= all_output_options[i].field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) output[j].user_unset_fields &= ~all_output_options[i].field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) output[j].user_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) output[j].wildcard_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) if (output[type].invalid_fields & all_output_options[i].field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) fprintf(stderr, "\'%s\' not valid for %s events.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) all_output_options[i].str, event_type(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) if (change == REMOVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) output[type].fields &= ~all_output_options[i].field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) output[type].fields |= all_output_options[i].field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) output[type].user_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) output[type].wildcard_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) if (type >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) if (output[type].fields == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) pr_debug("No fields requested for %s type. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) "Events will not be displayed.\n", event_type(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) out_badmix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) fprintf(stderr, "Cannot mix +-field with overridden fields\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) free(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) #define for_each_lang(scripts_path, scripts_dir, lang_dirent) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) while ((lang_dirent = readdir(scripts_dir)) != NULL) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) if ((lang_dirent->d_type == DT_DIR || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) (lang_dirent->d_type == DT_UNKNOWN && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) is_directory(scripts_path, lang_dirent))) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) (strcmp(lang_dirent->d_name, ".")) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) (strcmp(lang_dirent->d_name, "..")))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) #define for_each_script(lang_path, lang_dir, script_dirent) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) while ((script_dirent = readdir(lang_dir)) != NULL) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) if (script_dirent->d_type != DT_DIR && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) (script_dirent->d_type != DT_UNKNOWN || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) !is_directory(lang_path, script_dirent)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) #define RECORD_SUFFIX "-record"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) #define REPORT_SUFFIX "-report"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) struct script_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) char *half_liner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) char *args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) static LIST_HEAD(script_descs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) static struct script_desc *script_desc__new(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) struct script_desc *s = zalloc(sizeof(*s));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) if (s != NULL && name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) s->name = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) static void script_desc__delete(struct script_desc *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) zfree(&s->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) zfree(&s->half_liner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) zfree(&s->args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) free(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) static void script_desc__add(struct script_desc *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) list_add_tail(&s->node, &script_descs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) static struct script_desc *script_desc__find(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) struct script_desc *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) list_for_each_entry(s, &script_descs, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) if (strcasecmp(s->name, name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) static struct script_desc *script_desc__findnew(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) struct script_desc *s = script_desc__find(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) if (s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) s = script_desc__new(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) script_desc__add(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) static const char *ends_with(const char *str, const char *suffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) size_t suffix_len = strlen(suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) const char *p = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) if (strlen(str) > suffix_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) p = str + strlen(str) - suffix_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) if (!strncmp(p, suffix, suffix_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) static int read_script_info(struct script_desc *desc, const char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) char line[BUFSIZ], *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) fp = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) if (!fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) while (fgets(line, sizeof(line), fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) p = skip_spaces(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) if (strlen(p) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) if (*p != '#')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) if (strlen(p) && *p == '!')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) p = skip_spaces(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) if (strlen(p) && p[strlen(p) - 1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) p[strlen(p) - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) if (!strncmp(p, "description:", strlen("description:"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) p += strlen("description:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) desc->half_liner = strdup(skip_spaces(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) if (!strncmp(p, "args:", strlen("args:"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) p += strlen("args:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) desc->args = strdup(skip_spaces(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) static char *get_script_root(struct dirent *script_dirent, const char *suffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) char *script_root, *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) script_root = strdup(script_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) if (!script_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) str = (char *)ends_with(script_root, suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) if (!str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) free(script_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) *str = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) return script_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) static int list_available_scripts(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) const char *s __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) struct dirent *script_dirent, *lang_dirent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) char scripts_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) DIR *scripts_dir, *lang_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) char script_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) char lang_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) struct script_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) char first_half[BUFSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) char *script_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) scripts_dir = opendir(scripts_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) if (!scripts_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) fprintf(stdout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) "open(%s) failed.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) "Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) scripts_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) for_each_lang(scripts_path, scripts_dir, lang_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) lang_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) lang_dir = opendir(lang_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) if (!lang_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) for_each_script(lang_path, lang_dir, script_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) script_root = get_script_root(script_dirent, REPORT_SUFFIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) if (script_root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) desc = script_desc__findnew(script_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) scnprintf(script_path, MAXPATHLEN, "%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) lang_path, script_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) read_script_info(desc, script_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) free(script_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) fprintf(stdout, "List of available trace scripts:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) list_for_each_entry(desc, &script_descs, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) sprintf(first_half, "%s %s", desc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) desc->args ? desc->args : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) fprintf(stdout, " %-36s %s\n", first_half,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) desc->half_liner ? desc->half_liner : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) * Some scripts specify the required events in their "xxx-record" file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) * this function will check if the events in perf.data match those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) * mentioned in the "xxx-record".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) * Fixme: All existing "xxx-record" are all in good formats "-e event ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) * which is covered well now. And new parsing code should be added to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) * cover the future complexing formats like event groups etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) static int check_ev_match(char *dir_name, char *scriptname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) char filename[MAXPATHLEN], evname[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) char line[BUFSIZ], *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) struct evsel *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) int match, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) fp = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) if (!fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) while (fgets(line, sizeof(line), fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) p = skip_spaces(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) if (*p == '#')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) while (strlen(p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) p = strstr(p, "-e");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) p += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) p = skip_spaces(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) len = strcspn(p, " \t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) snprintf(evname, len + 1, "%s", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) match = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) evlist__for_each_entry(session->evlist, pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) if (!strcmp(evsel__name(pos), evname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) match = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) if (!match) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) * Return -1 if none is found, otherwise the actual scripts number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) * Currently the only user of this function is the script browser, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) * will list all statically runnable scripts, select one, execute it and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) * show the output in a perf browser.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) int find_scripts(char **scripts_array, char **scripts_path_array, int num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) int pathlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) struct dirent *script_dirent, *lang_dirent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) DIR *scripts_dir, *lang_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) struct perf_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) struct perf_data data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) .path = input_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) .mode = PERF_DATA_MODE_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) char *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) session = perf_session__new(&data, false, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) if (IS_ERR(session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) return PTR_ERR(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) scripts_dir = opendir(scripts_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) if (!scripts_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) perf_session__delete(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) for_each_lang(scripts_path, scripts_dir, lang_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) lang_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) #ifndef HAVE_LIBPERL_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) if (strstr(lang_path, "perl"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) #ifndef HAVE_LIBPYTHON_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) if (strstr(lang_path, "python"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) lang_dir = opendir(lang_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) if (!lang_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) for_each_script(lang_path, lang_dir, script_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) /* Skip those real time scripts: xxxtop.p[yl] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) if (strstr(script_dirent->d_name, "top."))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) if (i >= num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) snprintf(scripts_path_array[i], pathlen, "%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) lang_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) script_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) temp = strchr(script_dirent->d_name, '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) snprintf(scripts_array[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) (temp - script_dirent->d_name) + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) "%s", script_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) if (check_ev_match(lang_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) scripts_array[i], session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) closedir(lang_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) closedir(scripts_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) perf_session__delete(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) static char *get_script_path(const char *script_root, const char *suffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) struct dirent *script_dirent, *lang_dirent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) char scripts_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) char script_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) DIR *scripts_dir, *lang_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) char lang_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) char *__script_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) scripts_dir = opendir(scripts_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) if (!scripts_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) for_each_lang(scripts_path, scripts_dir, lang_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) lang_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) lang_dir = opendir(lang_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) if (!lang_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) for_each_script(lang_path, lang_dir, script_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) __script_root = get_script_root(script_dirent, suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) if (__script_root && !strcmp(script_root, __script_root)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) free(__script_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) closedir(scripts_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) scnprintf(script_path, MAXPATHLEN, "%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) lang_path, script_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) closedir(lang_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) return strdup(script_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) free(__script_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) closedir(lang_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) closedir(scripts_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) static bool is_top_script(const char *script_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) return ends_with(script_path, "top") == NULL ? false : true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) static int has_required_arg(char *script_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) struct script_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) int n_args = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) desc = script_desc__new(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) if (read_script_info(desc, script_path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) if (!desc->args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) for (p = desc->args; *p; p++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) if (*p == '<')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) n_args++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) script_desc__delete(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) return n_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) static int have_cmd(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) char **__argv = malloc(sizeof(const char *) * argc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) if (!__argv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) pr_err("malloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) memcpy(__argv, argv, sizeof(const char *) * argc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) argc = parse_options(argc, (const char **)__argv, record_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) NULL, PARSE_OPT_STOP_AT_NON_OPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) free(__argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) system_wide = (argc == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) static void script__setup_sample_type(struct perf_script *script)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) struct perf_session *session = script->session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) u64 sample_type = evlist__combined_sample_type(session->evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) if ((sample_type & PERF_SAMPLE_REGS_USER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) (sample_type & PERF_SAMPLE_STACK_USER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) callchain_param.record_mode = CALLCHAIN_DWARF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) dwarf_callchain_users = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) } else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) callchain_param.record_mode = CALLCHAIN_LBR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) callchain_param.record_mode = CALLCHAIN_FP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) if (script->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) pr_warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) "Please apply --call-graph lbr when recording.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) script->stitch_lbr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) static int process_stat_round_event(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) union perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) struct perf_record_stat_round *round = &event->stat_round;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) struct evsel *counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) evlist__for_each_entry(session->evlist, counter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) perf_stat_process_counter(&stat_config, counter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) process_stat(counter, round->time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) process_stat_interval(round->time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) static int process_stat_config_event(struct perf_session *session __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) union perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) perf_event__read_stat_config(&stat_config, &event->stat_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) static int set_maps(struct perf_script *script)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) struct evlist *evlist = script->session->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) if (!script->cpus || !script->threads)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) if (WARN_ONCE(script->allocated, "stats double allocation\n"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) perf_evlist__set_maps(&evlist->core, script->cpus, script->threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) if (perf_evlist__alloc_stats(evlist, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) script->allocated = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) int process_thread_map_event(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) union perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) struct perf_tool *tool = session->tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) struct perf_script *script = container_of(tool, struct perf_script, tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) if (script->threads) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) pr_warning("Extra thread map event, ignoring.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) script->threads = thread_map__new_event(&event->thread_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) if (!script->threads)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) return set_maps(script);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) int process_cpu_map_event(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) union perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) struct perf_tool *tool = session->tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) struct perf_script *script = container_of(tool, struct perf_script, tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) if (script->cpus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) pr_warning("Extra cpu map event, ignoring.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) script->cpus = cpu_map__new_data(&event->cpu_map.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) if (!script->cpus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) return set_maps(script);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) static int process_feature_event(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) union perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) if (event->feat.feat_id < HEADER_LAST_FEATURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) return perf_event__process_feature(session, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) #ifdef HAVE_AUXTRACE_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) static int perf_script__process_auxtrace_info(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) union perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) struct perf_tool *tool = session->tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) int ret = perf_event__process_auxtrace_info(session, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) struct perf_script *script = container_of(tool, struct perf_script, tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) ret = perf_script__setup_per_event_dump(script);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) #define perf_script__process_auxtrace_info 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) static int parse_insn_trace(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) const char *str __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) parse_output_fields(NULL, "+insn,-event,-period", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) itrace_parse_synth_opts(opt, "i0ns", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) symbol_conf.nanosecs = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) static int parse_xed(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) const char *str __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) if (isatty(1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) force_pager("xed -F insn: -A -64 | less");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) force_pager("xed -F insn: -A -64");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) static int parse_call_trace(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) const char *str __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) itrace_parse_synth_opts(opt, "cewp", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) symbol_conf.nanosecs = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) symbol_conf.pad_output_len_dso = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) static int parse_callret_trace(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) const char *str __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent,+flags", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) itrace_parse_synth_opts(opt, "crewp", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) symbol_conf.nanosecs = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) int cmd_script(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) bool show_full_info = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) bool header = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) bool header_only = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) bool script_started = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) char *rec_script_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) char *rep_script_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) struct perf_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) struct itrace_synth_opts itrace_synth_opts = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) .set = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) .default_no_sample = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) struct utsname uts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) char *script_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) const char **__argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) int i, j, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) struct perf_script script = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) .tool = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) .sample = process_sample_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) .mmap = perf_event__process_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) .mmap2 = perf_event__process_mmap2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) .comm = perf_event__process_comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) .namespaces = perf_event__process_namespaces,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) .cgroup = perf_event__process_cgroup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) .exit = perf_event__process_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) .fork = perf_event__process_fork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) .attr = process_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) .event_update = perf_event__process_event_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) .tracing_data = perf_event__process_tracing_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) .feature = process_feature_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) .build_id = perf_event__process_build_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) .id_index = perf_event__process_id_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) .auxtrace_info = perf_script__process_auxtrace_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) .auxtrace = perf_event__process_auxtrace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) .auxtrace_error = perf_event__process_auxtrace_error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) .stat = perf_event__process_stat_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) .stat_round = process_stat_round_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) .stat_config = process_stat_config_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) .thread_map = process_thread_map_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) .cpu_map = process_cpu_map_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) .ordered_events = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) .ordering_requires_timestamps = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) struct perf_data data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) .mode = PERF_DATA_MODE_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) const struct option options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) "dump raw trace in ASCII"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) OPT_INCR('v', "verbose", &verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) "be more verbose (show symbol address, etc)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) OPT_BOOLEAN('L', "Latency", &latency_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) "show latency attributes (irqs/preemption disabled, etc)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) list_available_scripts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) OPT_CALLBACK('s', "script", NULL, "name",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) "script file name (lang:script name, script name, or *)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) parse_scriptname),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) "generate perf-script.xx script in specified language"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) OPT_STRING('i', "input", &input_name, "file", "input file name"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) OPT_BOOLEAN('d', "debug-mode", &debug_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) "do various checks like samples ordering and lost events"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) OPT_BOOLEAN(0, "header", &header, "Show data header."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) "file", "vmlinux pathname"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) "file", "kallsyms pathname"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) "When printing symbols do not display call chain"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) OPT_CALLBACK(0, "symfs", NULL, "directory",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) "Look for files with symbols relative to this directory",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) symbol__config_symfs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) OPT_CALLBACK('F', "fields", NULL, "str",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) "comma separated output fields prepend with 'type:'. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) "+field to add and -field to remove."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) "Valid types: hw,sw,trace,raw,synth. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) "addr,symoff,srcline,period,iregs,uregs,brstack,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) "brstacksym,flags,bpf-output,brstackinsn,brstackoff,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) "callindent,insn,insnlen,synth,phys_addr,metric,misc,ipc,tod",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) parse_output_fields),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) OPT_BOOLEAN('a', "all-cpus", &system_wide,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) "system-wide collection from all CPUs"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) "only consider these symbols"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) OPT_CALLBACK_OPTARG(0, "insn-trace", &itrace_synth_opts, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) "Decode instructions from itrace", parse_insn_trace),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) OPT_CALLBACK_OPTARG(0, "xed", NULL, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) "Run xed disassembler on output", parse_xed),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) OPT_CALLBACK_OPTARG(0, "call-trace", &itrace_synth_opts, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) "Decode calls from from itrace", parse_call_trace),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) OPT_CALLBACK_OPTARG(0, "call-ret-trace", &itrace_synth_opts, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) "Decode calls and returns from itrace", parse_callret_trace),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) OPT_STRING(0, "graph-function", &symbol_conf.graph_function, "symbol[,symbol...]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) "Only print symbols and callees with --call-trace/--call-ret-trace"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) "Stop display of callgraph at these symbols"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) "only display events for these comms"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) "only consider symbols in these pids"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) "only consider symbols in these tids"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) OPT_UINTEGER(0, "max-stack", &scripting_max_stack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) "Set the maximum stack depth when parsing the callchain, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) "anything beyond the specified depth will be ignored. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) OPT_BOOLEAN(0, "reltime", &reltime, "Show time stamps relative to start"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) OPT_BOOLEAN(0, "deltatime", &deltatime, "Show time stamps relative to previous event"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) OPT_BOOLEAN('I', "show-info", &show_full_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) "display extended information from perf.data file"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) "Show the path of [kernel.kallsyms]"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) "Show the fork/comm/exit events"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) "Show the mmap events"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) "Show context switch events (if recorded)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) "Show namespace events (if recorded)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) OPT_BOOLEAN('\0', "show-cgroup-events", &script.show_cgroup_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) "Show cgroup events (if recorded)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) "Show lost events (if recorded)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) "Show round events (if recorded)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) OPT_BOOLEAN('\0', "show-bpf-events", &script.show_bpf_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) "Show bpf related events (if recorded)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) OPT_BOOLEAN('\0', "show-text-poke-events", &script.show_text_poke_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) "Show text poke related events (if recorded)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) "Dump trace output to files named by the monitored events"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) OPT_INTEGER(0, "max-blocks", &max_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) "Maximum number of code blocks to dump with brstackinsn"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) "Use 9 decimal places when displaying time"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) "Instruction Tracing options\n" ITRACE_HELP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) itrace_parse_synth_opts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) "Show full source file name path for source lines"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) "Enable symbol demangling"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) "Enable kernel symbol demangling"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) OPT_STRING(0, "time", &script.time_str, "str",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) "Time span of interest (start,stop)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) "Show inline function"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) "guest mount directory under which every guest os"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) " instance has a subdir"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) "file", "file saving guest os vmlinux"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) "file", "file saving guest os /proc/kallsyms"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) "file", "file saving guest os /proc/modules"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) OPT_BOOLEAN('\0', "stitch-lbr", &script.stitch_lbr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) "Enable LBR callgraph stitching approach"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) OPTS_EVSWITCH(&script.evswitch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) const char * const script_subcommands[] = { "record", "report", NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) const char *script_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) "perf script [<options>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) "perf script [<options>] record <script> [<record-options>] <command>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) "perf script [<options>] report <script> [script-args]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) "perf script [<options>] <script> [<record-options>] <command>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) "perf script [<options>] <top-script> [script-args]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) perf_set_singlethreaded();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) setup_scripting();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) PARSE_OPT_STOP_AT_NON_OPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) if (symbol_conf.guestmount ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) symbol_conf.default_guest_vmlinux_name ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) symbol_conf.default_guest_kallsyms ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) symbol_conf.default_guest_modules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) * Enable guest sample processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) perf_guest = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) data.path = input_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) data.force = symbol_conf.force;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) if (!rec_script_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) return cmd_record(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) if (!rep_script_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) "Please specify a valid report script"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) "(see 'perf script -l' for listing)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) if (reltime && deltatime) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) "reltime and deltatime - the two don't get along well. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) "Please limit to --reltime or --deltatime.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) itrace_synth_opts.callchain_sz > scripting_max_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) scripting_max_stack = itrace_synth_opts.callchain_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) /* make sure PERF_EXEC_PATH is set for scripts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) set_argv_exec_path(get_argv_exec_path());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) if (argc && !script_name && !rec_script_path && !rep_script_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) int live_pipe[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) int rep_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) pid_t pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) if (!rec_script_path && !rep_script_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) usage_with_options_msg(script_usage, options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) "Couldn't find script `%s'\n\n See perf"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) " script -l for available scripts.\n", argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) if (is_top_script(argv[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) rep_args = argc - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) int rec_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) rep_args = has_required_arg(rep_script_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) rec_args = (argc - 1) - rep_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) if (rec_args < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) usage_with_options_msg(script_usage, options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) "`%s' script requires options."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) "\n\n See perf script -l for available "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) "scripts and options.\n", argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) if (pipe(live_pipe) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) perror("failed to create pipe");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) pid = fork();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) if (pid < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) perror("failed to fork");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) if (!pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) dup2(live_pipe[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) close(live_pipe[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) if (is_top_script(argv[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) system_wide = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) } else if (!system_wide) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) __argv = malloc((argc + 6) * sizeof(const char *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) if (!__argv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) pr_err("malloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) __argv[j++] = "/bin/sh";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) __argv[j++] = rec_script_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) if (system_wide)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) __argv[j++] = "-a";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) __argv[j++] = "-q";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) __argv[j++] = "-o";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) __argv[j++] = "-";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) for (i = rep_args + 1; i < argc; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) __argv[j++] = argv[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) __argv[j++] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) execvp("/bin/sh", (char **)__argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) free(__argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) dup2(live_pipe[0], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) close(live_pipe[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) __argv = malloc((argc + 4) * sizeof(const char *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) if (!__argv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) pr_err("malloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) __argv[j++] = "/bin/sh";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) __argv[j++] = rep_script_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) for (i = 1; i < rep_args + 1; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) __argv[j++] = argv[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) __argv[j++] = "-i";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) __argv[j++] = "-";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) __argv[j++] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) execvp("/bin/sh", (char **)__argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) free(__argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) if (rec_script_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) script_path = rec_script_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) if (rep_script_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) script_path = rep_script_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) if (script_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) if (!rec_script_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) system_wide = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) else if (!system_wide) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) if (have_cmd(argc - 1, &argv[1]) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) __argv = malloc((argc + 2) * sizeof(const char *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) if (!__argv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) pr_err("malloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) __argv[j++] = "/bin/sh";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) __argv[j++] = script_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) if (system_wide)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) __argv[j++] = "-a";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) for (i = 2; i < argc; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) __argv[j++] = argv[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) __argv[j++] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) execvp("/bin/sh", (char **)__argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) free(__argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) if (!script_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) setup_pager();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) use_browser = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) session = perf_session__new(&data, false, &script.tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) if (IS_ERR(session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) return PTR_ERR(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) if (header || header_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) perf_session__fprintf_info(session, stdout, show_full_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) if (header_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) if (show_full_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) if (symbol__init(&session->header.env) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) uname(&uts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) if (data.is_pipe) { /* Assume pipe_mode indicates native_arch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) native_arch = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) } else if (session->header.env.arch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) if (!strcmp(uts.machine, session->header.env.arch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) native_arch = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) else if (!strcmp(uts.machine, "x86_64") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) !strcmp(session->header.env.arch, "i386"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) native_arch = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) script.session = session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) script__setup_sample_type(&script);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) if ((output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) symbol_conf.graph_function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) itrace_synth_opts.thread_stack = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) session->itrace_synth_opts = &itrace_synth_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) if (cpu_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) itrace_synth_opts.cpu_bitmap = cpu_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) if (!no_callchain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) symbol_conf.use_callchain = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) symbol_conf.use_callchain = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) if (session->tevent.pevent &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) tep_set_function_resolver(session->tevent.pevent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) machine__resolve_kernel_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) &session->machines.host) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) if (generate_script_lang) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) struct stat perf_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) int input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) if (output_set_by_user()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) "custom fields not supported for generated scripts");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) input = open(data.path, O_RDONLY); /* input_name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) if (input < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) perror("failed to open file");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) err = fstat(input, &perf_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) perror("failed to stat file");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) if (!perf_stat.st_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) fprintf(stderr, "zero-sized file, nothing to do!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) scripting_ops = script_spec__lookup(generate_script_lang);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) if (!scripting_ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) fprintf(stderr, "invalid language specifier");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) err = scripting_ops->generate_script(session->tevent.pevent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) "perf-script");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) if (script_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) err = scripting_ops->start_script(script_name, argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) pr_debug("perf script started with script %s\n\n", script_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) script_started = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) err = perf_session__check_output_opt(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) if (script.time_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) err = perf_time__parse_for_ranges_reltime(script.time_str, session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) &script.ptime_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) &script.range_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) &script.range_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) reltime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) itrace_synth_opts__set_time_range(&itrace_synth_opts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) script.ptime_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) script.range_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) err = evswitch__init(&script.evswitch, session->evlist, stderr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) if (zstd_init(&(session->zstd_data), 0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) err = __cmd_script(&script);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) flush_scripting();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) out_delete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) if (script.ptime_range) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) itrace_synth_opts__clear_time_range(&itrace_synth_opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) zfree(&script.ptime_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) perf_evlist__free_stats(session->evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) perf_session__delete(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) perf_script__exit(&script);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) if (script_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) cleanup_scripting();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) }