at v6.12-rc4 294 lines 8.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2#include "data.h" 3#include "debug.h" 4#include "header.h" 5#include "session.h" 6#include "stat.h" 7#include "tool.h" 8#include "tsc.h" 9#include <sys/mman.h> 10#include <unistd.h> 11 12#ifdef HAVE_ZSTD_SUPPORT 13static int perf_session__process_compressed_event(struct perf_session *session, 14 union perf_event *event, u64 file_offset, 15 const char *file_path) 16{ 17 void *src; 18 size_t decomp_size, src_size; 19 u64 decomp_last_rem = 0; 20 size_t mmap_len, decomp_len = session->header.env.comp_mmap_len; 21 struct decomp *decomp, *decomp_last = session->active_decomp->decomp_last; 22 23 if (decomp_last) { 24 decomp_last_rem = decomp_last->size - decomp_last->head; 25 decomp_len += decomp_last_rem; 26 } 27 28 mmap_len = sizeof(struct decomp) + decomp_len; 29 decomp = mmap(NULL, mmap_len, PROT_READ|PROT_WRITE, 30 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); 31 if (decomp == MAP_FAILED) { 32 pr_err("Couldn't allocate memory for decompression\n"); 33 return -1; 34 } 35 36 decomp->file_pos = file_offset; 37 decomp->file_path = file_path; 38 decomp->mmap_len = mmap_len; 39 decomp->head = 0; 40 41 if (decomp_last_rem) { 42 memcpy(decomp->data, &(decomp_last->data[decomp_last->head]), decomp_last_rem); 43 decomp->size = decomp_last_rem; 44 } 45 46 src = (void *)event + sizeof(struct perf_record_compressed); 47 src_size = event->pack.header.size - sizeof(struct perf_record_compressed); 48 49 decomp_size = zstd_decompress_stream(session->active_decomp->zstd_decomp, src, src_size, 50 &(decomp->data[decomp_last_rem]), decomp_len - decomp_last_rem); 51 if (!decomp_size) { 52 munmap(decomp, mmap_len); 53 pr_err("Couldn't decompress data\n"); 54 return -1; 55 } 56 57 decomp->size += decomp_size; 58 59 if (session->active_decomp->decomp == NULL) 60 session->active_decomp->decomp = decomp; 61 else 62 session->active_decomp->decomp_last->next = decomp; 63 64 session->active_decomp->decomp_last = decomp; 65 66 pr_debug("decomp (B): %zd to %zd\n", src_size, decomp_size); 67 68 return 0; 69} 70#endif 71 72static int process_event_synth_tracing_data_stub(struct perf_session *session 73 __maybe_unused, 74 union perf_event *event 75 __maybe_unused) 76{ 77 dump_printf(": unhandled!\n"); 78 return 0; 79} 80 81static int process_event_synth_attr_stub(const struct perf_tool *tool __maybe_unused, 82 union perf_event *event __maybe_unused, 83 struct evlist **pevlist 84 __maybe_unused) 85{ 86 dump_printf(": unhandled!\n"); 87 return 0; 88} 89 90static int process_event_synth_event_update_stub(const struct perf_tool *tool __maybe_unused, 91 union perf_event *event __maybe_unused, 92 struct evlist **pevlist 93 __maybe_unused) 94{ 95 if (dump_trace) 96 perf_event__fprintf_event_update(event, stdout); 97 98 dump_printf(": unhandled!\n"); 99 return 0; 100} 101 102int process_event_sample_stub(const struct perf_tool *tool __maybe_unused, 103 union perf_event *event __maybe_unused, 104 struct perf_sample *sample __maybe_unused, 105 struct evsel *evsel __maybe_unused, 106 struct machine *machine __maybe_unused) 107{ 108 dump_printf(": unhandled!\n"); 109 return 0; 110} 111 112static int process_event_stub(const struct perf_tool *tool __maybe_unused, 113 union perf_event *event __maybe_unused, 114 struct perf_sample *sample __maybe_unused, 115 struct machine *machine __maybe_unused) 116{ 117 dump_printf(": unhandled!\n"); 118 return 0; 119} 120 121static int process_finished_round_stub(const struct perf_tool *tool __maybe_unused, 122 union perf_event *event __maybe_unused, 123 struct ordered_events *oe __maybe_unused) 124{ 125 dump_printf(": unhandled!\n"); 126 return 0; 127} 128 129static int skipn(int fd, off_t n) 130{ 131 char buf[4096]; 132 ssize_t ret; 133 134 while (n > 0) { 135 ret = read(fd, buf, min(n, (off_t)sizeof(buf))); 136 if (ret <= 0) 137 return ret; 138 n -= ret; 139 } 140 141 return 0; 142} 143 144static s64 process_event_auxtrace_stub(struct perf_session *session __maybe_unused, 145 union perf_event *event) 146{ 147 dump_printf(": unhandled!\n"); 148 if (perf_data__is_pipe(session->data)) 149 skipn(perf_data__fd(session->data), event->auxtrace.size); 150 return event->auxtrace.size; 151} 152 153static int process_event_op2_stub(struct perf_session *session __maybe_unused, 154 union perf_event *event __maybe_unused) 155{ 156 dump_printf(": unhandled!\n"); 157 return 0; 158} 159 160 161static 162int process_event_thread_map_stub(struct perf_session *session __maybe_unused, 163 union perf_event *event __maybe_unused) 164{ 165 if (dump_trace) 166 perf_event__fprintf_thread_map(event, stdout); 167 168 dump_printf(": unhandled!\n"); 169 return 0; 170} 171 172static 173int process_event_cpu_map_stub(struct perf_session *session __maybe_unused, 174 union perf_event *event __maybe_unused) 175{ 176 if (dump_trace) 177 perf_event__fprintf_cpu_map(event, stdout); 178 179 dump_printf(": unhandled!\n"); 180 return 0; 181} 182 183static 184int process_event_stat_config_stub(struct perf_session *session __maybe_unused, 185 union perf_event *event __maybe_unused) 186{ 187 if (dump_trace) 188 perf_event__fprintf_stat_config(event, stdout); 189 190 dump_printf(": unhandled!\n"); 191 return 0; 192} 193 194static int process_stat_stub(struct perf_session *perf_session __maybe_unused, 195 union perf_event *event) 196{ 197 if (dump_trace) 198 perf_event__fprintf_stat(event, stdout); 199 200 dump_printf(": unhandled!\n"); 201 return 0; 202} 203 204static int process_stat_round_stub(struct perf_session *perf_session __maybe_unused, 205 union perf_event *event) 206{ 207 if (dump_trace) 208 perf_event__fprintf_stat_round(event, stdout); 209 210 dump_printf(": unhandled!\n"); 211 return 0; 212} 213 214static int process_event_time_conv_stub(struct perf_session *perf_session __maybe_unused, 215 union perf_event *event) 216{ 217 if (dump_trace) 218 perf_event__fprintf_time_conv(event, stdout); 219 220 dump_printf(": unhandled!\n"); 221 return 0; 222} 223 224static int perf_session__process_compressed_event_stub(struct perf_session *session __maybe_unused, 225 union perf_event *event __maybe_unused, 226 u64 file_offset __maybe_unused, 227 const char *file_path __maybe_unused) 228{ 229 dump_printf(": unhandled!\n"); 230 return 0; 231} 232 233void perf_tool__init(struct perf_tool *tool, bool ordered_events) 234{ 235 tool->ordered_events = ordered_events; 236 tool->ordering_requires_timestamps = false; 237 tool->namespace_events = false; 238 tool->cgroup_events = false; 239 tool->no_warn = false; 240 tool->show_feat_hdr = SHOW_FEAT_NO_HEADER; 241 242 tool->sample = process_event_sample_stub; 243 tool->mmap = process_event_stub; 244 tool->mmap2 = process_event_stub; 245 tool->comm = process_event_stub; 246 tool->namespaces = process_event_stub; 247 tool->cgroup = process_event_stub; 248 tool->fork = process_event_stub; 249 tool->exit = process_event_stub; 250 tool->lost = perf_event__process_lost; 251 tool->lost_samples = perf_event__process_lost_samples; 252 tool->aux = perf_event__process_aux; 253 tool->itrace_start = perf_event__process_itrace_start; 254 tool->context_switch = perf_event__process_switch; 255 tool->ksymbol = perf_event__process_ksymbol; 256 tool->bpf = perf_event__process_bpf; 257 tool->text_poke = perf_event__process_text_poke; 258 tool->aux_output_hw_id = perf_event__process_aux_output_hw_id; 259 tool->read = process_event_sample_stub; 260 tool->throttle = process_event_stub; 261 tool->unthrottle = process_event_stub; 262 tool->attr = process_event_synth_attr_stub; 263 tool->event_update = process_event_synth_event_update_stub; 264 tool->tracing_data = process_event_synth_tracing_data_stub; 265 tool->build_id = process_event_op2_stub; 266 267 if (ordered_events) 268 tool->finished_round = perf_event__process_finished_round; 269 else 270 tool->finished_round = process_finished_round_stub; 271 272 tool->id_index = process_event_op2_stub; 273 tool->auxtrace_info = process_event_op2_stub; 274 tool->auxtrace = process_event_auxtrace_stub; 275 tool->auxtrace_error = process_event_op2_stub; 276 tool->thread_map = process_event_thread_map_stub; 277 tool->cpu_map = process_event_cpu_map_stub; 278 tool->stat_config = process_event_stat_config_stub; 279 tool->stat = process_stat_stub; 280 tool->stat_round = process_stat_round_stub; 281 tool->time_conv = process_event_time_conv_stub; 282 tool->feature = process_event_op2_stub; 283#ifdef HAVE_ZSTD_SUPPORT 284 tool->compressed = perf_session__process_compressed_event; 285#else 286 tool->compressed = perf_session__process_compressed_event_stub; 287#endif 288 tool->finished_init = process_event_op2_stub; 289} 290 291bool perf_tool__compressed_is_stub(const struct perf_tool *tool) 292{ 293 return tool->compressed == perf_session__process_compressed_event_stub; 294}