^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Arm Statistical Profiling Extensions (SPE) support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2017-2018, Arm Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <byteswap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <endian.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "auxtrace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "color.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "machine.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "thread.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "thread-stack.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "tool.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "util/synthetic-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "arm-spe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "arm-spe-decoder/arm-spe-decoder.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "arm-spe-decoder/arm-spe-pkt-decoder.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define MAX_TIMESTAMP (~0ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct arm_spe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct auxtrace auxtrace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct auxtrace_queues queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct auxtrace_heap heap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct itrace_synth_opts synth_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u32 auxtrace_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct perf_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct machine *machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u32 pmu_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u8 timeless_decoding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u8 data_queued;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u64 sample_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u8 sample_flc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) u8 sample_llc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u8 sample_tlb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u8 sample_branch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u8 sample_remote_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u64 l1d_miss_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u64 l1d_access_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u64 llc_miss_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u64 llc_access_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u64 tlb_miss_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u64 tlb_access_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) u64 branch_miss_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u64 remote_access_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u64 kernel_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned long num_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct arm_spe_queue {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct arm_spe *spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) unsigned int queue_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct auxtrace_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct auxtrace_buffer *old_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) union perf_event *event_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) bool on_heap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) bool done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) pid_t pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) pid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct arm_spe_decoder *decoder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u64 time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u64 timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct thread *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct arm_spe_pkt packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) size_t pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int ret, pkt_len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) char desc[ARM_SPE_PKT_DESC_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) const char *color = PERF_COLOR_BLUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) color_fprintf(stdout, color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ". ... ARM SPE data: size %zu bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) while (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ret = arm_spe_get_packet(buf, len, &packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) pkt_len = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) pkt_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) printf(".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) color_fprintf(stdout, color, " %08x: ", pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) for (i = 0; i < pkt_len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) color_fprintf(stdout, color, " %02x", buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) for (; i < 16; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) color_fprintf(stdout, color, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ret = arm_spe_pkt_desc(&packet, desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ARM_SPE_PKT_DESC_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) color_fprintf(stdout, color, " %s\n", desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) color_fprintf(stdout, color, " Bad packet!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) pos += pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) buf += pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) len -= pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static void arm_spe_dump_event(struct arm_spe *spe, unsigned char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) printf(".\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) arm_spe_dump(spe, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int arm_spe_get_trace(struct arm_spe_buffer *b, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct arm_spe_queue *speq = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct auxtrace_buffer *buffer = speq->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct auxtrace_buffer *old_buffer = speq->old_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct auxtrace_queue *queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) queue = &speq->spe->queues.queue_array[speq->queue_nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) buffer = auxtrace_buffer__next(queue, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* If no more data, drop the previous auxtrace_buffer and return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (!buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (old_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) auxtrace_buffer__drop_data(old_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) b->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) speq->buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* If the aux_buffer doesn't have data associated, try to load it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!buffer->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* get the file desc associated with the perf data file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int fd = perf_data__fd(speq->spe->session->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) buffer->data = auxtrace_buffer__get_data(buffer, fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (!buffer->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) b->len = buffer->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) b->buf = buffer->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (b->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (old_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) auxtrace_buffer__drop_data(old_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) speq->old_buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) auxtrace_buffer__drop_data(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return arm_spe_get_trace(b, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static struct arm_spe_queue *arm_spe__alloc_queue(struct arm_spe *spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) unsigned int queue_nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct arm_spe_params params = { .get_trace = 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct arm_spe_queue *speq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) speq = zalloc(sizeof(*speq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!speq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) speq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (!speq->event_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) speq->spe = spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) speq->queue_nr = queue_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) speq->pid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) speq->tid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) speq->cpu = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* params set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) params.get_trace = arm_spe_get_trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) params.data = speq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* create new decoder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) speq->decoder = arm_spe_decoder_new(¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (!speq->decoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return speq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) zfree(&speq->event_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) free(speq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static inline u8 arm_spe_cpumode(struct arm_spe *spe, u64 ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return ip >= spe->kernel_start ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) PERF_RECORD_MISC_KERNEL :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) PERF_RECORD_MISC_USER;
^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) static void arm_spe_prep_sample(struct arm_spe *spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct arm_spe_queue *speq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct arm_spe_record *record = &speq->decoder->record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (!spe->timeless_decoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) sample->time = speq->timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) sample->ip = record->from_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) sample->cpumode = arm_spe_cpumode(spe, sample->ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) sample->pid = speq->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) sample->tid = speq->tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) sample->addr = record->to_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) sample->period = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) sample->cpu = speq->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) event->sample.header.type = PERF_RECORD_SAMPLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) event->sample.header.misc = sample->cpumode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) event->sample.header.size = sizeof(struct perf_event_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int arm_spe__inject_event(union perf_event *event, struct perf_sample *sample, u64 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) event->header.size = perf_event__sample_event_size(sample, type, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return perf_event__synthesize_sample(event, type, 0, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) arm_spe_deliver_synth_event(struct arm_spe *spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct arm_spe_queue *speq __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (spe->synth_opts.inject) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ret = arm_spe__inject_event(event, sample, spe->sample_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret = perf_session__deliver_synth_event(spe->session, event, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) pr_err("ARM SPE: failed to deliver event, error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) arm_spe_synth_spe_events_sample(struct arm_spe_queue *speq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) u64 spe_events_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct arm_spe *spe = speq->spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) union perf_event *event = speq->event_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct perf_sample sample = { .ip = 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) arm_spe_prep_sample(spe, speq, event, &sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) sample.id = spe_events_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) sample.stream_id = spe_events_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return arm_spe_deliver_synth_event(spe, speq, event, &sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int arm_spe_sample(struct arm_spe_queue *speq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) const struct arm_spe_record *record = &speq->decoder->record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct arm_spe *spe = speq->spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (spe->sample_flc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (record->type & ARM_SPE_L1D_MISS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) speq, spe->l1d_miss_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (record->type & ARM_SPE_L1D_ACCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) speq, spe->l1d_access_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (spe->sample_llc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (record->type & ARM_SPE_LLC_MISS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) speq, spe->llc_miss_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (record->type & ARM_SPE_LLC_ACCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) speq, spe->llc_access_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (spe->sample_tlb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (record->type & ARM_SPE_TLB_MISS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) speq, spe->tlb_miss_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (record->type & ARM_SPE_TLB_ACCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) err = arm_spe_synth_spe_events_sample(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) speq, spe->tlb_access_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^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) if (spe->sample_branch && (record->type & ARM_SPE_BRANCH_MISS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) err = arm_spe_synth_spe_events_sample(speq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) spe->branch_miss_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (spe->sample_remote_access &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) (record->type & ARM_SPE_REMOTE_ACCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) err = arm_spe_synth_spe_events_sample(speq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) spe->remote_access_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int arm_spe_run_decoder(struct arm_spe_queue *speq, u64 *timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct arm_spe *spe = speq->spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (!spe->kernel_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) spe->kernel_start = machine__kernel_start(spe->machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ret = arm_spe_decode(speq->decoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) pr_debug("No data or all data has been processed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * Error is detected when decode SPE trace data, continue to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * the next trace data and find out more records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ret = arm_spe_sample(speq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (!spe->timeless_decoding && speq->timestamp >= *timestamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) *timestamp = speq->timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int arm_spe__setup_queue(struct arm_spe *spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct auxtrace_queue *queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) unsigned int queue_nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct arm_spe_queue *speq = queue->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct arm_spe_record *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (list_empty(&queue->head) || speq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) speq = arm_spe__alloc_queue(spe, queue_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (!speq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) queue->priv = speq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (queue->cpu != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) speq->cpu = queue->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (!speq->on_heap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (spe->timeless_decoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ret = arm_spe_decode(speq->decoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) record = &speq->decoder->record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) speq->timestamp = record->timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret = auxtrace_heap__add(&spe->heap, queue_nr, speq->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) speq->on_heap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static int arm_spe__setup_queues(struct arm_spe *spe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) for (i = 0; i < spe->queues.nr_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ret = arm_spe__setup_queue(spe, &spe->queues.queue_array[i], i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static int arm_spe__update_queues(struct arm_spe *spe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (spe->queues.new_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) spe->queues.new_data = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return arm_spe__setup_queues(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static bool arm_spe__is_timeless_decoding(struct arm_spe *spe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct evlist *evlist = spe->session->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) bool timeless_decoding = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * Circle through the list of event and complain if we find one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * with the time bit set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if ((evsel->core.attr.sample_type & PERF_SAMPLE_TIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) timeless_decoding = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return timeless_decoding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static void arm_spe_set_pid_tid_cpu(struct arm_spe *spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct auxtrace_queue *queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct arm_spe_queue *speq = queue->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) pid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) tid = machine__get_current_tid(spe->machine, speq->cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (tid != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) speq->tid = tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) thread__zput(speq->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) speq->tid = queue->tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if ((!speq->thread) && (speq->tid != -1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) speq->thread = machine__find_thread(spe->machine, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) speq->tid);
^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) if (speq->thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) speq->pid = speq->thread->pid_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (queue->cpu == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) speq->cpu = speq->thread->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int arm_spe_process_queues(struct arm_spe *spe, u64 timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unsigned int queue_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) u64 ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct auxtrace_queue *queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct arm_spe_queue *speq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (!spe->heap.heap_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (spe->heap.heap_array[0].ordinal >= timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) queue_nr = spe->heap.heap_array[0].queue_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) queue = &spe->queues.queue_array[queue_nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) speq = queue->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) auxtrace_heap__pop(&spe->heap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (spe->heap.heap_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ts = spe->heap.heap_array[0].ordinal + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (ts > timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ts = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ts = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) arm_spe_set_pid_tid_cpu(spe, queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ret = arm_spe_run_decoder(speq, &ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) auxtrace_heap__add(&spe->heap, queue_nr, ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ret = auxtrace_heap__add(&spe->heap, queue_nr, ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) speq->on_heap = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return 0;
^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) static int arm_spe_process_timeless_queues(struct arm_spe *spe, pid_t tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) u64 time_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct auxtrace_queues *queues = &spe->queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) u64 ts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) for (i = 0; i < queues->nr_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct auxtrace_queue *queue = &spe->queues.queue_array[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct arm_spe_queue *speq = queue->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (speq && (tid == -1 || speq->tid == tid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) speq->time = time_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) arm_spe_set_pid_tid_cpu(spe, queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) arm_spe_run_decoder(speq, &ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int arm_spe_process_event(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct perf_tool *tool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) u64 timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct arm_spe *spe = container_of(session->auxtrace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct arm_spe, auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (dump_trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (!tool->ordered_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) pr_err("SPE trace requires ordered events\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return -EINVAL;
^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 (sample->time && (sample->time != (u64) -1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) timestamp = sample->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) timestamp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (timestamp || spe->timeless_decoding) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) err = arm_spe__update_queues(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (spe->timeless_decoding) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (event->header.type == PERF_RECORD_EXIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) err = arm_spe_process_timeless_queues(spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) event->fork.tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) sample->time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) } else if (timestamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (event->header.type == PERF_RECORD_EXIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) err = arm_spe_process_queues(spe, timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^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 err;
^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) static int arm_spe_process_auxtrace_event(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct perf_tool *tool __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (!spe->data_queued) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct auxtrace_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) off_t data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) int fd = perf_data__fd(session->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (perf_data__is_pipe(session->data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) data_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) data_offset = lseek(fd, 0, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (data_offset == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) err = auxtrace_queues__add_event(&spe->queues, session, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) data_offset, &buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /* Dump here now we have copied a piped trace out of the pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (dump_trace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (auxtrace_buffer__get_data(buffer, fd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) arm_spe_dump_event(spe, buffer->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) buffer->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) auxtrace_buffer__put_data(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static int arm_spe_flush(struct perf_session *session __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct perf_tool *tool __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (dump_trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (!tool->ordered_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ret = arm_spe__update_queues(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (spe->timeless_decoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return arm_spe_process_timeless_queues(spe, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) MAX_TIMESTAMP - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return arm_spe_process_queues(spe, MAX_TIMESTAMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static void arm_spe_free_queue(void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct arm_spe_queue *speq = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (!speq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) thread__zput(speq->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) arm_spe_decoder_free(speq->decoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) zfree(&speq->event_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) free(speq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static void arm_spe_free_events(struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct auxtrace_queues *queues = &spe->queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) for (i = 0; i < queues->nr_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) arm_spe_free_queue(queues->queue_array[i].priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) queues->queue_array[i].priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) auxtrace_queues__free(queues);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static void arm_spe_free(struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) auxtrace_heap__free(&spe->heap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) arm_spe_free_events(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) session->auxtrace = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) free(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static bool arm_spe_evsel_is_auxtrace(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe, auxtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return evsel->core.attr.type == spe->pmu_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static const char * const arm_spe_info_fmts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) [ARM_SPE_PMU_TYPE] = " PMU Type %"PRId64"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static void arm_spe_print_info(__u64 *arr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (!dump_trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) fprintf(stdout, arm_spe_info_fmts[ARM_SPE_PMU_TYPE], arr[ARM_SPE_PMU_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct arm_spe_synth {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct perf_tool dummy_tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct perf_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static int arm_spe_event_synth(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct perf_sample *sample __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct machine *machine __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct arm_spe_synth *arm_spe_synth =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) container_of(tool, struct arm_spe_synth, dummy_tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return perf_session__deliver_synth_event(arm_spe_synth->session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) event, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static int arm_spe_synth_event(struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct perf_event_attr *attr, u64 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) struct arm_spe_synth arm_spe_synth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) memset(&arm_spe_synth, 0, sizeof(struct arm_spe_synth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) arm_spe_synth.session = session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return perf_event__synthesize_attr(&arm_spe_synth.dummy_tool, attr, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) &id, arm_spe_event_synth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static void arm_spe_set_event_name(struct evlist *evlist, u64 id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (evsel->core.id && evsel->core.id[0] == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (evsel->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) zfree(&evsel->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) evsel->name = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) arm_spe_synth_events(struct arm_spe *spe, struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct evlist *evlist = session->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) u64 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (evsel->core.attr.type == spe->pmu_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) break;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) pr_debug("No selected events with SPE trace data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) memset(&attr, 0, sizeof(struct perf_event_attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) attr.size = sizeof(struct perf_event_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) attr.type = PERF_TYPE_HARDWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) attr.sample_type = evsel->core.attr.sample_type & PERF_SAMPLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) PERF_SAMPLE_PERIOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (spe->timeless_decoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) attr.sample_type |= PERF_SAMPLE_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) spe->sample_type = attr.sample_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) attr.exclude_user = evsel->core.attr.exclude_user;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) attr.exclude_kernel = evsel->core.attr.exclude_kernel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) attr.exclude_hv = evsel->core.attr.exclude_hv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) attr.exclude_host = evsel->core.attr.exclude_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) attr.exclude_guest = evsel->core.attr.exclude_guest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) attr.sample_id_all = evsel->core.attr.sample_id_all;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) attr.read_format = evsel->core.attr.read_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* create new id val to be a fixed offset from evsel id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) id = evsel->core.id[0] + 1000000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) id = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (spe->synth_opts.flc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) spe->sample_flc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) /* Level 1 data cache miss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) spe->l1d_miss_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) arm_spe_set_event_name(evlist, id, "l1d-miss");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* Level 1 data cache access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) spe->l1d_access_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) arm_spe_set_event_name(evlist, id, "l1d-access");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (spe->synth_opts.llc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) spe->sample_llc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) /* Last level cache miss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) spe->llc_miss_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) arm_spe_set_event_name(evlist, id, "llc-miss");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /* Last level cache access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) spe->llc_access_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) arm_spe_set_event_name(evlist, id, "llc-access");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (spe->synth_opts.tlb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) spe->sample_tlb = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* TLB miss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) spe->tlb_miss_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) arm_spe_set_event_name(evlist, id, "tlb-miss");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* TLB access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) spe->tlb_access_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) arm_spe_set_event_name(evlist, id, "tlb-access");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (spe->synth_opts.branches) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) spe->sample_branch = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /* Branch miss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) spe->branch_miss_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) arm_spe_set_event_name(evlist, id, "branch-miss");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (spe->synth_opts.remote_access) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) spe->sample_remote_access = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /* Remote access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) err = arm_spe_synth_event(session, &attr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) spe->remote_access_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) arm_spe_set_event_name(evlist, id, "remote-access");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) id += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) int arm_spe_process_auxtrace_info(union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) size_t min_sz = sizeof(u64) * ARM_SPE_AUXTRACE_PRIV_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) struct arm_spe *spe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (auxtrace_info->header.size < sizeof(struct perf_record_auxtrace_info) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) min_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) spe = zalloc(sizeof(struct arm_spe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (!spe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) err = auxtrace_queues__init(&spe->queues);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) spe->session = session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) spe->machine = &session->machines.host; /* No kvm support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) spe->auxtrace_type = auxtrace_info->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) spe->pmu_type = auxtrace_info->priv[ARM_SPE_PMU_TYPE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) spe->timeless_decoding = arm_spe__is_timeless_decoding(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) spe->auxtrace.process_event = arm_spe_process_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) spe->auxtrace.process_auxtrace_event = arm_spe_process_auxtrace_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) spe->auxtrace.flush_events = arm_spe_flush;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) spe->auxtrace.free_events = arm_spe_free_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) spe->auxtrace.free = arm_spe_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) spe->auxtrace.evsel_is_auxtrace = arm_spe_evsel_is_auxtrace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) session->auxtrace = &spe->auxtrace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) arm_spe_print_info(&auxtrace_info->priv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (dump_trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (session->itrace_synth_opts && session->itrace_synth_opts->set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) spe->synth_opts = *session->itrace_synth_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) itrace_synth_opts__set_default(&spe->synth_opts, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) err = arm_spe_synth_events(spe, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) goto err_free_queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) err = auxtrace_queues__process_index(&spe->queues, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) goto err_free_queues;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (spe->queues.populated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) spe->data_queued = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) err_free_queues:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) auxtrace_queues__free(&spe->queues);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) session->auxtrace = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) free(spe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }