aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c325
1 files changed, 64 insertions, 261 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ce6f51162386..bd85280bb6e8 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -16,7 +16,6 @@
16#include "cpumap.h" 16#include "cpumap.h"
17#include "event-parse.h" 17#include "event-parse.h"
18#include "perf_regs.h" 18#include "perf_regs.h"
19#include "unwind.h"
20#include "vdso.h" 19#include "vdso.h"
21 20
22static int perf_session__open(struct perf_session *self, bool force) 21static int perf_session__open(struct perf_session *self, bool force)
@@ -87,13 +86,12 @@ void perf_session__set_id_hdr_size(struct perf_session *session)
87{ 86{
88 u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist); 87 u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist);
89 88
90 session->host_machine.id_hdr_size = id_hdr_size;
91 machines__set_id_hdr_size(&session->machines, id_hdr_size); 89 machines__set_id_hdr_size(&session->machines, id_hdr_size);
92} 90}
93 91
94int perf_session__create_kernel_maps(struct perf_session *self) 92int perf_session__create_kernel_maps(struct perf_session *self)
95{ 93{
96 int ret = machine__create_kernel_maps(&self->host_machine); 94 int ret = machine__create_kernel_maps(&self->machines.host);
97 95
98 if (ret >= 0) 96 if (ret >= 0)
99 ret = machines__create_guest_kernel_maps(&self->machines); 97 ret = machines__create_guest_kernel_maps(&self->machines);
@@ -102,8 +100,7 @@ int perf_session__create_kernel_maps(struct perf_session *self)
102 100
103static void perf_session__destroy_kernel_maps(struct perf_session *self) 101static void perf_session__destroy_kernel_maps(struct perf_session *self)
104{ 102{
105 machine__destroy_kernel_maps(&self->host_machine); 103 machines__destroy_kernel_maps(&self->machines);
106 machines__destroy_guest_kernel_maps(&self->machines);
107} 104}
108 105
109struct perf_session *perf_session__new(const char *filename, int mode, 106struct perf_session *perf_session__new(const char *filename, int mode,
@@ -128,22 +125,11 @@ struct perf_session *perf_session__new(const char *filename, int mode,
128 goto out; 125 goto out;
129 126
130 memcpy(self->filename, filename, len); 127 memcpy(self->filename, filename, len);
131 /*
132 * On 64bit we can mmap the data file in one go. No need for tiny mmap
133 * slices. On 32bit we use 32MB.
134 */
135#if BITS_PER_LONG == 64
136 self->mmap_window = ULLONG_MAX;
137#else
138 self->mmap_window = 32 * 1024 * 1024ULL;
139#endif
140 self->machines = RB_ROOT;
141 self->repipe = repipe; 128 self->repipe = repipe;
142 INIT_LIST_HEAD(&self->ordered_samples.samples); 129 INIT_LIST_HEAD(&self->ordered_samples.samples);
143 INIT_LIST_HEAD(&self->ordered_samples.sample_cache); 130 INIT_LIST_HEAD(&self->ordered_samples.sample_cache);
144 INIT_LIST_HEAD(&self->ordered_samples.to_free); 131 INIT_LIST_HEAD(&self->ordered_samples.to_free);
145 machine__init(&self->host_machine, "", HOST_KERNEL_ID); 132 machines__init(&self->machines);
146 hists__init(&self->hists);
147 133
148 if (mode == O_RDONLY) { 134 if (mode == O_RDONLY) {
149 if (perf_session__open(self, force) < 0) 135 if (perf_session__open(self, force) < 0)
@@ -171,37 +157,30 @@ out_delete:
171 return NULL; 157 return NULL;
172} 158}
173 159
174static void machine__delete_dead_threads(struct machine *machine)
175{
176 struct thread *n, *t;
177
178 list_for_each_entry_safe(t, n, &machine->dead_threads, node) {
179 list_del(&t->node);
180 thread__delete(t);
181 }
182}
183
184static void perf_session__delete_dead_threads(struct perf_session *session) 160static void perf_session__delete_dead_threads(struct perf_session *session)
185{ 161{
186 machine__delete_dead_threads(&session->host_machine); 162 machine__delete_dead_threads(&session->machines.host);
187} 163}
188 164
189static void machine__delete_threads(struct machine *self) 165static void perf_session__delete_threads(struct perf_session *session)
190{ 166{
191 struct rb_node *nd = rb_first(&self->threads); 167 machine__delete_threads(&session->machines.host);
192
193 while (nd) {
194 struct thread *t = rb_entry(nd, struct thread, rb_node);
195
196 rb_erase(&t->rb_node, &self->threads);
197 nd = rb_next(nd);
198 thread__delete(t);
199 }
200} 168}
201 169
202static void perf_session__delete_threads(struct perf_session *session) 170static void perf_session_env__delete(struct perf_session_env *env)
203{ 171{
204 machine__delete_threads(&session->host_machine); 172 free(env->hostname);
173 free(env->os_release);
174 free(env->version);
175 free(env->arch);
176 free(env->cpu_desc);
177 free(env->cpuid);
178
179 free(env->cmdline);
180 free(env->sibling_cores);
181 free(env->sibling_threads);
182 free(env->numa_nodes);
183 free(env->pmu_mappings);
205} 184}
206 185
207void perf_session__delete(struct perf_session *self) 186void perf_session__delete(struct perf_session *self)
@@ -209,198 +188,13 @@ void perf_session__delete(struct perf_session *self)
209 perf_session__destroy_kernel_maps(self); 188 perf_session__destroy_kernel_maps(self);
210 perf_session__delete_dead_threads(self); 189 perf_session__delete_dead_threads(self);
211 perf_session__delete_threads(self); 190 perf_session__delete_threads(self);
212 machine__exit(&self->host_machine); 191 perf_session_env__delete(&self->header.env);
192 machines__exit(&self->machines);
213 close(self->fd); 193 close(self->fd);
214 free(self); 194 free(self);
215 vdso__exit(); 195 vdso__exit();
216} 196}
217 197
218void machine__remove_thread(struct machine *self, struct thread *th)
219{
220 self->last_match = NULL;
221 rb_erase(&th->rb_node, &self->threads);
222 /*
223 * We may have references to this thread, for instance in some hist_entry
224 * instances, so just move them to a separate list.
225 */
226 list_add_tail(&th->node, &self->dead_threads);
227}
228
229static bool symbol__match_parent_regex(struct symbol *sym)
230{
231 if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
232 return 1;
233
234 return 0;
235}
236
237static const u8 cpumodes[] = {
238 PERF_RECORD_MISC_USER,
239 PERF_RECORD_MISC_KERNEL,
240 PERF_RECORD_MISC_GUEST_USER,
241 PERF_RECORD_MISC_GUEST_KERNEL
242};
243#define NCPUMODES (sizeof(cpumodes)/sizeof(u8))
244
245static void ip__resolve_ams(struct machine *self, struct thread *thread,
246 struct addr_map_symbol *ams,
247 u64 ip)
248{
249 struct addr_location al;
250 size_t i;
251 u8 m;
252
253 memset(&al, 0, sizeof(al));
254
255 for (i = 0; i < NCPUMODES; i++) {
256 m = cpumodes[i];
257 /*
258 * We cannot use the header.misc hint to determine whether a
259 * branch stack address is user, kernel, guest, hypervisor.
260 * Branches may straddle the kernel/user/hypervisor boundaries.
261 * Thus, we have to try consecutively until we find a match
262 * or else, the symbol is unknown
263 */
264 thread__find_addr_location(thread, self, m, MAP__FUNCTION,
265 ip, &al, NULL);
266 if (al.sym)
267 goto found;
268 }
269found:
270 ams->addr = ip;
271 ams->al_addr = al.addr;
272 ams->sym = al.sym;
273 ams->map = al.map;
274}
275
276struct branch_info *machine__resolve_bstack(struct machine *self,
277 struct thread *thr,
278 struct branch_stack *bs)
279{
280 struct branch_info *bi;
281 unsigned int i;
282
283 bi = calloc(bs->nr, sizeof(struct branch_info));
284 if (!bi)
285 return NULL;
286
287 for (i = 0; i < bs->nr; i++) {
288 ip__resolve_ams(self, thr, &bi[i].to, bs->entries[i].to);
289 ip__resolve_ams(self, thr, &bi[i].from, bs->entries[i].from);
290 bi[i].flags = bs->entries[i].flags;
291 }
292 return bi;
293}
294
295static int machine__resolve_callchain_sample(struct machine *machine,
296 struct thread *thread,
297 struct ip_callchain *chain,
298 struct symbol **parent)
299
300{
301 u8 cpumode = PERF_RECORD_MISC_USER;
302 unsigned int i;
303 int err;
304
305 callchain_cursor_reset(&callchain_cursor);
306
307 if (chain->nr > PERF_MAX_STACK_DEPTH) {
308 pr_warning("corrupted callchain. skipping...\n");
309 return 0;
310 }
311
312 for (i = 0; i < chain->nr; i++) {
313 u64 ip;
314 struct addr_location al;
315
316 if (callchain_param.order == ORDER_CALLEE)
317 ip = chain->ips[i];
318 else
319 ip = chain->ips[chain->nr - i - 1];
320
321 if (ip >= PERF_CONTEXT_MAX) {
322 switch (ip) {
323 case PERF_CONTEXT_HV:
324 cpumode = PERF_RECORD_MISC_HYPERVISOR;
325 break;
326 case PERF_CONTEXT_KERNEL:
327 cpumode = PERF_RECORD_MISC_KERNEL;
328 break;
329 case PERF_CONTEXT_USER:
330 cpumode = PERF_RECORD_MISC_USER;
331 break;
332 default:
333 pr_debug("invalid callchain context: "
334 "%"PRId64"\n", (s64) ip);
335 /*
336 * It seems the callchain is corrupted.
337 * Discard all.
338 */
339 callchain_cursor_reset(&callchain_cursor);
340 return 0;
341 }
342 continue;
343 }
344
345 al.filtered = false;
346 thread__find_addr_location(thread, machine, cpumode,
347 MAP__FUNCTION, ip, &al, NULL);
348 if (al.sym != NULL) {
349 if (sort__has_parent && !*parent &&
350 symbol__match_parent_regex(al.sym))
351 *parent = al.sym;
352 if (!symbol_conf.use_callchain)
353 break;
354 }
355
356 err = callchain_cursor_append(&callchain_cursor,
357 ip, al.map, al.sym);
358 if (err)
359 return err;
360 }
361
362 return 0;
363}
364
365static int unwind_entry(struct unwind_entry *entry, void *arg)
366{
367 struct callchain_cursor *cursor = arg;
368 return callchain_cursor_append(cursor, entry->ip,
369 entry->map, entry->sym);
370}
371
372int machine__resolve_callchain(struct machine *machine,
373 struct perf_evsel *evsel,
374 struct thread *thread,
375 struct perf_sample *sample,
376 struct symbol **parent)
377
378{
379 int ret;
380
381 callchain_cursor_reset(&callchain_cursor);
382
383 ret = machine__resolve_callchain_sample(machine, thread,
384 sample->callchain, parent);
385 if (ret)
386 return ret;
387
388 /* Can we do dwarf post unwind? */
389 if (!((evsel->attr.sample_type & PERF_SAMPLE_REGS_USER) &&
390 (evsel->attr.sample_type & PERF_SAMPLE_STACK_USER)))
391 return 0;
392
393 /* Bail out if nothing was captured. */
394 if ((!sample->user_regs.regs) ||
395 (!sample->user_stack.size))
396 return 0;
397
398 return unwind__get_entries(unwind_entry, &callchain_cursor, machine,
399 thread, evsel->attr.sample_regs_user,
400 sample);
401
402}
403
404static int process_event_synth_tracing_data_stub(union perf_event *event 198static int process_event_synth_tracing_data_stub(union perf_event *event
405 __maybe_unused, 199 __maybe_unused,
406 struct perf_session *session 200 struct perf_session *session
@@ -1027,7 +821,7 @@ static struct machine *
1027 return perf_session__findnew_machine(session, pid); 821 return perf_session__findnew_machine(session, pid);
1028 } 822 }
1029 823
1030 return perf_session__find_host_machine(session); 824 return &session->machines.host;
1031} 825}
1032 826
1033static int perf_session_deliver_event(struct perf_session *session, 827static int perf_session_deliver_event(struct perf_session *session,
@@ -1065,11 +859,11 @@ static int perf_session_deliver_event(struct perf_session *session,
1065 case PERF_RECORD_SAMPLE: 859 case PERF_RECORD_SAMPLE:
1066 dump_sample(evsel, event, sample); 860 dump_sample(evsel, event, sample);
1067 if (evsel == NULL) { 861 if (evsel == NULL) {
1068 ++session->hists.stats.nr_unknown_id; 862 ++session->stats.nr_unknown_id;
1069 return 0; 863 return 0;
1070 } 864 }
1071 if (machine == NULL) { 865 if (machine == NULL) {
1072 ++session->hists.stats.nr_unprocessable_samples; 866 ++session->stats.nr_unprocessable_samples;
1073 return 0; 867 return 0;
1074 } 868 }
1075 return tool->sample(tool, event, sample, evsel, machine); 869 return tool->sample(tool, event, sample, evsel, machine);
@@ -1083,7 +877,7 @@ static int perf_session_deliver_event(struct perf_session *session,
1083 return tool->exit(tool, event, sample, machine); 877 return tool->exit(tool, event, sample, machine);
1084 case PERF_RECORD_LOST: 878 case PERF_RECORD_LOST:
1085 if (tool->lost == perf_event__process_lost) 879 if (tool->lost == perf_event__process_lost)
1086 session->hists.stats.total_lost += event->lost.lost; 880 session->stats.total_lost += event->lost.lost;
1087 return tool->lost(tool, event, sample, machine); 881 return tool->lost(tool, event, sample, machine);
1088 case PERF_RECORD_READ: 882 case PERF_RECORD_READ:
1089 return tool->read(tool, event, sample, evsel, machine); 883 return tool->read(tool, event, sample, evsel, machine);
@@ -1092,7 +886,7 @@ static int perf_session_deliver_event(struct perf_session *session,
1092 case PERF_RECORD_UNTHROTTLE: 886 case PERF_RECORD_UNTHROTTLE:
1093 return tool->unthrottle(tool, event, sample, machine); 887 return tool->unthrottle(tool, event, sample, machine);
1094 default: 888 default:
1095 ++session->hists.stats.nr_unknown_events; 889 ++session->stats.nr_unknown_events;
1096 return -1; 890 return -1;
1097 } 891 }
1098} 892}
@@ -1106,8 +900,8 @@ static int perf_session__preprocess_sample(struct perf_session *session,
1106 900
1107 if (!ip_callchain__valid(sample->callchain, event)) { 901 if (!ip_callchain__valid(sample->callchain, event)) {
1108 pr_debug("call-chain problem with event, skipping it.\n"); 902 pr_debug("call-chain problem with event, skipping it.\n");
1109 ++session->hists.stats.nr_invalid_chains; 903 ++session->stats.nr_invalid_chains;
1110 session->hists.stats.total_invalid_chains += sample->period; 904 session->stats.total_invalid_chains += sample->period;
1111 return -EINVAL; 905 return -EINVAL;
1112 } 906 }
1113 return 0; 907 return 0;
@@ -1165,7 +959,7 @@ static int perf_session__process_event(struct perf_session *session,
1165 if (event->header.type >= PERF_RECORD_HEADER_MAX) 959 if (event->header.type >= PERF_RECORD_HEADER_MAX)
1166 return -EINVAL; 960 return -EINVAL;
1167 961
1168 hists__inc_nr_events(&session->hists, event->header.type); 962 events_stats__inc(&session->stats, event->header.type);
1169 963
1170 if (event->header.type >= PERF_RECORD_USER_TYPE_START) 964 if (event->header.type >= PERF_RECORD_USER_TYPE_START)
1171 return perf_session__process_user_event(session, event, tool, file_offset); 965 return perf_session__process_user_event(session, event, tool, file_offset);
@@ -1201,7 +995,7 @@ void perf_event_header__bswap(struct perf_event_header *self)
1201 995
1202struct thread *perf_session__findnew(struct perf_session *session, pid_t pid) 996struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
1203{ 997{
1204 return machine__findnew_thread(&session->host_machine, pid); 998 return machine__findnew_thread(&session->machines.host, pid);
1205} 999}
1206 1000
1207static struct thread *perf_session__register_idle_thread(struct perf_session *self) 1001static struct thread *perf_session__register_idle_thread(struct perf_session *self)
@@ -1220,39 +1014,39 @@ static void perf_session__warn_about_errors(const struct perf_session *session,
1220 const struct perf_tool *tool) 1014 const struct perf_tool *tool)
1221{ 1015{
1222 if (tool->lost == perf_event__process_lost && 1016 if (tool->lost == perf_event__process_lost &&
1223 session->hists.stats.nr_events[PERF_RECORD_LOST] != 0) { 1017 session->stats.nr_events[PERF_RECORD_LOST] != 0) {
1224 ui__warning("Processed %d events and lost %d chunks!\n\n" 1018 ui__warning("Processed %d events and lost %d chunks!\n\n"
1225 "Check IO/CPU overload!\n\n", 1019 "Check IO/CPU overload!\n\n",
1226 session->hists.stats.nr_events[0], 1020 session->stats.nr_events[0],
1227 session->hists.stats.nr_events[PERF_RECORD_LOST]); 1021 session->stats.nr_events[PERF_RECORD_LOST]);
1228 } 1022 }
1229 1023
1230 if (session->hists.stats.nr_unknown_events != 0) { 1024 if (session->stats.nr_unknown_events != 0) {
1231 ui__warning("Found %u unknown events!\n\n" 1025 ui__warning("Found %u unknown events!\n\n"
1232 "Is this an older tool processing a perf.data " 1026 "Is this an older tool processing a perf.data "
1233 "file generated by a more recent tool?\n\n" 1027 "file generated by a more recent tool?\n\n"
1234 "If that is not the case, consider " 1028 "If that is not the case, consider "
1235 "reporting to linux-kernel@vger.kernel.org.\n\n", 1029 "reporting to linux-kernel@vger.kernel.org.\n\n",
1236 session->hists.stats.nr_unknown_events); 1030 session->stats.nr_unknown_events);
1237 } 1031 }
1238 1032
1239 if (session->hists.stats.nr_unknown_id != 0) { 1033 if (session->stats.nr_unknown_id != 0) {
1240 ui__warning("%u samples with id not present in the header\n", 1034 ui__warning("%u samples with id not present in the header\n",
1241 session->hists.stats.nr_unknown_id); 1035 session->stats.nr_unknown_id);
1242 } 1036 }
1243 1037
1244 if (session->hists.stats.nr_invalid_chains != 0) { 1038 if (session->stats.nr_invalid_chains != 0) {
1245 ui__warning("Found invalid callchains!\n\n" 1039 ui__warning("Found invalid callchains!\n\n"
1246 "%u out of %u events were discarded for this reason.\n\n" 1040 "%u out of %u events were discarded for this reason.\n\n"
1247 "Consider reporting to linux-kernel@vger.kernel.org.\n\n", 1041 "Consider reporting to linux-kernel@vger.kernel.org.\n\n",
1248 session->hists.stats.nr_invalid_chains, 1042 session->stats.nr_invalid_chains,
1249 session->hists.stats.nr_events[PERF_RECORD_SAMPLE]); 1043 session->stats.nr_events[PERF_RECORD_SAMPLE]);
1250 } 1044 }
1251 1045
1252 if (session->hists.stats.nr_unprocessable_samples != 0) { 1046 if (session->stats.nr_unprocessable_samples != 0) {
1253 ui__warning("%u unprocessable samples recorded.\n" 1047 ui__warning("%u unprocessable samples recorded.\n"
1254 "Do you have a KVM guest running and not using 'perf kvm'?\n", 1048 "Do you have a KVM guest running and not using 'perf kvm'?\n",
1255 session->hists.stats.nr_unprocessable_samples); 1049 session->stats.nr_unprocessable_samples);
1256 } 1050 }
1257} 1051}
1258 1052
@@ -1369,6 +1163,18 @@ fetch_mmaped_event(struct perf_session *session,
1369 return event; 1163 return event;
1370} 1164}
1371 1165
1166/*
1167 * On 64bit we can mmap the data file in one go. No need for tiny mmap
1168 * slices. On 32bit we use 32MB.
1169 */
1170#if BITS_PER_LONG == 64
1171#define MMAP_SIZE ULLONG_MAX
1172#define NUM_MMAPS 1
1173#else
1174#define MMAP_SIZE (32 * 1024 * 1024ULL)
1175#define NUM_MMAPS 128
1176#endif
1177
1372int __perf_session__process_events(struct perf_session *session, 1178int __perf_session__process_events(struct perf_session *session,
1373 u64 data_offset, u64 data_size, 1179 u64 data_offset, u64 data_size,
1374 u64 file_size, struct perf_tool *tool) 1180 u64 file_size, struct perf_tool *tool)
@@ -1376,7 +1182,7 @@ int __perf_session__process_events(struct perf_session *session,
1376 u64 head, page_offset, file_offset, file_pos, progress_next; 1182 u64 head, page_offset, file_offset, file_pos, progress_next;
1377 int err, mmap_prot, mmap_flags, map_idx = 0; 1183 int err, mmap_prot, mmap_flags, map_idx = 0;
1378 size_t mmap_size; 1184 size_t mmap_size;
1379 char *buf, *mmaps[8]; 1185 char *buf, *mmaps[NUM_MMAPS];
1380 union perf_event *event; 1186 union perf_event *event;
1381 uint32_t size; 1187 uint32_t size;
1382 1188
@@ -1391,7 +1197,7 @@ int __perf_session__process_events(struct perf_session *session,
1391 1197
1392 progress_next = file_size / 16; 1198 progress_next = file_size / 16;
1393 1199
1394 mmap_size = session->mmap_window; 1200 mmap_size = MMAP_SIZE;
1395 if (mmap_size > file_size) 1201 if (mmap_size > file_size)
1396 mmap_size = file_size; 1202 mmap_size = file_size;
1397 1203
@@ -1526,16 +1332,13 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
1526 1332
1527size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp) 1333size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
1528{ 1334{
1529 return __dsos__fprintf(&self->host_machine.kernel_dsos, fp) + 1335 return machines__fprintf_dsos(&self->machines, fp);
1530 __dsos__fprintf(&self->host_machine.user_dsos, fp) +
1531 machines__fprintf_dsos(&self->machines, fp);
1532} 1336}
1533 1337
1534size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp, 1338size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
1535 bool with_hits) 1339 bool (skip)(struct dso *dso, int parm), int parm)
1536{ 1340{
1537 size_t ret = machine__fprintf_dsos_buildid(&self->host_machine, fp, with_hits); 1341 return machines__fprintf_dsos_buildid(&self->machines, fp, skip, parm);
1538 return ret + machines__fprintf_dsos_buildid(&self->machines, fp, with_hits);
1539} 1342}
1540 1343
1541size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) 1344size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
@@ -1543,11 +1346,11 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
1543 struct perf_evsel *pos; 1346 struct perf_evsel *pos;
1544 size_t ret = fprintf(fp, "Aggregated stats:\n"); 1347 size_t ret = fprintf(fp, "Aggregated stats:\n");
1545 1348
1546 ret += hists__fprintf_nr_events(&session->hists, fp); 1349 ret += events_stats__fprintf(&session->stats, fp);
1547 1350
1548 list_for_each_entry(pos, &session->evlist->entries, node) { 1351 list_for_each_entry(pos, &session->evlist->entries, node) {
1549 ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); 1352 ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos));
1550 ret += hists__fprintf_nr_events(&pos->hists, fp); 1353 ret += events_stats__fprintf(&pos->hists.stats, fp);
1551 } 1354 }
1552 1355
1553 return ret; 1356 return ret;
@@ -1559,7 +1362,7 @@ size_t perf_session__fprintf(struct perf_session *session, FILE *fp)
1559 * FIXME: Here we have to actually print all the machines in this 1362 * FIXME: Here we have to actually print all the machines in this
1560 * session, not just the host... 1363 * session, not just the host...
1561 */ 1364 */
1562 return machine__fprintf(&session->host_machine, fp); 1365 return machine__fprintf(&session->machines.host, fp);
1563} 1366}
1564 1367
1565void perf_session__remove_thread(struct perf_session *session, 1368void perf_session__remove_thread(struct perf_session *session,
@@ -1568,10 +1371,10 @@ void perf_session__remove_thread(struct perf_session *session,
1568 /* 1371 /*
1569 * FIXME: This one makes no sense, we need to remove the thread from 1372 * FIXME: This one makes no sense, we need to remove the thread from
1570 * the machine it belongs to, perf_session can have many machines, so 1373 * the machine it belongs to, perf_session can have many machines, so
1571 * doing it always on ->host_machine is wrong. Fix when auditing all 1374 * doing it always on ->machines.host is wrong. Fix when auditing all
1572 * the 'perf kvm' code. 1375 * the 'perf kvm' code.
1573 */ 1376 */
1574 machine__remove_thread(&session->host_machine, th); 1377 machine__remove_thread(&session->machines.host, th);
1575} 1378}
1576 1379
1577struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, 1380struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,