1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <linux/kernel.h> 2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <traceevent/event-parse.h> 3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <byteswap.h> 5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <unistd.h> 6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sys/types.h> 7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sys/mman.h> 8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "evlist.h" 10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "evsel.h" 11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "session.h" 12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "tool.h" 13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "sort.h" 14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util.h" 15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "cpumap.h" 16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "perf_regs.h" 17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "vdso.h" 18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int perf_session__open(struct perf_session *self, bool force) 20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct stat input_stat; 22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!strcmp(self->filename, "-")) { 24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->fd_pipe = true; 25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->fd = STDIN_FILENO; 26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (perf_session__read_header(self) < 0) 28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("incompatible file format (rerun with -v to learn more)"); 29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->fd = open(self->filename, O_RDONLY); 34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (self->fd < 0) { 35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int err = errno; 36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("failed to open %s: %s", self->filename, strerror(err)); 38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (err == ENOENT && !strcmp(self->filename, "perf.data")) 39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err(" (try 'perf record' first)"); 40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("\n"); 41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -errno; 42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (fstat(self->fd, &input_stat) < 0) 45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_close; 46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) { 48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("file %s not owned by current user or root\n", 49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->filename); 50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_close; 51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!input_stat.st_size) { 54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_info("zero-sized file (%s), nothing to do!\n", 55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->filename); 56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_close; 57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (perf_session__read_header(self) < 0) { 60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("incompatible file format (rerun with -v to learn more)"); 61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_close; 62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!perf_evlist__valid_sample_type(self->evlist)) { 65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("non matching sample_type"); 66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_close; 67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!perf_evlist__valid_sample_id_all(self->evlist)) { 70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("non matching sample_id_all"); 71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_close; 72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!perf_evlist__valid_read_format(self->evlist)) { 75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("non matching read_format"); 76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_close; 77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->size = input_stat.st_size; 80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_close: 83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng close(self->fd); 84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->fd = -1; 85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid perf_session__set_id_hdr_size(struct perf_session *session) 89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist); 91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng machines__set_id_hdr_size(&session->machines, id_hdr_size); 93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint perf_session__create_kernel_maps(struct perf_session *self) 96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret = machine__create_kernel_maps(&self->machines.host); 98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret >= 0) 100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = machines__create_guest_kernel_maps(&self->machines); 101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_session__destroy_kernel_maps(struct perf_session *self) 105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng machines__destroy_kernel_maps(&self->machines); 107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct perf_session *perf_session__new(const char *filename, int mode, 110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool force, bool repipe, 111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool) 112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_session *self; 114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct stat st; 115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size_t len; 116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!filename || !strlen(filename)) { 118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) 119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng filename = "-"; 120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng else 121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng filename = "perf.data"; 122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng len = strlen(filename); 125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self = zalloc(sizeof(*self) + len); 126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (self == NULL) 128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out; 129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng memcpy(self->filename, filename, len); 131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->repipe = repipe; 132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng INIT_LIST_HEAD(&self->ordered_samples.samples); 133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng INIT_LIST_HEAD(&self->ordered_samples.sample_cache); 134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng INIT_LIST_HEAD(&self->ordered_samples.to_free); 135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng machines__init(&self->machines); 136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (mode == O_RDONLY) { 138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (perf_session__open(self, force) < 0) 139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_delete; 140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__set_id_hdr_size(self); 141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } else if (mode == O_WRONLY) { 142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* 143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * In O_RDONLY mode this will be performed when reading the 144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * kernel MMAP event, in perf_event__process_mmap(). 145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (perf_session__create_kernel_maps(self) < 0) 147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_delete; 148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool && tool->ordering_requires_timestamps && 151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->ordered_samples && !perf_evlist__sample_id_all(self->evlist)) { 152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); 153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->ordered_samples = false; 154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout: 157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return self; 158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_delete: 159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__delete(self); 160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_session__delete_dead_threads(struct perf_session *session) 164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng machine__delete_dead_threads(&session->machines.host); 166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_session__delete_threads(struct perf_session *session) 169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng machine__delete_threads(&session->machines.host); 171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_session_env__delete(struct perf_session_env *env) 174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->hostname); 176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->os_release); 177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->version); 178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->arch); 179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->cpu_desc); 180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->cpuid); 181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->cmdline); 183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->sibling_cores); 184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->sibling_threads); 185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->numa_nodes); 186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(env->pmu_mappings); 187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid perf_session__delete(struct perf_session *self) 190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__destroy_kernel_maps(self); 192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__delete_dead_threads(self); 193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__delete_threads(self); 194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session_env__delete(&self->header.env); 195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng machines__exit(&self->machines); 196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng close(self->fd); 197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(self); 198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng vdso__exit(); 199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int process_event_synth_tracing_data_stub(struct perf_tool *tool 202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng __maybe_unused, 203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event 204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng __maybe_unused, 205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_session *session 206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng __maybe_unused) 207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng dump_printf(": unhandled!\n"); 209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int process_event_synth_attr_stub(struct perf_tool *tool __maybe_unused, 213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event __maybe_unused, 214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evlist **pevlist 215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng __maybe_unused) 216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng dump_printf(": unhandled!\n"); 218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int process_event_sample_stub(struct perf_tool *tool __maybe_unused, 222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event __maybe_unused, 223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample __maybe_unused, 224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evsel *evsel __maybe_unused, 225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct machine *machine __maybe_unused) 226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng dump_printf(": unhandled!\n"); 228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int process_event_stub(struct perf_tool *tool __maybe_unused, 232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event __maybe_unused, 233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample __maybe_unused, 234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct machine *machine __maybe_unused) 235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng dump_printf(": unhandled!\n"); 237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int process_finished_round_stub(struct perf_tool *tool __maybe_unused, 241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event __maybe_unused, 242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_session *perf_session 243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng __maybe_unused) 244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng dump_printf(": unhandled!\n"); 246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int process_finished_round(struct perf_tool *tool, 250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event, 251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_session *session); 252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid perf_tool__fill_defaults(struct perf_tool *tool) 254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->sample == NULL) 256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->sample = process_event_sample_stub; 257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->mmap == NULL) 258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->mmap = process_event_stub; 259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->mmap2 == NULL) 260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->mmap2 = process_event_stub; 261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->comm == NULL) 262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->comm = process_event_stub; 263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->fork == NULL) 264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->fork = process_event_stub; 265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->exit == NULL) 266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->exit = process_event_stub; 267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->lost == NULL) 268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->lost = perf_event__process_lost; 269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->read == NULL) 270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->read = process_event_sample_stub; 271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->throttle == NULL) 272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->throttle = process_event_stub; 273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->unthrottle == NULL) 274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->unthrottle = process_event_stub; 275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->attr == NULL) 276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->attr = process_event_synth_attr_stub; 277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->tracing_data == NULL) 278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->tracing_data = process_event_synth_tracing_data_stub; 279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->build_id == NULL) 280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->build_id = process_finished_round_stub; 281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->finished_round == NULL) { 282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->ordered_samples) 283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->finished_round = process_finished_round; 284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng else 285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tool->finished_round = process_finished_round_stub; 286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid mem_bswap_32(void *src, int byte_size) 290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u32 *m = src; 292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (byte_size > 0) { 293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *m = bswap_32(*m); 294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng byte_size -= sizeof(u32); 295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ++m; 296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid mem_bswap_64(void *src, int byte_size) 300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 *m = src; 302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (byte_size > 0) { 304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *m = bswap_64(*m); 305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng byte_size -= sizeof(u64); 306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ++m; 307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void swap_sample_id_all(union perf_event *event, void *data) 311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng void *end = (void *) event + event->header.size; 313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int size = end - data; 314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng BUG_ON(size % sizeof(u64)); 316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mem_bswap_64(data, size); 317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_event__all64_swap(union perf_event *event, 320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool sample_id_all __maybe_unused) 321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_event_header *hdr = &event->header; 323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mem_bswap_64(hdr + 1, event->header.size - sizeof(*hdr)); 324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_event__comm_swap(union perf_event *event, bool sample_id_all) 327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->comm.pid = bswap_32(event->comm.pid); 329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->comm.tid = bswap_32(event->comm.tid); 330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_id_all) { 332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng void *data = &event->comm.comm; 333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng data += PERF_ALIGN(strlen(data) + 1, sizeof(u64)); 335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng swap_sample_id_all(event, data); 336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_event__mmap_swap(union perf_event *event, 340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool sample_id_all) 341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap.pid = bswap_32(event->mmap.pid); 343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap.tid = bswap_32(event->mmap.tid); 344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap.start = bswap_64(event->mmap.start); 345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap.len = bswap_64(event->mmap.len); 346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap.pgoff = bswap_64(event->mmap.pgoff); 347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_id_all) { 349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng void *data = &event->mmap.filename; 350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng data += PERF_ALIGN(strlen(data) + 1, sizeof(u64)); 352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng swap_sample_id_all(event, data); 353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_event__mmap2_swap(union perf_event *event, 357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool sample_id_all) 358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap2.pid = bswap_32(event->mmap2.pid); 360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap2.tid = bswap_32(event->mmap2.tid); 361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap2.start = bswap_64(event->mmap2.start); 362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap2.len = bswap_64(event->mmap2.len); 363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap2.pgoff = bswap_64(event->mmap2.pgoff); 364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap2.maj = bswap_32(event->mmap2.maj); 365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap2.min = bswap_32(event->mmap2.min); 366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->mmap2.ino = bswap_64(event->mmap2.ino); 367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_id_all) { 369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng void *data = &event->mmap2.filename; 370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng data += PERF_ALIGN(strlen(data) + 1, sizeof(u64)); 372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng swap_sample_id_all(event, data); 373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_event__task_swap(union perf_event *event, bool sample_id_all) 376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->fork.pid = bswap_32(event->fork.pid); 378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->fork.tid = bswap_32(event->fork.tid); 379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->fork.ppid = bswap_32(event->fork.ppid); 380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->fork.ptid = bswap_32(event->fork.ptid); 381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->fork.time = bswap_64(event->fork.time); 382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_id_all) 384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng swap_sample_id_all(event, &event->fork + 1); 385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_event__read_swap(union perf_event *event, bool sample_id_all) 388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->read.pid = bswap_32(event->read.pid); 390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->read.tid = bswap_32(event->read.tid); 391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->read.value = bswap_64(event->read.value); 392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->read.time_enabled = bswap_64(event->read.time_enabled); 393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->read.time_running = bswap_64(event->read.time_running); 394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->read.id = bswap_64(event->read.id); 395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_id_all) 397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng swap_sample_id_all(event, &event->read + 1); 398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic u8 revbyte(u8 b) 401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int rev = (b >> 4) | ((b & 0xf) << 4); 403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng rev = ((rev & 0xcc) >> 2) | ((rev & 0x33) << 2); 404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng rev = ((rev & 0xaa) >> 1) | ((rev & 0x55) << 1); 405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return (u8) rev; 406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* 409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * XXX this is hack in attempt to carry flags bitfield 410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * throught endian village. ABI says: 411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Bit-fields are allocated from right to left (least to most significant) 413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * on little-endian implementations and from left to right (most to least 414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * significant) on big-endian implementations. 415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * The above seems to be byte specific, so we need to reverse each 417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * byte of the bitfield. 'Internet' also says this might be implementation 418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * specific and we probably need proper fix and carry perf_event_attr 419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * bitfield flags in separate data file FEAT_ section. Thought this seems 420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * to work for now. 421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void swap_bitfield(u8 *p, unsigned len) 423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unsigned i; 425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < len; i++) { 427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *p = revbyte(*p); 428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng p++; 429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* exported for swapping attributes in file header */ 433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid perf_event__attr_swap(struct perf_event_attr *attr) 434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->type = bswap_32(attr->type); 436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->size = bswap_32(attr->size); 437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->config = bswap_64(attr->config); 438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->sample_period = bswap_64(attr->sample_period); 439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->sample_type = bswap_64(attr->sample_type); 440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->read_format = bswap_64(attr->read_format); 441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->wakeup_events = bswap_32(attr->wakeup_events); 442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->bp_type = bswap_32(attr->bp_type); 443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->bp_addr = bswap_64(attr->bp_addr); 444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->bp_len = bswap_64(attr->bp_len); 445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64)); 447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_event__hdr_attr_swap(union perf_event *event, 450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool sample_id_all __maybe_unused) 451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size_t size; 453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_event__attr_swap(&event->attr.attr); 455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size = event->header.size; 457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size -= (void *)&event->attr.id - (void *)event; 458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mem_bswap_64(event->attr.id, size); 459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_event__event_type_swap(union perf_event *event, 462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool sample_id_all __maybe_unused) 463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->event_type.event_type.event_id = 465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bswap_64(event->event_type.event_type.event_id); 466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_event__tracing_data_swap(union perf_event *event, 469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool sample_id_all __maybe_unused) 470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 471e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->tracing_data.size = bswap_32(event->tracing_data.size); 472e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 473e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 474e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtypedef void (*perf_event__swap_op)(union perf_event *event, 475e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool sample_id_all); 476e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 477e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic perf_event__swap_op perf_event__swap_ops[] = { 478e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_MMAP] = perf_event__mmap_swap, 479e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_MMAP2] = perf_event__mmap2_swap, 480e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_COMM] = perf_event__comm_swap, 481e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_FORK] = perf_event__task_swap, 482e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_EXIT] = perf_event__task_swap, 483e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_LOST] = perf_event__all64_swap, 484e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_READ] = perf_event__read_swap, 485e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_SAMPLE] = perf_event__all64_swap, 486e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap, 487e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap, 488e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap, 489e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_HEADER_BUILD_ID] = NULL, 490e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng [PERF_RECORD_HEADER_MAX] = NULL, 491e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}; 492e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 493e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct sample_queue { 494e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 timestamp; 495e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 file_offset; 496e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event; 497e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct list_head list; 498e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}; 499e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 500e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_session_free_sample_buffers(struct perf_session *session) 501e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 502e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct ordered_samples *os = &session->ordered_samples; 503e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 504e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (!list_empty(&os->to_free)) { 505e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct sample_queue *sq; 506e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 507e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sq = list_entry(os->to_free.next, struct sample_queue, list); 508e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_del(&sq->list); 509e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(sq); 510e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 511e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 512e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 513e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int perf_session_deliver_event(struct perf_session *session, 514e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event, 515e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample, 516e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool, 517e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 file_offset); 518e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 519e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int flush_sample_queue(struct perf_session *s, 520e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool) 521e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 522e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct ordered_samples *os = &s->ordered_samples; 523e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct list_head *head = &os->samples; 524e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct sample_queue *tmp, *iter; 525e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample sample; 526e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 limit = os->next_flush; 527e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; 528e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unsigned idx = 0, progress_next = os->nr_samples / 16; 529e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool show_progress = limit == ULLONG_MAX; 530e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret; 531e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 532e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!tool->ordered_samples || !limit) 533e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 534e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 535e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_for_each_entry_safe(iter, tmp, head, list) { 536e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session_done()) 537e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 538e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 539e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (iter->timestamp > limit) 540e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng break; 541e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 542e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample); 543e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret) 544e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("Can't parse sample, err = %d\n", ret); 545e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng else { 546e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = perf_session_deliver_event(s, iter->event, &sample, tool, 547e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng iter->file_offset); 548e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret) 549e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 550e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 551e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 552e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng os->last_flush = iter->timestamp; 553e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_del(&iter->list); 554e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_add(&iter->list, &os->sample_cache); 555e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (show_progress && (++idx >= progress_next)) { 556e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng progress_next += os->nr_samples / 16; 557e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ui_progress__update(idx, os->nr_samples, 558e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "Processing time ordered events..."); 559e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 560e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 561e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 562e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (list_empty(head)) { 563e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng os->last_sample = NULL; 564e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } else if (last_ts <= limit) { 565e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng os->last_sample = 566e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_entry(head->prev, struct sample_queue, list); 567e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 568e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 569e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng os->nr_samples = 0; 570e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 571e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 572e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 573e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 574e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* 575e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * When perf record finishes a pass on every buffers, it records this pseudo 576e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * event. 577e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * We record the max timestamp t found in the pass n. 578e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Assuming these timestamps are monotonic across cpus, we know that if 579e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * a buffer still has events with timestamps below t, they will be all 580e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * available and then read in the pass n + 1. 581e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Hence when we start to read the pass n + 2, we can safely flush every 582e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * events with timestamps below t. 583e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 584e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ============ PASS n ================= 585e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * CPU 0 | CPU 1 586e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * | 587e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * cnt1 timestamps | cnt2 timestamps 588e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 1 | 2 589e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 2 | 3 590e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * - | 4 <--- max recorded 591e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 592e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ============ PASS n + 1 ============== 593e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * CPU 0 | CPU 1 594e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * | 595e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * cnt1 timestamps | cnt2 timestamps 596e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 3 | 5 597e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 4 | 6 598e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 5 | 7 <---- max recorded 599e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 600e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Flush every events below timestamp 4 601e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 602e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ============ PASS n + 2 ============== 603e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * CPU 0 | CPU 1 604e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * | 605e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * cnt1 timestamps | cnt2 timestamps 606e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 6 | 8 607e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 7 | 9 608e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * - | 10 609e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 610e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Flush every events below timestamp 7 611e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * etc... 612e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 613e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int process_finished_round(struct perf_tool *tool, 614e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event __maybe_unused, 615e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_session *session) 616e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 617e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret = flush_sample_queue(session, tool); 618e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!ret) 619e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->ordered_samples.next_flush = session->ordered_samples.max_timestamp; 620e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 621e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 622e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 623e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 624e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* The queue is ordered by time */ 625e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void __queue_event(struct sample_queue *new, struct perf_session *s) 626e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 627e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct ordered_samples *os = &s->ordered_samples; 628e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct sample_queue *sample = os->last_sample; 629e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 timestamp = new->timestamp; 630e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct list_head *p; 631e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 632e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ++os->nr_samples; 633e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng os->last_sample = new; 634e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 635e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!sample) { 636e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_add(&new->list, &os->samples); 637e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng os->max_timestamp = timestamp; 638e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 639e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 640e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 641e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* 642e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * last_sample might point to some random place in the list as it's 643e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the last queued event. We expect that the new event is close to 644e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * this. 645e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 646e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample->timestamp <= timestamp) { 647e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (sample->timestamp <= timestamp) { 648e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng p = sample->list.next; 649e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (p == &os->samples) { 650e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_add_tail(&new->list, &os->samples); 651e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng os->max_timestamp = timestamp; 652e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 653e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 654e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample = list_entry(p, struct sample_queue, list); 655e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 656e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_add_tail(&new->list, &sample->list); 657e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } else { 658e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (sample->timestamp > timestamp) { 659e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng p = sample->list.prev; 660e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (p == &os->samples) { 661e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_add(&new->list, &os->samples); 662e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 663e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 664e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample = list_entry(p, struct sample_queue, list); 665e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 666e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_add(&new->list, &sample->list); 667e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 668e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 669e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 670e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct sample_queue)) 671e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 672e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint perf_session_queue_event(struct perf_session *s, union perf_event *event, 673e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample, u64 file_offset) 674e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 675e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct ordered_samples *os = &s->ordered_samples; 676e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct list_head *sc = &os->sample_cache; 677e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 timestamp = sample->time; 678e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct sample_queue *new; 679e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 680e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!timestamp || timestamp == ~0ULL) 681e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -ETIME; 682e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 683e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (timestamp < s->ordered_samples.last_flush) { 684e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("Warning: Timestamp below last timeslice flush\n"); 685e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -EINVAL; 686e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 687e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 688e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!list_empty(sc)) { 689e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng new = list_entry(sc->next, struct sample_queue, list); 690e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_del(&new->list); 691e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } else if (os->sample_buffer) { 692e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng new = os->sample_buffer + os->sample_buffer_idx; 693e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (++os->sample_buffer_idx == MAX_SAMPLE_BUFFER) 694e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng os->sample_buffer = NULL; 695e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } else { 696e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng os->sample_buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new)); 697e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!os->sample_buffer) 698e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -ENOMEM; 699e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_add(&os->sample_buffer->list, &os->to_free); 700e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng os->sample_buffer_idx = 2; 701e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng new = os->sample_buffer + 1; 702e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 703e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 704e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng new->timestamp = timestamp; 705e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng new->file_offset = file_offset; 706e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng new->event = event; 707e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 708e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng __queue_event(new, s); 709e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 710e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 711e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 712e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 713e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void callchain__printf(struct perf_sample *sample) 714e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 715e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unsigned int i; 716e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 717e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("... chain: nr:%" PRIu64 "\n", sample->callchain->nr); 718e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 719e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < sample->callchain->nr; i++) 720e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("..... %2d: %016" PRIx64 "\n", 721e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng i, sample->callchain->ips[i]); 722e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 723e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 724e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void branch_stack__printf(struct perf_sample *sample) 725e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 726e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng uint64_t i; 727e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 728e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("... branch stack: nr:%" PRIu64 "\n", sample->branch_stack->nr); 729e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 730e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < sample->branch_stack->nr; i++) 731e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 "\n", 732e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng i, sample->branch_stack->entries[i].from, 733e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample->branch_stack->entries[i].to); 734e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 735e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 736e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void regs_dump__printf(u64 mask, u64 *regs) 737e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 738e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unsigned rid, i = 0; 739e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 740e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for_each_set_bit(rid, (unsigned long *) &mask, sizeof(mask) * 8) { 741e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 val = regs[i++]; 742e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 743e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf(".... %-5s 0x%" PRIx64 "\n", 744e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_reg_name(rid), val); 745e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 746e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 747e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 748e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void regs_user__printf(struct perf_sample *sample, u64 mask) 749e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 750e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct regs_dump *user_regs = &sample->user_regs; 751e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 752e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (user_regs->regs) { 753e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("... user regs: mask 0x%" PRIx64 "\n", mask); 754e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng regs_dump__printf(mask, user_regs->regs); 755e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 756e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 757e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 758e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void stack_user__printf(struct stack_dump *dump) 759e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 760e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("... ustack: size %" PRIu64 ", offset 0x%x\n", 761e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng dump->size, dump->offset); 762e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 763e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 764e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_session__print_tstamp(struct perf_session *session, 765e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event, 766e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample) 767e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 768e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 sample_type = __perf_evlist__combined_sample_type(session->evlist); 769e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 770e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (event->header.type != PERF_RECORD_SAMPLE && 771e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng !perf_evlist__sample_id_all(session->evlist)) { 772e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fputs("-1 -1 ", stdout); 773e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 774e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 775e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 776e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if ((sample_type & PERF_SAMPLE_CPU)) 777e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("%u ", sample->cpu); 778e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 779e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_type & PERF_SAMPLE_TIME) 780e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("%" PRIu64 " ", sample->time); 781e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 782e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 783e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void sample_read__printf(struct perf_sample *sample, u64 read_format) 784e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 785e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("... sample_read:\n"); 786e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 787e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 788e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("...... time enabled %016" PRIx64 "\n", 789e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample->read.time_enabled); 790e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 791e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) 792e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("...... time running %016" PRIx64 "\n", 793e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample->read.time_running); 794e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 795e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (read_format & PERF_FORMAT_GROUP) { 796e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 i; 797e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 798e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf(".... group nr %" PRIu64 "\n", sample->read.group.nr); 799e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 800e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < sample->read.group.nr; i++) { 801e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct sample_read_value *value; 802e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 803e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng value = &sample->read.group.values[i]; 804e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("..... id %016" PRIx64 805e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ", value %016" PRIx64 "\n", 806e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng value->id, value->value); 807e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 808e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } else 809e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("..... id %016" PRIx64 ", value %016" PRIx64 "\n", 810e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample->read.one.id, sample->read.one.value); 811e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 812e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 813e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void dump_event(struct perf_session *session, union perf_event *event, 814e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 file_offset, struct perf_sample *sample) 815e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 816e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!dump_trace) 817e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 818e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 819e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("\n%#" PRIx64 " [%#x]: event: %d\n", 820e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file_offset, event->header.size, event->header.type); 821e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 822e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng trace_event(event); 823e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 824e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample) 825e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__print_tstamp(session, event, sample); 826e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 827e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("%#" PRIx64 " [%#x]: PERF_RECORD_%s", file_offset, 828e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->header.size, perf_event__name(event->header.type)); 829e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 830e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 831e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void dump_sample(struct perf_evsel *evsel, union perf_event *event, 832e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample) 833e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 834e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 sample_type; 835e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 836e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!dump_trace) 837e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 838e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 839e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRIx64 "\n", 840e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->header.misc, sample->pid, sample->tid, sample->ip, 841e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample->period, sample->addr); 842e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 843e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample_type = evsel->attr.sample_type; 844e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 845e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_type & PERF_SAMPLE_CALLCHAIN) 846e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng callchain__printf(sample); 847e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 848e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_type & PERF_SAMPLE_BRANCH_STACK) 849e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng branch_stack__printf(sample); 850e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 851e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_type & PERF_SAMPLE_REGS_USER) 852e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng regs_user__printf(sample, evsel->attr.sample_regs_user); 853e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 854e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_type & PERF_SAMPLE_STACK_USER) 855e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng stack_user__printf(&sample->user_stack); 856e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 857e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_type & PERF_SAMPLE_WEIGHT) 858e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("... weight: %" PRIu64 "\n", sample->weight); 859e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 860e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_type & PERF_SAMPLE_DATA_SRC) 861e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf(" . data_src: 0x%"PRIx64"\n", sample->data_src); 862e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 863e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sample_type & PERF_SAMPLE_READ) 864e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample_read__printf(sample, evsel->attr.read_format); 865e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 866e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 867e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct machine * 868e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__find_machine_for_cpumode(struct perf_session *session, 869e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event, 870e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample) 871e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 872e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 873e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 874e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (perf_guest && 875e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || 876e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng (cpumode == PERF_RECORD_MISC_GUEST_USER))) { 877e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u32 pid; 878e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 879e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (event->header.type == PERF_RECORD_MMAP 880e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng || event->header.type == PERF_RECORD_MMAP2) 881e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pid = event->mmap.pid; 882e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng else 883e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pid = sample->pid; 884e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 885e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return perf_session__findnew_machine(session, pid); 886e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 887e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 888e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return &session->machines.host; 889e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 890e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 891e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int deliver_sample_value(struct perf_session *session, 892e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool, 893e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event, 894e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample, 895e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct sample_read_value *v, 896e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct machine *machine) 897e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 898e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample_id *sid; 899e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 900e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sid = perf_evlist__id2sid(session->evlist, v->id); 901e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sid) { 902e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample->id = v->id; 903e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample->period = v->value - sid->period; 904e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sid->period = v->value; 905e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 906e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 907e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!sid || sid->evsel == NULL) { 908e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ++session->stats.nr_unknown_id; 909e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 910e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 911e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 912e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->sample(tool, event, sample, sid->evsel, machine); 913e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 914e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 915e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int deliver_sample_group(struct perf_session *session, 916e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool, 917e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event, 918e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample, 919e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct machine *machine) 920e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 921e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret = -EINVAL; 922e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 i; 923e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 924e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < sample->read.group.nr; i++) { 925e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = deliver_sample_value(session, tool, event, sample, 926e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng &sample->read.group.values[i], 927e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng machine); 928e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret) 929e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng break; 930e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 931e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 932e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 933e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 934e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 935e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int 936e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengperf_session__deliver_sample(struct perf_session *session, 937e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool, 938e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event, 939e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample, 940e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evsel *evsel, 941e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct machine *machine) 942e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 943e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* We know evsel != NULL. */ 944e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 sample_type = evsel->attr.sample_type; 945e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 read_format = evsel->attr.read_format; 946e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 947e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* Standard sample delievery. */ 948e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!(sample_type & PERF_SAMPLE_READ)) 949e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->sample(tool, event, sample, evsel, machine); 950e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 951e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* For PERF_SAMPLE_READ we have either single or group mode. */ 952e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (read_format & PERF_FORMAT_GROUP) 953e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return deliver_sample_group(session, tool, event, sample, 954e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng machine); 955e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng else 956e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return deliver_sample_value(session, tool, event, sample, 957e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng &sample->read.one, machine); 958e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 959e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 960e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int perf_session_deliver_event(struct perf_session *session, 961e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event, 962e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample, 963e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool, 964e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 file_offset) 965e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 966e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evsel *evsel; 967e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct machine *machine; 968e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 969e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng dump_event(session, event, file_offset, sample); 970e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 971e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng evsel = perf_evlist__id2evsel(session->evlist, sample->id); 972e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (evsel != NULL && event->header.type != PERF_RECORD_SAMPLE) { 973e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* 974e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * XXX We're leaving PERF_RECORD_SAMPLE unnacounted here 975e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * because the tools right now may apply filters, discarding 976e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * some of the samples. For consistency, in the future we 977e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * should have something like nr_filtered_samples and remove 978e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the sample->period from total_sample_period, etc, KISS for 979e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * now tho. 980e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 981e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Also testing against NULL allows us to handle files without 982e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * attr.sample_id_all and/or without PERF_SAMPLE_ID. In the 983e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * future probably it'll be a good idea to restrict event 984e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * processing via perf_session to files with both set. 985e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 986e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng hists__inc_nr_events(&evsel->hists, event->header.type); 987e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 988e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 989e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng machine = perf_session__find_machine_for_cpumode(session, event, 990e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample); 991e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 992e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng switch (event->header.type) { 993e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_SAMPLE: 994e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng dump_sample(evsel, event, sample); 995e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (evsel == NULL) { 996e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ++session->stats.nr_unknown_id; 997e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 998e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 999e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (machine == NULL) { 1000e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ++session->stats.nr_unprocessable_samples; 1001e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 1002e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1003e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return perf_session__deliver_sample(session, tool, event, 1004e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample, evsel, machine); 1005e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_MMAP: 1006e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->mmap(tool, event, sample, machine); 1007e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_MMAP2: 1008e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->mmap2(tool, event, sample, machine); 1009e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_COMM: 1010e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->comm(tool, event, sample, machine); 1011e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_FORK: 1012e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->fork(tool, event, sample, machine); 1013e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_EXIT: 1014e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->exit(tool, event, sample, machine); 1015e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_LOST: 1016e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->lost == perf_event__process_lost) 1017e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->stats.total_lost += event->lost.lost; 1018e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->lost(tool, event, sample, machine); 1019e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_READ: 1020e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->read(tool, event, sample, evsel, machine); 1021e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_THROTTLE: 1022e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->throttle(tool, event, sample, machine); 1023e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_UNTHROTTLE: 1024e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->unthrottle(tool, event, sample, machine); 1025e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng default: 1026e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ++session->stats.nr_unknown_events; 1027e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 1028e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1029e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1030e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1031e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int perf_session__process_user_event(struct perf_session *session, union perf_event *event, 1032e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool, u64 file_offset) 1033e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1034e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int err; 1035e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1036e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng dump_event(session, event, file_offset, NULL); 1037e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1038e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* These events are processed right away */ 1039e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng switch (event->header.type) { 1040e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_HEADER_ATTR: 1041e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = tool->attr(tool, event, &session->evlist); 1042e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (err == 0) 1043e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__set_id_hdr_size(session); 1044e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return err; 1045e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_HEADER_TRACING_DATA: 1046e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* setup for reading amidst mmap */ 1047e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng lseek(session->fd, file_offset, SEEK_SET); 1048e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->tracing_data(tool, event, session); 1049e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_HEADER_BUILD_ID: 1050e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->build_id(tool, event, session); 1051e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng case PERF_RECORD_FINISHED_ROUND: 1052e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tool->finished_round(tool, event, session); 1053e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng default: 1054e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -EINVAL; 1055e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1056e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1057e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1058e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void event_swap(union perf_event *event, bool sample_id_all) 1059e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1060e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_event__swap_op swap; 1061e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1062e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng swap = perf_event__swap_ops[event->header.type]; 1063e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (swap) 1064e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng swap(event, sample_id_all); 1065e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1066e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1067e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int perf_session__process_event(struct perf_session *session, 1068e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event, 1069e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool, 1070e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 file_offset) 1071e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1072e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample sample; 1073e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret; 1074e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1075e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session->header.needs_swap) 1076e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event_swap(event, perf_evlist__sample_id_all(session->evlist)); 1077e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1078e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (event->header.type >= PERF_RECORD_HEADER_MAX) 1079e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -EINVAL; 1080e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1081e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng events_stats__inc(&session->stats, event->header.type); 1082e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1083e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (event->header.type >= PERF_RECORD_USER_TYPE_START) 1084e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return perf_session__process_user_event(session, event, tool, file_offset); 1085e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1086e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* 1087e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * For all kernel events we get the sample data 1088e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 1089e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = perf_evlist__parse_sample(session->evlist, event, &sample); 1090e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret) 1091e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 1092e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1093e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->ordered_samples) { 1094e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = perf_session_queue_event(session, event, &sample, 1095e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file_offset); 1096e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret != -ETIME) 1097e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 1098e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1099e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return perf_session_deliver_event(session, event, &sample, tool, 1101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file_offset); 1102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid perf_event_header__bswap(struct perf_event_header *self) 1105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->type = bswap_32(self->type); 1107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->misc = bswap_16(self->misc); 1108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->size = bswap_16(self->size); 1109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct thread *perf_session__findnew(struct perf_session *session, pid_t pid) 1112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return machine__findnew_thread(&session->machines.host, 0, pid); 1114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct thread *perf_session__register_idle_thread(struct perf_session *self) 1117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct thread *thread = perf_session__findnew(self, 0); 1119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (thread == NULL || thread__set_comm(thread, "swapper")) { 1121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("problem inserting idle task.\n"); 1122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng thread = NULL; 1123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return thread; 1126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void perf_session__warn_about_errors(const struct perf_session *session, 1129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const struct perf_tool *tool) 1130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tool->lost == perf_event__process_lost && 1132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->stats.nr_events[PERF_RECORD_LOST] != 0) { 1133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ui__warning("Processed %d events and lost %d chunks!\n\n" 1134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "Check IO/CPU overload!\n\n", 1135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->stats.nr_events[0], 1136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->stats.nr_events[PERF_RECORD_LOST]); 1137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session->stats.nr_unknown_events != 0) { 1140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ui__warning("Found %u unknown events!\n\n" 1141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "Is this an older tool processing a perf.data " 1142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "file generated by a more recent tool?\n\n" 1143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "If that is not the case, consider " 1144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "reporting to linux-kernel@vger.kernel.org.\n\n", 1145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->stats.nr_unknown_events); 1146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session->stats.nr_unknown_id != 0) { 1149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ui__warning("%u samples with id not present in the header\n", 1150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->stats.nr_unknown_id); 1151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session->stats.nr_invalid_chains != 0) { 1154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ui__warning("Found invalid callchains!\n\n" 1155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "%u out of %u events were discarded for this reason.\n\n" 1156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "Consider reporting to linux-kernel@vger.kernel.org.\n\n", 1157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->stats.nr_invalid_chains, 1158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->stats.nr_events[PERF_RECORD_SAMPLE]); 1159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session->stats.nr_unprocessable_samples != 0) { 1162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ui__warning("%u unprocessable samples recorded.\n" 1163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "Do you have a KVM guest running and not using 'perf kvm'?\n", 1164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->stats.nr_unprocessable_samples); 1165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvolatile int session_done; 1169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int __perf_session__process_pipe_events(struct perf_session *self, 1171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool) 1172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event; 1174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng uint32_t size, cur_size = 0; 1175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng void *buf = NULL; 1176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int skip = 0; 1177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 head; 1178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int err; 1179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng void *p; 1180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_tool__fill_defaults(tool); 1182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng head = 0; 1184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng cur_size = sizeof(union perf_event); 1185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng buf = malloc(cur_size); 1187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!buf) 1188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -errno; 1189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengmore: 1190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event = buf; 1191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = readn(self->fd, event, sizeof(struct perf_event_header)); 1192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (err <= 0) { 1193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (err == 0) 1194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto done; 1195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("failed to read event header\n"); 1197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 1198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (self->header.needs_swap) 1201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_event_header__bswap(&event->header); 1202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size = event->header.size; 1204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (size < sizeof(struct perf_event_header)) { 1205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("bad event header size\n"); 1206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 1207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (size > cur_size) { 1210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng void *new = realloc(buf, size); 1211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!new) { 1212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("failed to allocate memory to read event\n"); 1213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 1214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng buf = new; 1216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng cur_size = size; 1217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event = buf; 1218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng p = event; 1220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng p += sizeof(struct perf_event_header); 1221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (size - sizeof(struct perf_event_header)) { 1223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = readn(self->fd, p, size - sizeof(struct perf_event_header)); 1224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (err <= 0) { 1225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (err == 0) { 1226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("unexpected end of event stream\n"); 1227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto done; 1228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("failed to read event data\n"); 1231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 1232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if ((skip = perf_session__process_event(self, event, tool, head)) < 0) { 1236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", 1237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng head, event->header.size, event->header.type); 1238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = -EINVAL; 1239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 1240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng head += size; 1243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (skip > 0) 1245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng head += skip; 1246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!session_done()) 1248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto more; 1249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengdone: 1250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = 0; 1251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_err: 1252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(buf); 1253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__warn_about_errors(self, tool); 1254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session_free_sample_buffers(self); 1255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return err; 1256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic union perf_event * 1259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengfetch_mmaped_event(struct perf_session *session, 1260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 head, size_t mmap_size, char *buf) 1261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event; 1263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* 1265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Ensure we have enough space remaining to read 1266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the size of the event in the headers. 1267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 1268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (head + sizeof(event->header) > mmap_size) 1269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 1270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event = (union perf_event *)(buf + head); 1272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session->header.needs_swap) 1274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_event_header__bswap(&event->header); 1275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (head + event->header.size > mmap_size) { 1277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* We're not fetching the event so swap back again */ 1278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session->header.needs_swap) 1279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_event_header__bswap(&event->header); 1280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 1281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return event; 1284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* 1287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * On 64bit we can mmap the data file in one go. No need for tiny mmap 1288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * slices. On 32bit we use 32MB. 1289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 1290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#if BITS_PER_LONG == 64 1291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define MMAP_SIZE ULLONG_MAX 1292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define NUM_MMAPS 1 1293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#else 1294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define MMAP_SIZE (32 * 1024 * 1024ULL) 1295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define NUM_MMAPS 128 1296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif 1297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint __perf_session__process_events(struct perf_session *session, 1299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 data_offset, u64 data_size, 1300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 file_size, struct perf_tool *tool) 1301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 head, page_offset, file_offset, file_pos, progress_next; 1303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int err, mmap_prot, mmap_flags, map_idx = 0; 1304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size_t mmap_size; 1305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *buf, *mmaps[NUM_MMAPS]; 1306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event; 1307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng uint32_t size; 1308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_tool__fill_defaults(tool); 1310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng page_offset = page_size * (data_offset / page_size); 1312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file_offset = page_offset; 1313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng head = data_offset - page_offset; 1314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (data_size && (data_offset + data_size < file_size)) 1316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file_size = data_offset + data_size; 1317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng progress_next = file_size / 16; 1319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mmap_size = MMAP_SIZE; 1321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (mmap_size > file_size) 1322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mmap_size = file_size; 1323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng memset(mmaps, 0, sizeof(mmaps)); 1325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mmap_prot = PROT_READ; 1327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mmap_flags = MAP_SHARED; 1328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session->header.needs_swap) { 1330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mmap_prot |= PROT_WRITE; 1331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mmap_flags = MAP_PRIVATE; 1332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengremap: 1334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng buf = mmap(NULL, mmap_size, mmap_prot, mmap_flags, session->fd, 1335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file_offset); 1336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (buf == MAP_FAILED) { 1337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("failed to mmap file\n"); 1338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = -errno; 1339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 1340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mmaps[map_idx] = buf; 1342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng map_idx = (map_idx + 1) & (ARRAY_SIZE(mmaps) - 1); 1343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file_pos = file_offset + head; 1344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengmore: 1346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event = fetch_mmaped_event(session, head, mmap_size, buf); 1347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!event) { 1348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (mmaps[map_idx]) { 1349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng munmap(mmaps[map_idx], mmap_size); 1350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mmaps[map_idx] = NULL; 1351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng page_offset = page_size * (head / page_size); 1354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file_offset += page_offset; 1355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng head -= page_offset; 1356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto remap; 1357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size = event->header.size; 1360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (size < sizeof(struct perf_event_header) || 1362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__process_event(session, event, tool, file_pos) < 0) { 1363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", 1364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file_offset + head, event->header.size, 1365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->header.type); 1366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = -EINVAL; 1367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 1368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng head += size; 1371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file_pos += size; 1372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (file_pos >= progress_next) { 1374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng progress_next += file_size / 16; 1375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ui_progress__update(file_pos, file_size, 1376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "Processing events..."); 1377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = 0; 1380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session_done()) 1381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 1382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (file_pos < file_size) 1384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto more; 1385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* do the final flush for ordered samples */ 1387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng session->ordered_samples.next_flush = ULLONG_MAX; 1388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = flush_sample_queue(session, tool); 1389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_err: 1390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ui_progress__finish(); 1391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session__warn_about_errors(session, tool); 1392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_session_free_sample_buffers(session); 1393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return err; 1394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint perf_session__process_events(struct perf_session *self, 1397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tool *tool) 1398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int err; 1400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (perf_session__register_idle_thread(self) == NULL) 1402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -ENOMEM; 1403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!self->fd_pipe) 1405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = __perf_session__process_events(self, 1406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->header.data_offset, 1407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->header.data_size, 1408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng self->size, tool); 1409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng else 1410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = __perf_session__process_pipe_events(self, tool); 1411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return err; 1413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool perf_session__has_traces(struct perf_session *session, const char *msg) 1416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evsel *evsel; 1418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_for_each_entry(evsel, &session->evlist->entries, node) { 1420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (evsel->attr.type == PERF_TYPE_TRACEPOINT) 1421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return true; 1422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg); 1425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return false; 1426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint maps__set_kallsyms_ref_reloc_sym(struct map **maps, 1429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const char *symbol_name, u64 addr) 1430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *bracket; 1432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng enum map_type i; 1433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct ref_reloc_sym *ref; 1434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ref = zalloc(sizeof(struct ref_reloc_sym)); 1436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ref == NULL) 1437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -ENOMEM; 1438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ref->name = strdup(symbol_name); 1440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ref->name == NULL) { 1441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(ref); 1442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -ENOMEM; 1443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bracket = strchr(ref->name, ']'); 1446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (bracket) 1447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *bracket = '\0'; 1448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ref->addr = addr; 1450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < MAP__NR_TYPES; ++i) { 1452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct kmap *kmap = map__kmap(maps[i]); 1453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng kmap->ref_reloc_sym = ref; 1454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 1457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengsize_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp) 1460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return machines__fprintf_dsos(&self->machines, fp); 1462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengsize_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp, 1465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool (skip)(struct dso *dso, int parm), int parm) 1466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return machines__fprintf_dsos_buildid(&self->machines, fp, skip, parm); 1468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengsize_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) 1471e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1472e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evsel *pos; 1473e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size_t ret = fprintf(fp, "Aggregated stats:\n"); 1474e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1475e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret += events_stats__fprintf(&session->stats, fp); 1476e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1477e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_for_each_entry(pos, &session->evlist->entries, node) { 1478e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); 1479e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret += events_stats__fprintf(&pos->hists.stats, fp); 1480e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1481e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1482e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 1483e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1484e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1485e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengsize_t perf_session__fprintf(struct perf_session *session, FILE *fp) 1486e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1487e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* 1488e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * FIXME: Here we have to actually print all the machines in this 1489e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * session, not just the host... 1490e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 1491e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return machine__fprintf(&session->machines.host, fp); 1492e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1493e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1494e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, 1495e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unsigned int type) 1496e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1497e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evsel *pos; 1498e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1499e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng list_for_each_entry(pos, &session->evlist->entries, node) { 1500e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (pos->attr.type == type) 1501e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pos; 1502e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1503e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 1504e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1505e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1506e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, 1507e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_sample *sample, struct machine *machine, 1508e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unsigned int print_opts, unsigned int stack_depth) 1509e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1510e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct addr_location al; 1511e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct callchain_cursor_node *node; 1512e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int print_ip = print_opts & PRINT_IP_OPT_IP; 1513e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int print_sym = print_opts & PRINT_IP_OPT_SYM; 1514e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int print_dso = print_opts & PRINT_IP_OPT_DSO; 1515e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET; 1516e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int print_oneline = print_opts & PRINT_IP_OPT_ONELINE; 1517e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char s = print_oneline ? ' ' : '\t'; 1518e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1519e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 1520e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng error("problem processing %d event, skipping it.\n", 1521e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event->header.type); 1522e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 1523e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1524e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1525e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (symbol_conf.use_callchain && sample->callchain) { 1526e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1527e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (machine__resolve_callchain(machine, evsel, al.thread, 1528e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sample, NULL, NULL) != 0) { 1529e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (verbose) 1530e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng error("Failed to resolve callchain. Skipping\n"); 1531e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 1532e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1533e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng callchain_cursor_commit(&callchain_cursor); 1534e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1535e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (stack_depth) { 1536e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng node = callchain_cursor_current(&callchain_cursor); 1537e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!node) 1538e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng break; 1539e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1540e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (print_ip) 1541e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("%c%16" PRIx64, s, node->ip); 1542e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1543e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (print_sym) { 1544e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf(" "); 1545e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (print_symoffset) { 1546e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng al.addr = node->ip; 1547e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng al.map = node->map; 1548e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng symbol__fprintf_symname_offs(node->sym, &al, stdout); 1549e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } else 1550e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng symbol__fprintf_symname(node->sym, stdout); 1551e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1552e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1553e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (print_dso) { 1554e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf(" ("); 1555e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng map__fprintf_dsoname(node->map, stdout); 1556e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf(")"); 1557e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1558e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1559e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!print_oneline) 1560e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("\n"); 1561e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1562e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng callchain_cursor_advance(&callchain_cursor); 1563e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1564e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng stack_depth--; 1565e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1566e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1567e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } else { 1568e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (print_ip) 1569e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("%16" PRIx64, sample->ip); 1570e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1571e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (print_sym) { 1572e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf(" "); 1573e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (print_symoffset) 1574e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng symbol__fprintf_symname_offs(al.sym, &al, 1575e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng stdout); 1576e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng else 1577e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng symbol__fprintf_symname(al.sym, stdout); 1578e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1579e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1580e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (print_dso) { 1581e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf(" ("); 1582e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng map__fprintf_dsoname(al.map, stdout); 1583e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf(")"); 1584e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1585e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1586e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1587e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1588e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint perf_session__cpu_bitmap(struct perf_session *session, 1589e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const char *cpu_list, unsigned long *cpu_bitmap) 1590e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1591e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int i; 1592e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct cpu_map *map; 1593e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1594e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < PERF_TYPE_MAX; ++i) { 1595e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evsel *evsel; 1596e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1597e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng evsel = perf_session__find_first_evtype(session, i); 1598e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!evsel) 1599e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng continue; 1600e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1601e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!(evsel->attr.sample_type & PERF_SAMPLE_CPU)) { 1602e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("File does not contain CPU events. " 1603e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "Remove -c option to proceed.\n"); 1604e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 1605e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1606e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1607e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1608e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng map = cpu_map__new(cpu_list); 1609e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (map == NULL) { 1610e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("Invalid cpu_list\n"); 1611e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 1612e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1613e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1614e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < map->nr; i++) { 1615e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int cpu = map->map[i]; 1616e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1617e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (cpu >= MAX_NR_CPUS) { 1618e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_err("Requested CPU %d too large. " 1619e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "Consider raising MAX_NR_CPUS\n", cpu); 1620e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 1621e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1622e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1623e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng set_bit(cpu, cpu_bitmap); 1624e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1625e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1626e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 1627e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1628e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1629e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid perf_session__fprintf_info(struct perf_session *session, FILE *fp, 1630e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool full) 1631e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1632e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct stat st; 1633e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret; 1634e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1635e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (session == NULL || fp == NULL) 1636e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 1637e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1638e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = fstat(session->fd, &st); 1639e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret == -1) 1640e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 1641e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1642e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fprintf(fp, "# ========\n"); 1643e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fprintf(fp, "# captured on: %s", ctime(&st.st_ctime)); 1644e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_header__fprintf_info(session, fp, full); 1645e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fprintf(fp, "# ========\n#\n"); 1646e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1647e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1648e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1649e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint __perf_session__set_tracepoints_handlers(struct perf_session *session, 1650e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const struct perf_evsel_str_handler *assocs, 1651e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size_t nr_assocs) 1652e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 1653e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evsel *evsel; 1654e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size_t i; 1655e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int err; 1656e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1657e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < nr_assocs; i++) { 1658e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* 1659e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Adding a handler for an event not in the session, 1660e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * just ignore it. 1661e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 1662e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng evsel = perf_evlist__find_tracepoint_by_name(session->evlist, assocs[i].name); 1663e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (evsel == NULL) 1664e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng continue; 1665e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1666e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = -EEXIST; 1667e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (evsel->handler.func != NULL) 1668e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out; 1669e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng evsel->handler.func = assocs[i].handler; 1670e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 1671e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 1672e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = 0; 1673e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout: 1674e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return err; 1675e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 1676