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