blob: b1161d725ce998480ac47492087208a05ff200a0 [file] [log] [blame]
Adrian Hunter90e457f2015-07-17 19:33:41 +03001/*
2 * intel_pt.c: Intel Processor Trace support
3 * Copyright (c) 2013-2015, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 */
15
16#include <stdio.h>
17#include <stdbool.h>
18#include <errno.h>
19#include <linux/kernel.h>
20#include <linux/types.h>
21
22#include "../perf.h"
23#include "session.h"
24#include "machine.h"
Adrian Hunterf14445e2015-09-25 16:15:45 +030025#include "sort.h"
Adrian Hunter90e457f2015-07-17 19:33:41 +030026#include "tool.h"
27#include "event.h"
28#include "evlist.h"
29#include "evsel.h"
30#include "map.h"
31#include "color.h"
32#include "util.h"
33#include "thread.h"
34#include "thread-stack.h"
35#include "symbol.h"
36#include "callchain.h"
37#include "dso.h"
38#include "debug.h"
39#include "auxtrace.h"
40#include "tsc.h"
41#include "intel-pt.h"
Taeung Song41840d22016-06-23 17:55:17 +090042#include "config.h"
Adrian Hunter90e457f2015-07-17 19:33:41 +030043
44#include "intel-pt-decoder/intel-pt-log.h"
45#include "intel-pt-decoder/intel-pt-decoder.h"
46#include "intel-pt-decoder/intel-pt-insn-decoder.h"
47#include "intel-pt-decoder/intel-pt-pkt-decoder.h"
48
49#define MAX_TIMESTAMP (~0ULL)
50
51struct intel_pt {
52 struct auxtrace auxtrace;
53 struct auxtrace_queues queues;
54 struct auxtrace_heap heap;
55 u32 auxtrace_type;
56 struct perf_session *session;
57 struct machine *machine;
58 struct perf_evsel *switch_evsel;
59 struct thread *unknown_thread;
60 bool timeless_decoding;
61 bool sampling_mode;
62 bool snapshot_mode;
63 bool per_cpu_mmaps;
64 bool have_tsc;
65 bool data_queued;
66 bool est_tsc;
67 bool sync_switch;
Adrian Hunterba11ba62015-09-25 16:15:56 +030068 bool mispred_all;
Adrian Hunter90e457f2015-07-17 19:33:41 +030069 int have_sched_switch;
70 u32 pmu_type;
71 u64 kernel_start;
72 u64 switch_ip;
73 u64 ptss_ip;
74
75 struct perf_tsc_conversion tc;
76 bool cap_user_time_zero;
77
78 struct itrace_synth_opts synth_opts;
79
80 bool sample_instructions;
81 u64 instructions_sample_type;
82 u64 instructions_sample_period;
83 u64 instructions_id;
84
85 bool sample_branches;
86 u32 branches_filter;
87 u64 branches_sample_type;
88 u64 branches_id;
89
90 bool sample_transactions;
91 u64 transactions_sample_type;
92 u64 transactions_id;
93
94 bool synth_needs_swap;
95
96 u64 tsc_bit;
Adrian Hunter11fa7cb2015-07-17 19:33:54 +030097 u64 mtc_bit;
98 u64 mtc_freq_bits;
99 u32 tsc_ctc_ratio_n;
100 u32 tsc_ctc_ratio_d;
101 u64 cyc_bit;
Adrian Hunter90e457f2015-07-17 19:33:41 +0300102 u64 noretcomp_bit;
103 unsigned max_non_turbo_ratio;
Andi Kleend1706b32016-03-28 10:45:38 -0700104
105 unsigned long num_events;
Adrian Hunter2b9e32c2016-09-23 17:38:46 +0300106
107 char *filter;
Adrian Hunter2acee102016-09-23 17:38:48 +0300108 struct addr_filters filts;
Adrian Hunter90e457f2015-07-17 19:33:41 +0300109};
110
111enum switch_state {
112 INTEL_PT_SS_NOT_TRACING,
113 INTEL_PT_SS_UNKNOWN,
114 INTEL_PT_SS_TRACING,
115 INTEL_PT_SS_EXPECTING_SWITCH_EVENT,
116 INTEL_PT_SS_EXPECTING_SWITCH_IP,
117};
118
119struct intel_pt_queue {
120 struct intel_pt *pt;
121 unsigned int queue_nr;
122 struct auxtrace_buffer *buffer;
123 void *decoder;
124 const struct intel_pt_state *state;
125 struct ip_callchain *chain;
Adrian Hunterf14445e2015-09-25 16:15:45 +0300126 struct branch_stack *last_branch;
127 struct branch_stack *last_branch_rb;
128 size_t last_branch_pos;
Adrian Hunter90e457f2015-07-17 19:33:41 +0300129 union perf_event *event_buf;
130 bool on_heap;
131 bool stop;
132 bool step_through_buffers;
133 bool use_buffer_pid_tid;
Adrian Hunter6a330362018-03-07 16:02:22 +0200134 bool sync_switch;
Adrian Hunter90e457f2015-07-17 19:33:41 +0300135 pid_t pid, tid;
136 int cpu;
137 int switch_state;
138 pid_t next_tid;
139 struct thread *thread;
140 bool exclude_kernel;
141 bool have_sample;
142 u64 time;
143 u64 timestamp;
144 u32 flags;
145 u16 insn_len;
Adrian Hunter2a21d032015-07-17 19:33:48 +0300146 u64 last_insn_cnt;
Adrian Hunter90e457f2015-07-17 19:33:41 +0300147};
148
149static void intel_pt_dump(struct intel_pt *pt __maybe_unused,
150 unsigned char *buf, size_t len)
151{
152 struct intel_pt_pkt packet;
153 size_t pos = 0;
154 int ret, pkt_len, i;
155 char desc[INTEL_PT_PKT_DESC_MAX];
156 const char *color = PERF_COLOR_BLUE;
157
158 color_fprintf(stdout, color,
159 ". ... Intel Processor Trace data: size %zu bytes\n",
160 len);
161
162 while (len) {
163 ret = intel_pt_get_packet(buf, len, &packet);
164 if (ret > 0)
165 pkt_len = ret;
166 else
167 pkt_len = 1;
168 printf(".");
169 color_fprintf(stdout, color, " %08x: ", pos);
170 for (i = 0; i < pkt_len; i++)
171 color_fprintf(stdout, color, " %02x", buf[i]);
172 for (; i < 16; i++)
173 color_fprintf(stdout, color, " ");
174 if (ret > 0) {
175 ret = intel_pt_pkt_desc(&packet, desc,
176 INTEL_PT_PKT_DESC_MAX);
177 if (ret > 0)
178 color_fprintf(stdout, color, " %s\n", desc);
179 } else {
180 color_fprintf(stdout, color, " Bad packet!\n");
181 }
182 pos += pkt_len;
183 buf += pkt_len;
184 len -= pkt_len;
185 }
186}
187
188static void intel_pt_dump_event(struct intel_pt *pt, unsigned char *buf,
189 size_t len)
190{
191 printf(".\n");
192 intel_pt_dump(pt, buf, len);
193}
194
195static int intel_pt_do_fix_overlap(struct intel_pt *pt, struct auxtrace_buffer *a,
196 struct auxtrace_buffer *b)
197{
Adrian Hunteraad2ad62018-03-07 16:02:21 +0200198 bool consecutive = false;
Adrian Hunter90e457f2015-07-17 19:33:41 +0300199 void *start;
200
201 start = intel_pt_find_overlap(a->data, a->size, b->data, b->size,
Adrian Hunteraad2ad62018-03-07 16:02:21 +0200202 pt->have_tsc, &consecutive);
Adrian Hunter90e457f2015-07-17 19:33:41 +0300203 if (!start)
204 return -EINVAL;
205 b->use_size = b->data + b->size - start;
206 b->use_data = start;
Adrian Hunteraad2ad62018-03-07 16:02:21 +0200207 if (b->use_size && consecutive)
208 b->consecutive = true;
Adrian Hunter90e457f2015-07-17 19:33:41 +0300209 return 0;
210}
211
212static void intel_pt_use_buffer_pid_tid(struct intel_pt_queue *ptq,
213 struct auxtrace_queue *queue,
214 struct auxtrace_buffer *buffer)
215{
216 if (queue->cpu == -1 && buffer->cpu != -1)
217 ptq->cpu = buffer->cpu;
218
219 ptq->pid = buffer->pid;
220 ptq->tid = buffer->tid;
221
222 intel_pt_log("queue %u cpu %d pid %d tid %d\n",
223 ptq->queue_nr, ptq->cpu, ptq->pid, ptq->tid);
224
225 thread__zput(ptq->thread);
226
227 if (ptq->tid != -1) {
228 if (ptq->pid != -1)
229 ptq->thread = machine__findnew_thread(ptq->pt->machine,
230 ptq->pid,
231 ptq->tid);
232 else
233 ptq->thread = machine__find_thread(ptq->pt->machine, -1,
234 ptq->tid);
235 }
236}
237
238/* This function assumes data is processed sequentially only */
239static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data)
240{
241 struct intel_pt_queue *ptq = data;
242 struct auxtrace_buffer *buffer = ptq->buffer, *old_buffer = buffer;
243 struct auxtrace_queue *queue;
244
245 if (ptq->stop) {
246 b->len = 0;
247 return 0;
248 }
249
250 queue = &ptq->pt->queues.queue_array[ptq->queue_nr];
Adrian Hunter810c3982016-09-23 17:38:41 +0300251next:
Adrian Hunter90e457f2015-07-17 19:33:41 +0300252 buffer = auxtrace_buffer__next(queue, buffer);
253 if (!buffer) {
254 if (old_buffer)
255 auxtrace_buffer__drop_data(old_buffer);
256 b->len = 0;
257 return 0;
258 }
259
260 ptq->buffer = buffer;
261
262 if (!buffer->data) {
263 int fd = perf_data_file__fd(ptq->pt->session->file);
264
265 buffer->data = auxtrace_buffer__get_data(buffer, fd);
266 if (!buffer->data)
267 return -ENOMEM;
268 }
269
270 if (ptq->pt->snapshot_mode && !buffer->consecutive && old_buffer &&
271 intel_pt_do_fix_overlap(ptq->pt, old_buffer, buffer))
272 return -ENOMEM;
273
Adrian Hunter90e457f2015-07-17 19:33:41 +0300274 if (buffer->use_data) {
275 b->len = buffer->use_size;
276 b->buf = buffer->use_data;
277 } else {
278 b->len = buffer->size;
279 b->buf = buffer->data;
280 }
281 b->ref_timestamp = buffer->reference;
282
Adrian Hunter810c3982016-09-23 17:38:41 +0300283 /*
284 * If in snapshot mode and the buffer has no usable data, get next
285 * buffer and again check overlap against old_buffer.
286 */
287 if (ptq->pt->snapshot_mode && !b->len)
288 goto next;
289
290 if (old_buffer)
291 auxtrace_buffer__drop_data(old_buffer);
292
Adrian Hunter90e457f2015-07-17 19:33:41 +0300293 if (!old_buffer || ptq->pt->sampling_mode || (ptq->pt->snapshot_mode &&
294 !buffer->consecutive)) {
295 b->consecutive = false;
296 b->trace_nr = buffer->buffer_nr + 1;
297 } else {
298 b->consecutive = true;
299 }
300
301 if (ptq->use_buffer_pid_tid && (ptq->pid != buffer->pid ||
302 ptq->tid != buffer->tid))
303 intel_pt_use_buffer_pid_tid(ptq, queue, buffer);
304
305 if (ptq->step_through_buffers)
306 ptq->stop = true;
307
308 if (!b->len)
309 return intel_pt_get_trace(b, data);
310
311 return 0;
312}
313
314struct intel_pt_cache_entry {
315 struct auxtrace_cache_entry entry;
316 u64 insn_cnt;
317 u64 byte_cnt;
318 enum intel_pt_insn_op op;
319 enum intel_pt_insn_branch branch;
320 int length;
321 int32_t rel;
322};
323
324static int intel_pt_config_div(const char *var, const char *value, void *data)
325{
326 int *d = data;
327 long val;
328
329 if (!strcmp(var, "intel-pt.cache-divisor")) {
330 val = strtol(value, NULL, 0);
331 if (val > 0 && val <= INT_MAX)
332 *d = val;
333 }
334
335 return 0;
336}
337
338static int intel_pt_cache_divisor(void)
339{
340 static int d;
341
342 if (d)
343 return d;
344
345 perf_config(intel_pt_config_div, &d);
346
347 if (!d)
348 d = 64;
349
350 return d;
351}
352
353static unsigned int intel_pt_cache_size(struct dso *dso,
354 struct machine *machine)
355{
356 off_t size;
357
358 size = dso__data_size(dso, machine);
359 size /= intel_pt_cache_divisor();
360 if (size < 1000)
361 return 10;
362 if (size > (1 << 21))
363 return 21;
364 return 32 - __builtin_clz(size);
365}
366
367static struct auxtrace_cache *intel_pt_cache(struct dso *dso,
368 struct machine *machine)
369{
370 struct auxtrace_cache *c;
371 unsigned int bits;
372
373 if (dso->auxtrace_cache)
374 return dso->auxtrace_cache;
375
376 bits = intel_pt_cache_size(dso, machine);
377
378 /* Ignoring cache creation failure */
379 c = auxtrace_cache__new(bits, sizeof(struct intel_pt_cache_entry), 200);
380
381 dso->auxtrace_cache = c;
382
383 return c;
384}
385
386static int intel_pt_cache_add(struct dso *dso, struct machine *machine,
387 u64 offset, u64 insn_cnt, u64 byte_cnt,
388 struct intel_pt_insn *intel_pt_insn)
389{
390 struct auxtrace_cache *c = intel_pt_cache(dso, machine);
391 struct intel_pt_cache_entry *e;
392 int err;
393
394 if (!c)
395 return -ENOMEM;
396
397 e = auxtrace_cache__alloc_entry(c);
398 if (!e)
399 return -ENOMEM;
400
401 e->insn_cnt = insn_cnt;
402 e->byte_cnt = byte_cnt;
403 e->op = intel_pt_insn->op;
404 e->branch = intel_pt_insn->branch;
405 e->length = intel_pt_insn->length;
406 e->rel = intel_pt_insn->rel;
407
408 err = auxtrace_cache__add(c, offset, &e->entry);
409 if (err)
410 auxtrace_cache__free_entry(c, e);
411
412 return err;
413}
414
415static struct intel_pt_cache_entry *
416intel_pt_cache_lookup(struct dso *dso, struct machine *machine, u64 offset)
417{
418 struct auxtrace_cache *c = intel_pt_cache(dso, machine);
419
420 if (!c)
421 return NULL;
422
423 return auxtrace_cache__lookup(dso->auxtrace_cache, offset);
424}
425
426static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
427 uint64_t *insn_cnt_ptr, uint64_t *ip,
428 uint64_t to_ip, uint64_t max_insn_cnt,
429 void *data)
430{
431 struct intel_pt_queue *ptq = data;
432 struct machine *machine = ptq->pt->machine;
433 struct thread *thread;
434 struct addr_location al;
435 unsigned char buf[1024];
436 size_t bufsz;
437 ssize_t len;
438 int x86_64;
439 u8 cpumode;
440 u64 offset, start_offset, start_ip;
441 u64 insn_cnt = 0;
442 bool one_map = true;
443
444 if (to_ip && *ip == to_ip)
445 goto out_no_cache;
446
447 bufsz = intel_pt_insn_max_size();
448
449 if (*ip >= ptq->pt->kernel_start)
450 cpumode = PERF_RECORD_MISC_KERNEL;
451 else
452 cpumode = PERF_RECORD_MISC_USER;
453
454 thread = ptq->thread;
455 if (!thread) {
456 if (cpumode != PERF_RECORD_MISC_KERNEL)
457 return -EINVAL;
458 thread = ptq->pt->unknown_thread;
459 }
460
461 while (1) {
462 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, *ip, &al);
463 if (!al.map || !al.map->dso)
464 return -EINVAL;
465
466 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
467 dso__data_status_seen(al.map->dso,
468 DSO_DATA_STATUS_SEEN_ITRACE))
469 return -ENOENT;
470
471 offset = al.map->map_ip(al.map, *ip);
472
473 if (!to_ip && one_map) {
474 struct intel_pt_cache_entry *e;
475
476 e = intel_pt_cache_lookup(al.map->dso, machine, offset);
477 if (e &&
478 (!max_insn_cnt || e->insn_cnt <= max_insn_cnt)) {
479 *insn_cnt_ptr = e->insn_cnt;
480 *ip += e->byte_cnt;
481 intel_pt_insn->op = e->op;
482 intel_pt_insn->branch = e->branch;
483 intel_pt_insn->length = e->length;
484 intel_pt_insn->rel = e->rel;
485 intel_pt_log_insn_no_data(intel_pt_insn, *ip);
486 return 0;
487 }
488 }
489
490 start_offset = offset;
491 start_ip = *ip;
492
493 /* Load maps to ensure dso->is_64_bit has been updated */
Arnaldo Carvalho de Melobe39db92016-09-01 19:25:52 -0300494 map__load(al.map);
Adrian Hunter90e457f2015-07-17 19:33:41 +0300495
496 x86_64 = al.map->dso->is_64_bit;
497
498 while (1) {
499 len = dso__data_read_offset(al.map->dso, machine,
500 offset, buf, bufsz);
501 if (len <= 0)
502 return -EINVAL;
503
504 if (intel_pt_get_insn(buf, len, x86_64, intel_pt_insn))
505 return -EINVAL;
506
507 intel_pt_log_insn(intel_pt_insn, *ip);
508
509 insn_cnt += 1;
510
511 if (intel_pt_insn->branch != INTEL_PT_BR_NO_BRANCH)
512 goto out;
513
514 if (max_insn_cnt && insn_cnt >= max_insn_cnt)
515 goto out_no_cache;
516
517 *ip += intel_pt_insn->length;
518
519 if (to_ip && *ip == to_ip)
520 goto out_no_cache;
521
522 if (*ip >= al.map->end)
523 break;
524
525 offset += intel_pt_insn->length;
526 }
527 one_map = false;
528 }
529out:
530 *insn_cnt_ptr = insn_cnt;
531
532 if (!one_map)
533 goto out_no_cache;
534
535 /*
536 * Didn't lookup in the 'to_ip' case, so do it now to prevent duplicate
537 * entries.
538 */
539 if (to_ip) {
540 struct intel_pt_cache_entry *e;
541
542 e = intel_pt_cache_lookup(al.map->dso, machine, start_offset);
543 if (e)
544 return 0;
545 }
546
547 /* Ignore cache errors */
548 intel_pt_cache_add(al.map->dso, machine, start_offset, insn_cnt,
549 *ip - start_ip, intel_pt_insn);
550
551 return 0;
552
553out_no_cache:
554 *insn_cnt_ptr = insn_cnt;
555 return 0;
556}
557
Adrian Hunter2acee102016-09-23 17:38:48 +0300558static bool intel_pt_match_pgd_ip(struct intel_pt *pt, uint64_t ip,
559 uint64_t offset, const char *filename)
560{
561 struct addr_filter *filt;
562 bool have_filter = false;
563 bool hit_tracestop = false;
564 bool hit_filter = false;
565
566 list_for_each_entry(filt, &pt->filts.head, list) {
567 if (filt->start)
568 have_filter = true;
569
570 if ((filename && !filt->filename) ||
571 (!filename && filt->filename) ||
572 (filename && strcmp(filename, filt->filename)))
573 continue;
574
575 if (!(offset >= filt->addr && offset < filt->addr + filt->size))
576 continue;
577
578 intel_pt_log("TIP.PGD ip %#"PRIx64" offset %#"PRIx64" in %s hit filter: %s offset %#"PRIx64" size %#"PRIx64"\n",
579 ip, offset, filename ? filename : "[kernel]",
580 filt->start ? "filter" : "stop",
581 filt->addr, filt->size);
582
583 if (filt->start)
584 hit_filter = true;
585 else
586 hit_tracestop = true;
587 }
588
589 if (!hit_tracestop && !hit_filter)
590 intel_pt_log("TIP.PGD ip %#"PRIx64" offset %#"PRIx64" in %s is not in a filter region\n",
591 ip, offset, filename ? filename : "[kernel]");
592
593 return hit_tracestop || (have_filter && !hit_filter);
594}
595
596static int __intel_pt_pgd_ip(uint64_t ip, void *data)
597{
598 struct intel_pt_queue *ptq = data;
599 struct thread *thread;
600 struct addr_location al;
601 u8 cpumode;
602 u64 offset;
603
604 if (ip >= ptq->pt->kernel_start)
605 return intel_pt_match_pgd_ip(ptq->pt, ip, ip, NULL);
606
607 cpumode = PERF_RECORD_MISC_USER;
608
609 thread = ptq->thread;
610 if (!thread)
611 return -EINVAL;
612
613 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, ip, &al);
614 if (!al.map || !al.map->dso)
615 return -EINVAL;
616
617 offset = al.map->map_ip(al.map, ip);
618
619 return intel_pt_match_pgd_ip(ptq->pt, ip, offset,
620 al.map->dso->long_name);
621}
622
623static bool intel_pt_pgd_ip(uint64_t ip, void *data)
624{
625 return __intel_pt_pgd_ip(ip, data) > 0;
626}
627
Adrian Hunter90e457f2015-07-17 19:33:41 +0300628static bool intel_pt_get_config(struct intel_pt *pt,
629 struct perf_event_attr *attr, u64 *config)
630{
631 if (attr->type == pt->pmu_type) {
632 if (config)
633 *config = attr->config;
634 return true;
635 }
636
637 return false;
638}
639
640static bool intel_pt_exclude_kernel(struct intel_pt *pt)
641{
642 struct perf_evsel *evsel;
643
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -0300644 evlist__for_each_entry(pt->session->evlist, evsel) {
Adrian Hunter90e457f2015-07-17 19:33:41 +0300645 if (intel_pt_get_config(pt, &evsel->attr, NULL) &&
646 !evsel->attr.exclude_kernel)
647 return false;
648 }
649 return true;
650}
651
652static bool intel_pt_return_compression(struct intel_pt *pt)
653{
654 struct perf_evsel *evsel;
655 u64 config;
656
657 if (!pt->noretcomp_bit)
658 return true;
659
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -0300660 evlist__for_each_entry(pt->session->evlist, evsel) {
Adrian Hunter90e457f2015-07-17 19:33:41 +0300661 if (intel_pt_get_config(pt, &evsel->attr, &config) &&
662 (config & pt->noretcomp_bit))
663 return false;
664 }
665 return true;
666}
667
Adrian Hunter11fa7cb2015-07-17 19:33:54 +0300668static unsigned int intel_pt_mtc_period(struct intel_pt *pt)
669{
670 struct perf_evsel *evsel;
671 unsigned int shift;
672 u64 config;
673
674 if (!pt->mtc_freq_bits)
675 return 0;
676
677 for (shift = 0, config = pt->mtc_freq_bits; !(config & 1); shift++)
678 config >>= 1;
679
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -0300680 evlist__for_each_entry(pt->session->evlist, evsel) {
Adrian Hunter11fa7cb2015-07-17 19:33:54 +0300681 if (intel_pt_get_config(pt, &evsel->attr, &config))
682 return (config & pt->mtc_freq_bits) >> shift;
683 }
684 return 0;
685}
686
Adrian Hunter90e457f2015-07-17 19:33:41 +0300687static bool intel_pt_timeless_decoding(struct intel_pt *pt)
688{
689 struct perf_evsel *evsel;
690 bool timeless_decoding = true;
691 u64 config;
692
693 if (!pt->tsc_bit || !pt->cap_user_time_zero)
694 return true;
695
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -0300696 evlist__for_each_entry(pt->session->evlist, evsel) {
Adrian Hunter90e457f2015-07-17 19:33:41 +0300697 if (!(evsel->attr.sample_type & PERF_SAMPLE_TIME))
698 return true;
699 if (intel_pt_get_config(pt, &evsel->attr, &config)) {
700 if (config & pt->tsc_bit)
701 timeless_decoding = false;
702 else
703 return true;
704 }
705 }
706 return timeless_decoding;
707}
708
709static bool intel_pt_tracing_kernel(struct intel_pt *pt)
710{
711 struct perf_evsel *evsel;
712
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -0300713 evlist__for_each_entry(pt->session->evlist, evsel) {
Adrian Hunter90e457f2015-07-17 19:33:41 +0300714 if (intel_pt_get_config(pt, &evsel->attr, NULL) &&
715 !evsel->attr.exclude_kernel)
716 return true;
717 }
718 return false;
719}
720
721static bool intel_pt_have_tsc(struct intel_pt *pt)
722{
723 struct perf_evsel *evsel;
724 bool have_tsc = false;
725 u64 config;
726
727 if (!pt->tsc_bit)
728 return false;
729
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -0300730 evlist__for_each_entry(pt->session->evlist, evsel) {
Adrian Hunter90e457f2015-07-17 19:33:41 +0300731 if (intel_pt_get_config(pt, &evsel->attr, &config)) {
732 if (config & pt->tsc_bit)
733 have_tsc = true;
734 else
735 return false;
736 }
737 }
738 return have_tsc;
739}
740
741static u64 intel_pt_ns_to_ticks(const struct intel_pt *pt, u64 ns)
742{
743 u64 quot, rem;
744
745 quot = ns / pt->tc.time_mult;
746 rem = ns % pt->tc.time_mult;
747 return (quot << pt->tc.time_shift) + (rem << pt->tc.time_shift) /
748 pt->tc.time_mult;
749}
750
751static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt,
752 unsigned int queue_nr)
753{
754 struct intel_pt_params params = { .get_trace = 0, };
755 struct intel_pt_queue *ptq;
756
757 ptq = zalloc(sizeof(struct intel_pt_queue));
758 if (!ptq)
759 return NULL;
760
761 if (pt->synth_opts.callchain) {
762 size_t sz = sizeof(struct ip_callchain);
763
764 sz += pt->synth_opts.callchain_sz * sizeof(u64);
765 ptq->chain = zalloc(sz);
766 if (!ptq->chain)
767 goto out_free;
768 }
769
Adrian Hunterf14445e2015-09-25 16:15:45 +0300770 if (pt->synth_opts.last_branch) {
771 size_t sz = sizeof(struct branch_stack);
772
773 sz += pt->synth_opts.last_branch_sz *
774 sizeof(struct branch_entry);
775 ptq->last_branch = zalloc(sz);
776 if (!ptq->last_branch)
777 goto out_free;
778 ptq->last_branch_rb = zalloc(sz);
779 if (!ptq->last_branch_rb)
780 goto out_free;
781 }
782
Adrian Hunter90e457f2015-07-17 19:33:41 +0300783 ptq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
784 if (!ptq->event_buf)
785 goto out_free;
786
787 ptq->pt = pt;
788 ptq->queue_nr = queue_nr;
789 ptq->exclude_kernel = intel_pt_exclude_kernel(pt);
790 ptq->pid = -1;
791 ptq->tid = -1;
792 ptq->cpu = -1;
793 ptq->next_tid = -1;
794
795 params.get_trace = intel_pt_get_trace;
796 params.walk_insn = intel_pt_walk_next_insn;
797 params.data = ptq;
798 params.return_compression = intel_pt_return_compression(pt);
799 params.max_non_turbo_ratio = pt->max_non_turbo_ratio;
Adrian Hunter11fa7cb2015-07-17 19:33:54 +0300800 params.mtc_period = intel_pt_mtc_period(pt);
801 params.tsc_ctc_ratio_n = pt->tsc_ctc_ratio_n;
802 params.tsc_ctc_ratio_d = pt->tsc_ctc_ratio_d;
Adrian Hunter90e457f2015-07-17 19:33:41 +0300803
Adrian Hunter2acee102016-09-23 17:38:48 +0300804 if (pt->filts.cnt > 0)
805 params.pgd_ip = intel_pt_pgd_ip;
806
Adrian Hunter90e457f2015-07-17 19:33:41 +0300807 if (pt->synth_opts.instructions) {
808 if (pt->synth_opts.period) {
809 switch (pt->synth_opts.period_type) {
810 case PERF_ITRACE_PERIOD_INSTRUCTIONS:
811 params.period_type =
812 INTEL_PT_PERIOD_INSTRUCTIONS;
813 params.period = pt->synth_opts.period;
814 break;
815 case PERF_ITRACE_PERIOD_TICKS:
816 params.period_type = INTEL_PT_PERIOD_TICKS;
817 params.period = pt->synth_opts.period;
818 break;
819 case PERF_ITRACE_PERIOD_NANOSECS:
820 params.period_type = INTEL_PT_PERIOD_TICKS;
821 params.period = intel_pt_ns_to_ticks(pt,
822 pt->synth_opts.period);
823 break;
824 default:
825 break;
826 }
827 }
828
829 if (!params.period) {
830 params.period_type = INTEL_PT_PERIOD_INSTRUCTIONS;
Adrian Huntere1791342015-09-25 16:15:32 +0300831 params.period = 1;
Adrian Hunter90e457f2015-07-17 19:33:41 +0300832 }
833 }
834
835 ptq->decoder = intel_pt_decoder_new(&params);
836 if (!ptq->decoder)
837 goto out_free;
838
839 return ptq;
840
841out_free:
842 zfree(&ptq->event_buf);
Adrian Hunterf14445e2015-09-25 16:15:45 +0300843 zfree(&ptq->last_branch);
844 zfree(&ptq->last_branch_rb);
Adrian Hunter90e457f2015-07-17 19:33:41 +0300845 zfree(&ptq->chain);
846 free(ptq);
847 return NULL;
848}
849
850static void intel_pt_free_queue(void *priv)
851{
852 struct intel_pt_queue *ptq = priv;
853
854 if (!ptq)
855 return;
856 thread__zput(ptq->thread);
857 intel_pt_decoder_free(ptq->decoder);
858 zfree(&ptq->event_buf);
Adrian Hunterf14445e2015-09-25 16:15:45 +0300859 zfree(&ptq->last_branch);
860 zfree(&ptq->last_branch_rb);
Adrian Hunter90e457f2015-07-17 19:33:41 +0300861 zfree(&ptq->chain);
862 free(ptq);
863}
864
865static void intel_pt_set_pid_tid_cpu(struct intel_pt *pt,
866 struct auxtrace_queue *queue)
867{
868 struct intel_pt_queue *ptq = queue->priv;
869
870 if (queue->tid == -1 || pt->have_sched_switch) {
871 ptq->tid = machine__get_current_tid(pt->machine, ptq->cpu);
872 thread__zput(ptq->thread);
873 }
874
875 if (!ptq->thread && ptq->tid != -1)
876 ptq->thread = machine__find_thread(pt->machine, -1, ptq->tid);
877
878 if (ptq->thread) {
879 ptq->pid = ptq->thread->pid_;
880 if (queue->cpu == -1)
881 ptq->cpu = ptq->thread->cpu;
882 }
883}
884
885static void intel_pt_sample_flags(struct intel_pt_queue *ptq)
886{
887 if (ptq->state->flags & INTEL_PT_ABORT_TX) {
888 ptq->flags = PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT;
889 } else if (ptq->state->flags & INTEL_PT_ASYNC) {
890 if (ptq->state->to_ip)
891 ptq->flags = PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL |
892 PERF_IP_FLAG_ASYNC |
893 PERF_IP_FLAG_INTERRUPT;
894 else
895 ptq->flags = PERF_IP_FLAG_BRANCH |
896 PERF_IP_FLAG_TRACE_END;
897 ptq->insn_len = 0;
898 } else {
899 if (ptq->state->from_ip)
900 ptq->flags = intel_pt_insn_type(ptq->state->insn_op);
901 else
902 ptq->flags = PERF_IP_FLAG_BRANCH |
903 PERF_IP_FLAG_TRACE_BEGIN;
904 if (ptq->state->flags & INTEL_PT_IN_TX)
905 ptq->flags |= PERF_IP_FLAG_IN_TX;
906 ptq->insn_len = ptq->state->insn_len;
907 }
908}
909
910static int intel_pt_setup_queue(struct intel_pt *pt,
911 struct auxtrace_queue *queue,
912 unsigned int queue_nr)
913{
914 struct intel_pt_queue *ptq = queue->priv;
915
916 if (list_empty(&queue->head))
917 return 0;
918
919 if (!ptq) {
920 ptq = intel_pt_alloc_queue(pt, queue_nr);
921 if (!ptq)
922 return -ENOMEM;
923 queue->priv = ptq;
924
925 if (queue->cpu != -1)
926 ptq->cpu = queue->cpu;
927 ptq->tid = queue->tid;
928
929 if (pt->sampling_mode) {
930 if (pt->timeless_decoding)
931 ptq->step_through_buffers = true;
932 if (pt->timeless_decoding || !pt->have_sched_switch)
933 ptq->use_buffer_pid_tid = true;
934 }
Adrian Hunter6a330362018-03-07 16:02:22 +0200935
936 ptq->sync_switch = pt->sync_switch;
Adrian Hunter90e457f2015-07-17 19:33:41 +0300937 }
938
939 if (!ptq->on_heap &&
Adrian Hunter6a330362018-03-07 16:02:22 +0200940 (!ptq->sync_switch ||
Adrian Hunter90e457f2015-07-17 19:33:41 +0300941 ptq->switch_state != INTEL_PT_SS_EXPECTING_SWITCH_EVENT)) {
942 const struct intel_pt_state *state;
943 int ret;
944
945 if (pt->timeless_decoding)
946 return 0;
947
948 intel_pt_log("queue %u getting timestamp\n", queue_nr);
949 intel_pt_log("queue %u decoding cpu %d pid %d tid %d\n",
950 queue_nr, ptq->cpu, ptq->pid, ptq->tid);
951 while (1) {
952 state = intel_pt_decode(ptq->decoder);
953 if (state->err) {
954 if (state->err == INTEL_PT_ERR_NODATA) {
955 intel_pt_log("queue %u has no timestamp\n",
956 queue_nr);
957 return 0;
958 }
959 continue;
960 }
961 if (state->timestamp)
962 break;
963 }
964
965 ptq->timestamp = state->timestamp;
966 intel_pt_log("queue %u timestamp 0x%" PRIx64 "\n",
967 queue_nr, ptq->timestamp);
968 ptq->state = state;
969 ptq->have_sample = true;
970 intel_pt_sample_flags(ptq);
971 ret = auxtrace_heap__add(&pt->heap, queue_nr, ptq->timestamp);
972 if (ret)
973 return ret;
974 ptq->on_heap = true;
975 }
976
977 return 0;
978}
979
980static int intel_pt_setup_queues(struct intel_pt *pt)
981{
982 unsigned int i;
983 int ret;
984
985 for (i = 0; i < pt->queues.nr_queues; i++) {
986 ret = intel_pt_setup_queue(pt, &pt->queues.queue_array[i], i);
987 if (ret)
988 return ret;
989 }
990 return 0;
991}
992
Adrian Hunterf14445e2015-09-25 16:15:45 +0300993static inline void intel_pt_copy_last_branch_rb(struct intel_pt_queue *ptq)
994{
995 struct branch_stack *bs_src = ptq->last_branch_rb;
996 struct branch_stack *bs_dst = ptq->last_branch;
997 size_t nr = 0;
998
999 bs_dst->nr = bs_src->nr;
1000
1001 if (!bs_src->nr)
1002 return;
1003
1004 nr = ptq->pt->synth_opts.last_branch_sz - ptq->last_branch_pos;
1005 memcpy(&bs_dst->entries[0],
1006 &bs_src->entries[ptq->last_branch_pos],
1007 sizeof(struct branch_entry) * nr);
1008
1009 if (bs_src->nr >= ptq->pt->synth_opts.last_branch_sz) {
1010 memcpy(&bs_dst->entries[nr],
1011 &bs_src->entries[0],
1012 sizeof(struct branch_entry) * ptq->last_branch_pos);
1013 }
1014}
1015
1016static inline void intel_pt_reset_last_branch_rb(struct intel_pt_queue *ptq)
1017{
1018 ptq->last_branch_pos = 0;
1019 ptq->last_branch_rb->nr = 0;
1020}
1021
1022static void intel_pt_update_last_branch_rb(struct intel_pt_queue *ptq)
1023{
1024 const struct intel_pt_state *state = ptq->state;
1025 struct branch_stack *bs = ptq->last_branch_rb;
1026 struct branch_entry *be;
1027
1028 if (!ptq->last_branch_pos)
1029 ptq->last_branch_pos = ptq->pt->synth_opts.last_branch_sz;
1030
1031 ptq->last_branch_pos -= 1;
1032
1033 be = &bs->entries[ptq->last_branch_pos];
1034 be->from = state->from_ip;
1035 be->to = state->to_ip;
1036 be->flags.abort = !!(state->flags & INTEL_PT_ABORT_TX);
1037 be->flags.in_tx = !!(state->flags & INTEL_PT_IN_TX);
1038 /* No support for mispredict */
Adrian Hunterba11ba62015-09-25 16:15:56 +03001039 be->flags.mispred = ptq->pt->mispred_all;
Adrian Hunterf14445e2015-09-25 16:15:45 +03001040
1041 if (bs->nr < ptq->pt->synth_opts.last_branch_sz)
1042 bs->nr += 1;
1043}
1044
Adrian Hunter90e457f2015-07-17 19:33:41 +03001045static int intel_pt_inject_event(union perf_event *event,
1046 struct perf_sample *sample, u64 type,
1047 bool swapped)
1048{
1049 event->header.size = perf_event__sample_event_size(sample, type, 0);
1050 return perf_event__synthesize_sample(event, type, 0, sample, swapped);
1051}
1052
1053static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
1054{
1055 int ret;
1056 struct intel_pt *pt = ptq->pt;
1057 union perf_event *event = ptq->event_buf;
1058 struct perf_sample sample = { .ip = 0, };
Adrian Hunterf14445e2015-09-25 16:15:45 +03001059 struct dummy_branch_stack {
1060 u64 nr;
1061 struct branch_entry entries;
1062 } dummy_bs;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001063
Adrian Hunter385e3302015-09-25 16:15:44 +03001064 if (pt->branches_filter && !(pt->branches_filter & ptq->flags))
1065 return 0;
1066
Andi Kleend1706b32016-03-28 10:45:38 -07001067 if (pt->synth_opts.initial_skip &&
1068 pt->num_events++ < pt->synth_opts.initial_skip)
1069 return 0;
1070
Adrian Hunter90e457f2015-07-17 19:33:41 +03001071 event->sample.header.type = PERF_RECORD_SAMPLE;
1072 event->sample.header.misc = PERF_RECORD_MISC_USER;
1073 event->sample.header.size = sizeof(struct perf_event_header);
1074
1075 if (!pt->timeless_decoding)
1076 sample.time = tsc_to_perf_time(ptq->timestamp, &pt->tc);
1077
Arnaldo Carvalho de Melo3ea223a2016-03-29 18:46:04 -03001078 sample.cpumode = PERF_RECORD_MISC_USER;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001079 sample.ip = ptq->state->from_ip;
1080 sample.pid = ptq->pid;
1081 sample.tid = ptq->tid;
1082 sample.addr = ptq->state->to_ip;
1083 sample.id = ptq->pt->branches_id;
1084 sample.stream_id = ptq->pt->branches_id;
1085 sample.period = 1;
1086 sample.cpu = ptq->cpu;
1087 sample.flags = ptq->flags;
1088 sample.insn_len = ptq->insn_len;
1089
Adrian Hunterf14445e2015-09-25 16:15:45 +03001090 /*
1091 * perf report cannot handle events without a branch stack when using
1092 * SORT_MODE__BRANCH so make a dummy one.
1093 */
1094 if (pt->synth_opts.last_branch && sort__mode == SORT_MODE__BRANCH) {
1095 dummy_bs = (struct dummy_branch_stack){
1096 .nr = 1,
1097 .entries = {
1098 .from = sample.ip,
1099 .to = sample.addr,
1100 },
1101 };
1102 sample.branch_stack = (struct branch_stack *)&dummy_bs;
1103 }
1104
Adrian Hunter90e457f2015-07-17 19:33:41 +03001105 if (pt->synth_opts.inject) {
1106 ret = intel_pt_inject_event(event, &sample,
1107 pt->branches_sample_type,
1108 pt->synth_needs_swap);
1109 if (ret)
1110 return ret;
1111 }
1112
1113 ret = perf_session__deliver_synth_event(pt->session, event, &sample);
1114 if (ret)
1115 pr_err("Intel Processor Trace: failed to deliver branch event, error %d\n",
1116 ret);
1117
1118 return ret;
1119}
1120
1121static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq)
1122{
1123 int ret;
1124 struct intel_pt *pt = ptq->pt;
1125 union perf_event *event = ptq->event_buf;
1126 struct perf_sample sample = { .ip = 0, };
1127
Andi Kleend1706b32016-03-28 10:45:38 -07001128 if (pt->synth_opts.initial_skip &&
1129 pt->num_events++ < pt->synth_opts.initial_skip)
1130 return 0;
1131
Adrian Hunter90e457f2015-07-17 19:33:41 +03001132 event->sample.header.type = PERF_RECORD_SAMPLE;
1133 event->sample.header.misc = PERF_RECORD_MISC_USER;
1134 event->sample.header.size = sizeof(struct perf_event_header);
1135
1136 if (!pt->timeless_decoding)
1137 sample.time = tsc_to_perf_time(ptq->timestamp, &pt->tc);
1138
Arnaldo Carvalho de Melo3ea223a2016-03-29 18:46:04 -03001139 sample.cpumode = PERF_RECORD_MISC_USER;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001140 sample.ip = ptq->state->from_ip;
1141 sample.pid = ptq->pid;
1142 sample.tid = ptq->tid;
1143 sample.addr = ptq->state->to_ip;
1144 sample.id = ptq->pt->instructions_id;
1145 sample.stream_id = ptq->pt->instructions_id;
Adrian Hunter2a21d032015-07-17 19:33:48 +03001146 sample.period = ptq->state->tot_insn_cnt - ptq->last_insn_cnt;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001147 sample.cpu = ptq->cpu;
1148 sample.flags = ptq->flags;
1149 sample.insn_len = ptq->insn_len;
1150
Adrian Hunter2a21d032015-07-17 19:33:48 +03001151 ptq->last_insn_cnt = ptq->state->tot_insn_cnt;
1152
Adrian Hunter90e457f2015-07-17 19:33:41 +03001153 if (pt->synth_opts.callchain) {
1154 thread_stack__sample(ptq->thread, ptq->chain,
1155 pt->synth_opts.callchain_sz, sample.ip);
1156 sample.callchain = ptq->chain;
1157 }
1158
Adrian Hunterf14445e2015-09-25 16:15:45 +03001159 if (pt->synth_opts.last_branch) {
1160 intel_pt_copy_last_branch_rb(ptq);
1161 sample.branch_stack = ptq->last_branch;
1162 }
1163
Adrian Hunter90e457f2015-07-17 19:33:41 +03001164 if (pt->synth_opts.inject) {
1165 ret = intel_pt_inject_event(event, &sample,
1166 pt->instructions_sample_type,
1167 pt->synth_needs_swap);
1168 if (ret)
1169 return ret;
1170 }
1171
1172 ret = perf_session__deliver_synth_event(pt->session, event, &sample);
1173 if (ret)
1174 pr_err("Intel Processor Trace: failed to deliver instruction event, error %d\n",
1175 ret);
1176
Adrian Hunterf14445e2015-09-25 16:15:45 +03001177 if (pt->synth_opts.last_branch)
1178 intel_pt_reset_last_branch_rb(ptq);
1179
Adrian Hunter90e457f2015-07-17 19:33:41 +03001180 return ret;
1181}
1182
1183static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq)
1184{
1185 int ret;
1186 struct intel_pt *pt = ptq->pt;
1187 union perf_event *event = ptq->event_buf;
1188 struct perf_sample sample = { .ip = 0, };
1189
Andi Kleend1706b32016-03-28 10:45:38 -07001190 if (pt->synth_opts.initial_skip &&
1191 pt->num_events++ < pt->synth_opts.initial_skip)
1192 return 0;
1193
Adrian Hunter90e457f2015-07-17 19:33:41 +03001194 event->sample.header.type = PERF_RECORD_SAMPLE;
1195 event->sample.header.misc = PERF_RECORD_MISC_USER;
1196 event->sample.header.size = sizeof(struct perf_event_header);
1197
1198 if (!pt->timeless_decoding)
1199 sample.time = tsc_to_perf_time(ptq->timestamp, &pt->tc);
1200
Arnaldo Carvalho de Melo3ea223a2016-03-29 18:46:04 -03001201 sample.cpumode = PERF_RECORD_MISC_USER;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001202 sample.ip = ptq->state->from_ip;
1203 sample.pid = ptq->pid;
1204 sample.tid = ptq->tid;
1205 sample.addr = ptq->state->to_ip;
1206 sample.id = ptq->pt->transactions_id;
1207 sample.stream_id = ptq->pt->transactions_id;
1208 sample.period = 1;
1209 sample.cpu = ptq->cpu;
1210 sample.flags = ptq->flags;
1211 sample.insn_len = ptq->insn_len;
1212
1213 if (pt->synth_opts.callchain) {
1214 thread_stack__sample(ptq->thread, ptq->chain,
1215 pt->synth_opts.callchain_sz, sample.ip);
1216 sample.callchain = ptq->chain;
1217 }
1218
Adrian Hunterf14445e2015-09-25 16:15:45 +03001219 if (pt->synth_opts.last_branch) {
1220 intel_pt_copy_last_branch_rb(ptq);
1221 sample.branch_stack = ptq->last_branch;
1222 }
1223
Adrian Hunter90e457f2015-07-17 19:33:41 +03001224 if (pt->synth_opts.inject) {
1225 ret = intel_pt_inject_event(event, &sample,
1226 pt->transactions_sample_type,
1227 pt->synth_needs_swap);
1228 if (ret)
1229 return ret;
1230 }
1231
1232 ret = perf_session__deliver_synth_event(pt->session, event, &sample);
1233 if (ret)
1234 pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n",
1235 ret);
1236
Adrian Hunter1342e0b72016-04-18 13:57:48 +03001237 if (pt->synth_opts.last_branch)
Adrian Hunterf14445e2015-09-25 16:15:45 +03001238 intel_pt_reset_last_branch_rb(ptq);
1239
Adrian Hunter90e457f2015-07-17 19:33:41 +03001240 return ret;
1241}
1242
1243static int intel_pt_synth_error(struct intel_pt *pt, int code, int cpu,
1244 pid_t pid, pid_t tid, u64 ip)
1245{
1246 union perf_event event;
1247 char msg[MAX_AUXTRACE_ERROR_MSG];
1248 int err;
1249
1250 intel_pt__strerror(code, msg, MAX_AUXTRACE_ERROR_MSG);
1251
1252 auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE,
1253 code, cpu, pid, tid, ip, msg);
1254
1255 err = perf_session__deliver_synth_event(pt->session, &event, NULL);
1256 if (err)
1257 pr_err("Intel Processor Trace: failed to deliver error event, error %d\n",
1258 err);
1259
1260 return err;
1261}
1262
1263static int intel_pt_next_tid(struct intel_pt *pt, struct intel_pt_queue *ptq)
1264{
1265 struct auxtrace_queue *queue;
1266 pid_t tid = ptq->next_tid;
1267 int err;
1268
1269 if (tid == -1)
1270 return 0;
1271
1272 intel_pt_log("switch: cpu %d tid %d\n", ptq->cpu, tid);
1273
1274 err = machine__set_current_tid(pt->machine, ptq->cpu, -1, tid);
1275
1276 queue = &pt->queues.queue_array[ptq->queue_nr];
1277 intel_pt_set_pid_tid_cpu(pt, queue);
1278
1279 ptq->next_tid = -1;
1280
1281 return err;
1282}
1283
1284static inline bool intel_pt_is_switch_ip(struct intel_pt_queue *ptq, u64 ip)
1285{
1286 struct intel_pt *pt = ptq->pt;
1287
1288 return ip == pt->switch_ip &&
1289 (ptq->flags & PERF_IP_FLAG_BRANCH) &&
1290 !(ptq->flags & (PERF_IP_FLAG_CONDITIONAL | PERF_IP_FLAG_ASYNC |
1291 PERF_IP_FLAG_INTERRUPT | PERF_IP_FLAG_TX_ABORT));
1292}
1293
1294static int intel_pt_sample(struct intel_pt_queue *ptq)
1295{
1296 const struct intel_pt_state *state = ptq->state;
1297 struct intel_pt *pt = ptq->pt;
1298 int err;
1299
1300 if (!ptq->have_sample)
1301 return 0;
1302
1303 ptq->have_sample = false;
1304
1305 if (pt->sample_instructions &&
Andi Kleend1706b32016-03-28 10:45:38 -07001306 (state->type & INTEL_PT_INSTRUCTION) &&
1307 (!pt->synth_opts.initial_skip ||
1308 pt->num_events++ >= pt->synth_opts.initial_skip)) {
Adrian Hunter90e457f2015-07-17 19:33:41 +03001309 err = intel_pt_synth_instruction_sample(ptq);
1310 if (err)
1311 return err;
1312 }
1313
1314 if (pt->sample_transactions &&
Andi Kleend1706b32016-03-28 10:45:38 -07001315 (state->type & INTEL_PT_TRANSACTION) &&
1316 (!pt->synth_opts.initial_skip ||
1317 pt->num_events++ >= pt->synth_opts.initial_skip)) {
Adrian Hunter90e457f2015-07-17 19:33:41 +03001318 err = intel_pt_synth_transaction_sample(ptq);
1319 if (err)
1320 return err;
1321 }
1322
1323 if (!(state->type & INTEL_PT_BRANCH))
1324 return 0;
1325
Adrian Hunter50f736372016-06-23 16:40:57 +03001326 if (pt->synth_opts.callchain || pt->synth_opts.thread_stack)
Adrian Hunter90e457f2015-07-17 19:33:41 +03001327 thread_stack__event(ptq->thread, ptq->flags, state->from_ip,
1328 state->to_ip, ptq->insn_len,
1329 state->trace_nr);
1330 else
1331 thread_stack__set_trace_nr(ptq->thread, state->trace_nr);
1332
1333 if (pt->sample_branches) {
1334 err = intel_pt_synth_branch_sample(ptq);
1335 if (err)
1336 return err;
1337 }
1338
Adrian Hunterf14445e2015-09-25 16:15:45 +03001339 if (pt->synth_opts.last_branch)
1340 intel_pt_update_last_branch_rb(ptq);
1341
Adrian Hunter6a330362018-03-07 16:02:22 +02001342 if (!ptq->sync_switch)
Adrian Hunter90e457f2015-07-17 19:33:41 +03001343 return 0;
1344
1345 if (intel_pt_is_switch_ip(ptq, state->to_ip)) {
1346 switch (ptq->switch_state) {
1347 case INTEL_PT_SS_UNKNOWN:
1348 case INTEL_PT_SS_EXPECTING_SWITCH_IP:
1349 err = intel_pt_next_tid(pt, ptq);
1350 if (err)
1351 return err;
1352 ptq->switch_state = INTEL_PT_SS_TRACING;
1353 break;
1354 default:
1355 ptq->switch_state = INTEL_PT_SS_EXPECTING_SWITCH_EVENT;
1356 return 1;
1357 }
1358 } else if (!state->to_ip) {
1359 ptq->switch_state = INTEL_PT_SS_NOT_TRACING;
1360 } else if (ptq->switch_state == INTEL_PT_SS_NOT_TRACING) {
1361 ptq->switch_state = INTEL_PT_SS_UNKNOWN;
1362 } else if (ptq->switch_state == INTEL_PT_SS_UNKNOWN &&
1363 state->to_ip == pt->ptss_ip &&
1364 (ptq->flags & PERF_IP_FLAG_CALL)) {
1365 ptq->switch_state = INTEL_PT_SS_TRACING;
1366 }
1367
1368 return 0;
1369}
1370
Adrian Hunter86c27862015-08-13 12:40:57 +03001371static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip)
Adrian Hunter90e457f2015-07-17 19:33:41 +03001372{
Adrian Hunter86c27862015-08-13 12:40:57 +03001373 struct machine *machine = pt->machine;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001374 struct map *map;
1375 struct symbol *sym, *start;
1376 u64 ip, switch_ip = 0;
Adrian Hunter86c27862015-08-13 12:40:57 +03001377 const char *ptss;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001378
1379 if (ptss_ip)
1380 *ptss_ip = 0;
1381
Arnaldo Carvalho de Meloa5e813c2015-09-30 11:54:04 -03001382 map = machine__kernel_map(machine);
Adrian Hunter90e457f2015-07-17 19:33:41 +03001383 if (!map)
1384 return 0;
1385
Arnaldo Carvalho de Melobe39db92016-09-01 19:25:52 -03001386 if (map__load(map))
Adrian Hunter90e457f2015-07-17 19:33:41 +03001387 return 0;
1388
1389 start = dso__first_symbol(map->dso, MAP__FUNCTION);
1390
1391 for (sym = start; sym; sym = dso__next_symbol(sym)) {
1392 if (sym->binding == STB_GLOBAL &&
1393 !strcmp(sym->name, "__switch_to")) {
1394 ip = map->unmap_ip(map, sym->start);
1395 if (ip >= map->start && ip < map->end) {
1396 switch_ip = ip;
1397 break;
1398 }
1399 }
1400 }
1401
1402 if (!switch_ip || !ptss_ip)
1403 return 0;
1404
Adrian Hunter86c27862015-08-13 12:40:57 +03001405 if (pt->have_sched_switch == 1)
1406 ptss = "perf_trace_sched_switch";
1407 else
1408 ptss = "__perf_event_task_sched_out";
1409
Adrian Hunter90e457f2015-07-17 19:33:41 +03001410 for (sym = start; sym; sym = dso__next_symbol(sym)) {
Adrian Hunter86c27862015-08-13 12:40:57 +03001411 if (!strcmp(sym->name, ptss)) {
Adrian Hunter90e457f2015-07-17 19:33:41 +03001412 ip = map->unmap_ip(map, sym->start);
1413 if (ip >= map->start && ip < map->end) {
1414 *ptss_ip = ip;
1415 break;
1416 }
1417 }
1418 }
1419
1420 return switch_ip;
1421}
1422
Adrian Hunter6a330362018-03-07 16:02:22 +02001423static void intel_pt_enable_sync_switch(struct intel_pt *pt)
1424{
1425 unsigned int i;
1426
1427 pt->sync_switch = true;
1428
1429 for (i = 0; i < pt->queues.nr_queues; i++) {
1430 struct auxtrace_queue *queue = &pt->queues.queue_array[i];
1431 struct intel_pt_queue *ptq = queue->priv;
1432
1433 if (ptq)
1434 ptq->sync_switch = true;
1435 }
1436}
1437
Adrian Hunter90e457f2015-07-17 19:33:41 +03001438static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp)
1439{
1440 const struct intel_pt_state *state = ptq->state;
1441 struct intel_pt *pt = ptq->pt;
1442 int err;
1443
1444 if (!pt->kernel_start) {
1445 pt->kernel_start = machine__kernel_start(pt->machine);
Adrian Hunter86c27862015-08-13 12:40:57 +03001446 if (pt->per_cpu_mmaps &&
1447 (pt->have_sched_switch == 1 || pt->have_sched_switch == 3) &&
Adrian Hunter90e457f2015-07-17 19:33:41 +03001448 !pt->timeless_decoding && intel_pt_tracing_kernel(pt) &&
1449 !pt->sampling_mode) {
Adrian Hunter86c27862015-08-13 12:40:57 +03001450 pt->switch_ip = intel_pt_switch_ip(pt, &pt->ptss_ip);
Adrian Hunter90e457f2015-07-17 19:33:41 +03001451 if (pt->switch_ip) {
1452 intel_pt_log("switch_ip: %"PRIx64" ptss_ip: %"PRIx64"\n",
1453 pt->switch_ip, pt->ptss_ip);
Adrian Hunter6a330362018-03-07 16:02:22 +02001454 intel_pt_enable_sync_switch(pt);
Adrian Hunter90e457f2015-07-17 19:33:41 +03001455 }
1456 }
1457 }
1458
1459 intel_pt_log("queue %u decoding cpu %d pid %d tid %d\n",
1460 ptq->queue_nr, ptq->cpu, ptq->pid, ptq->tid);
1461 while (1) {
1462 err = intel_pt_sample(ptq);
1463 if (err)
1464 return err;
1465
1466 state = intel_pt_decode(ptq->decoder);
1467 if (state->err) {
1468 if (state->err == INTEL_PT_ERR_NODATA)
1469 return 1;
Adrian Hunter6a330362018-03-07 16:02:22 +02001470 if (ptq->sync_switch &&
Adrian Hunter90e457f2015-07-17 19:33:41 +03001471 state->from_ip >= pt->kernel_start) {
Adrian Hunter6a330362018-03-07 16:02:22 +02001472 ptq->sync_switch = false;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001473 intel_pt_next_tid(pt, ptq);
1474 }
1475 if (pt->synth_opts.errors) {
1476 err = intel_pt_synth_error(pt, state->err,
1477 ptq->cpu, ptq->pid,
1478 ptq->tid,
1479 state->from_ip);
1480 if (err)
1481 return err;
1482 }
1483 continue;
1484 }
1485
1486 ptq->state = state;
1487 ptq->have_sample = true;
1488 intel_pt_sample_flags(ptq);
1489
1490 /* Use estimated TSC upon return to user space */
1491 if (pt->est_tsc &&
1492 (state->from_ip >= pt->kernel_start || !state->from_ip) &&
1493 state->to_ip && state->to_ip < pt->kernel_start) {
1494 intel_pt_log("TSC %"PRIx64" est. TSC %"PRIx64"\n",
1495 state->timestamp, state->est_timestamp);
1496 ptq->timestamp = state->est_timestamp;
1497 /* Use estimated TSC in unknown switch state */
Adrian Hunter6a330362018-03-07 16:02:22 +02001498 } else if (ptq->sync_switch &&
Adrian Hunter90e457f2015-07-17 19:33:41 +03001499 ptq->switch_state == INTEL_PT_SS_UNKNOWN &&
1500 intel_pt_is_switch_ip(ptq, state->to_ip) &&
1501 ptq->next_tid == -1) {
1502 intel_pt_log("TSC %"PRIx64" est. TSC %"PRIx64"\n",
1503 state->timestamp, state->est_timestamp);
1504 ptq->timestamp = state->est_timestamp;
1505 } else if (state->timestamp > ptq->timestamp) {
1506 ptq->timestamp = state->timestamp;
1507 }
1508
1509 if (!pt->timeless_decoding && ptq->timestamp >= *timestamp) {
1510 *timestamp = ptq->timestamp;
1511 return 0;
1512 }
1513 }
1514 return 0;
1515}
1516
1517static inline int intel_pt_update_queues(struct intel_pt *pt)
1518{
1519 if (pt->queues.new_data) {
1520 pt->queues.new_data = false;
1521 return intel_pt_setup_queues(pt);
1522 }
1523 return 0;
1524}
1525
1526static int intel_pt_process_queues(struct intel_pt *pt, u64 timestamp)
1527{
1528 unsigned int queue_nr;
1529 u64 ts;
1530 int ret;
1531
1532 while (1) {
1533 struct auxtrace_queue *queue;
1534 struct intel_pt_queue *ptq;
1535
1536 if (!pt->heap.heap_cnt)
1537 return 0;
1538
1539 if (pt->heap.heap_array[0].ordinal >= timestamp)
1540 return 0;
1541
1542 queue_nr = pt->heap.heap_array[0].queue_nr;
1543 queue = &pt->queues.queue_array[queue_nr];
1544 ptq = queue->priv;
1545
1546 intel_pt_log("queue %u processing 0x%" PRIx64 " to 0x%" PRIx64 "\n",
1547 queue_nr, pt->heap.heap_array[0].ordinal,
1548 timestamp);
1549
1550 auxtrace_heap__pop(&pt->heap);
1551
1552 if (pt->heap.heap_cnt) {
1553 ts = pt->heap.heap_array[0].ordinal + 1;
1554 if (ts > timestamp)
1555 ts = timestamp;
1556 } else {
1557 ts = timestamp;
1558 }
1559
1560 intel_pt_set_pid_tid_cpu(pt, queue);
1561
1562 ret = intel_pt_run_decoder(ptq, &ts);
1563
1564 if (ret < 0) {
1565 auxtrace_heap__add(&pt->heap, queue_nr, ts);
1566 return ret;
1567 }
1568
1569 if (!ret) {
1570 ret = auxtrace_heap__add(&pt->heap, queue_nr, ts);
1571 if (ret < 0)
1572 return ret;
1573 } else {
1574 ptq->on_heap = false;
1575 }
1576 }
1577
1578 return 0;
1579}
1580
1581static int intel_pt_process_timeless_queues(struct intel_pt *pt, pid_t tid,
1582 u64 time_)
1583{
1584 struct auxtrace_queues *queues = &pt->queues;
1585 unsigned int i;
1586 u64 ts = 0;
1587
1588 for (i = 0; i < queues->nr_queues; i++) {
1589 struct auxtrace_queue *queue = &pt->queues.queue_array[i];
1590 struct intel_pt_queue *ptq = queue->priv;
1591
1592 if (ptq && (tid == -1 || ptq->tid == tid)) {
1593 ptq->time = time_;
1594 intel_pt_set_pid_tid_cpu(pt, queue);
1595 intel_pt_run_decoder(ptq, &ts);
1596 }
1597 }
1598 return 0;
1599}
1600
1601static int intel_pt_lost(struct intel_pt *pt, struct perf_sample *sample)
1602{
1603 return intel_pt_synth_error(pt, INTEL_PT_ERR_LOST, sample->cpu,
1604 sample->pid, sample->tid, 0);
1605}
1606
1607static struct intel_pt_queue *intel_pt_cpu_to_ptq(struct intel_pt *pt, int cpu)
1608{
1609 unsigned i, j;
1610
1611 if (cpu < 0 || !pt->queues.nr_queues)
1612 return NULL;
1613
1614 if ((unsigned)cpu >= pt->queues.nr_queues)
1615 i = pt->queues.nr_queues - 1;
1616 else
1617 i = cpu;
1618
1619 if (pt->queues.queue_array[i].cpu == cpu)
1620 return pt->queues.queue_array[i].priv;
1621
1622 for (j = 0; i > 0; j++) {
1623 if (pt->queues.queue_array[--i].cpu == cpu)
1624 return pt->queues.queue_array[i].priv;
1625 }
1626
1627 for (; j < pt->queues.nr_queues; j++) {
1628 if (pt->queues.queue_array[j].cpu == cpu)
1629 return pt->queues.queue_array[j].priv;
1630 }
1631
1632 return NULL;
1633}
1634
Adrian Hunter86c27862015-08-13 12:40:57 +03001635static int intel_pt_sync_switch(struct intel_pt *pt, int cpu, pid_t tid,
1636 u64 timestamp)
Adrian Hunter90e457f2015-07-17 19:33:41 +03001637{
1638 struct intel_pt_queue *ptq;
Adrian Hunter86c27862015-08-13 12:40:57 +03001639 int err;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001640
1641 if (!pt->sync_switch)
Adrian Hunter86c27862015-08-13 12:40:57 +03001642 return 1;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001643
1644 ptq = intel_pt_cpu_to_ptq(pt, cpu);
Adrian Hunter6a330362018-03-07 16:02:22 +02001645 if (!ptq || !ptq->sync_switch)
Adrian Hunter86c27862015-08-13 12:40:57 +03001646 return 1;
Adrian Hunter90e457f2015-07-17 19:33:41 +03001647
1648 switch (ptq->switch_state) {
1649 case INTEL_PT_SS_NOT_TRACING:
1650 ptq->next_tid = -1;
1651 break;
1652 case INTEL_PT_SS_UNKNOWN:
1653 case INTEL_PT_SS_TRACING:
1654 ptq->next_tid = tid;
1655 ptq->switch_state = INTEL_PT_SS_EXPECTING_SWITCH_IP;
1656 return 0;
1657 case INTEL_PT_SS_EXPECTING_SWITCH_EVENT:
1658 if (!ptq->on_heap) {
Adrian Hunter86c27862015-08-13 12:40:57 +03001659 ptq->timestamp = perf_time_to_tsc(timestamp,
Adrian Hunter90e457f2015-07-17 19:33:41 +03001660 &pt->tc);
1661 err = auxtrace_heap__add(&pt->heap, ptq->queue_nr,
1662 ptq->timestamp);
1663 if (err)
1664 return err;
1665 ptq->on_heap = true;
1666 }
1667 ptq->switch_state = INTEL_PT_SS_TRACING;
1668 break;
1669 case INTEL_PT_SS_EXPECTING_SWITCH_IP:
1670 ptq->next_tid = tid;
1671 intel_pt_log("ERROR: cpu %d expecting switch ip\n", cpu);
1672 break;
1673 default:
1674 break;
1675 }
Adrian Hunter86c27862015-08-13 12:40:57 +03001676
1677 return 1;
1678}
1679
1680static int intel_pt_process_switch(struct intel_pt *pt,
1681 struct perf_sample *sample)
1682{
1683 struct perf_evsel *evsel;
1684 pid_t tid;
1685 int cpu, ret;
1686
1687 evsel = perf_evlist__id2evsel(pt->session->evlist, sample->id);
1688 if (evsel != pt->switch_evsel)
1689 return 0;
1690
1691 tid = perf_evsel__intval(evsel, sample, "next_pid");
1692 cpu = sample->cpu;
1693
1694 intel_pt_log("sched_switch: cpu %d tid %d time %"PRIu64" tsc %#"PRIx64"\n",
1695 cpu, tid, sample->time, perf_time_to_tsc(sample->time,
1696 &pt->tc));
1697
1698 ret = intel_pt_sync_switch(pt, cpu, tid, sample->time);
1699 if (ret <= 0)
1700 return ret;
1701
Adrian Hunter90e457f2015-07-17 19:33:41 +03001702 return machine__set_current_tid(pt->machine, cpu, -1, tid);
1703}
1704
Adrian Hunter86c27862015-08-13 12:40:57 +03001705static int intel_pt_context_switch(struct intel_pt *pt, union perf_event *event,
1706 struct perf_sample *sample)
1707{
1708 bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
1709 pid_t pid, tid;
1710 int cpu, ret;
1711
1712 cpu = sample->cpu;
1713
1714 if (pt->have_sched_switch == 3) {
1715 if (!out)
1716 return 0;
1717 if (event->header.type != PERF_RECORD_SWITCH_CPU_WIDE) {
1718 pr_err("Expecting CPU-wide context switch event\n");
1719 return -EINVAL;
1720 }
1721 pid = event->context_switch.next_prev_pid;
1722 tid = event->context_switch.next_prev_tid;
1723 } else {
1724 if (out)
1725 return 0;
1726 pid = sample->pid;
1727 tid = sample->tid;
1728 }
1729
1730 if (tid == -1) {
1731 pr_err("context_switch event has no tid\n");
1732 return -EINVAL;
1733 }
1734
1735 intel_pt_log("context_switch: cpu %d pid %d tid %d time %"PRIu64" tsc %#"PRIx64"\n",
1736 cpu, pid, tid, sample->time, perf_time_to_tsc(sample->time,
1737 &pt->tc));
1738
1739 ret = intel_pt_sync_switch(pt, cpu, tid, sample->time);
1740 if (ret <= 0)
1741 return ret;
1742
1743 return machine__set_current_tid(pt->machine, cpu, pid, tid);
1744}
1745
Adrian Hunter90e457f2015-07-17 19:33:41 +03001746static int intel_pt_process_itrace_start(struct intel_pt *pt,
1747 union perf_event *event,
1748 struct perf_sample *sample)
1749{
1750 if (!pt->per_cpu_mmaps)
1751 return 0;
1752
1753 intel_pt_log("itrace_start: cpu %d pid %d tid %d time %"PRIu64" tsc %#"PRIx64"\n",
1754 sample->cpu, event->itrace_start.pid,
1755 event->itrace_start.tid, sample->time,
1756 perf_time_to_tsc(sample->time, &pt->tc));
1757
1758 return machine__set_current_tid(pt->machine, sample->cpu,
1759 event->itrace_start.pid,
1760 event->itrace_start.tid);
1761}
1762
1763static int intel_pt_process_event(struct perf_session *session,
1764 union perf_event *event,
1765 struct perf_sample *sample,
1766 struct perf_tool *tool)
1767{
1768 struct intel_pt *pt = container_of(session->auxtrace, struct intel_pt,
1769 auxtrace);
1770 u64 timestamp;
1771 int err = 0;
1772
1773 if (dump_trace)
1774 return 0;
1775
1776 if (!tool->ordered_events) {
1777 pr_err("Intel Processor Trace requires ordered events\n");
1778 return -EINVAL;
1779 }
1780
Adrian Hunter81cd60c2015-08-20 11:51:32 +03001781 if (sample->time && sample->time != (u64)-1)
Adrian Hunter90e457f2015-07-17 19:33:41 +03001782 timestamp = perf_time_to_tsc(sample->time, &pt->tc);
1783 else
1784 timestamp = 0;
1785
1786 if (timestamp || pt->timeless_decoding) {
1787 err = intel_pt_update_queues(pt);
1788 if (err)
1789 return err;
1790 }
1791
1792 if (pt->timeless_decoding) {
1793 if (event->header.type == PERF_RECORD_EXIT) {
1794 err = intel_pt_process_timeless_queues(pt,
Adrian Hunter53ff6bc2015-08-18 12:07:05 +03001795 event->fork.tid,
Adrian Hunter90e457f2015-07-17 19:33:41 +03001796 sample->time);
1797 }
1798 } else if (timestamp) {
1799 err = intel_pt_process_queues(pt, timestamp);
1800 }
1801 if (err)
1802 return err;
1803
1804 if (event->header.type == PERF_RECORD_AUX &&
1805 (event->aux.flags & PERF_AUX_FLAG_TRUNCATED) &&
1806 pt->synth_opts.errors) {
1807 err = intel_pt_lost(pt, sample);
1808 if (err)
1809 return err;
1810 }
1811
1812 if (pt->switch_evsel && event->header.type == PERF_RECORD_SAMPLE)
1813 err = intel_pt_process_switch(pt, sample);
1814 else if (event->header.type == PERF_RECORD_ITRACE_START)
1815 err = intel_pt_process_itrace_start(pt, event, sample);
Adrian Hunter86c27862015-08-13 12:40:57 +03001816 else if (event->header.type == PERF_RECORD_SWITCH ||
1817 event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)
1818 err = intel_pt_context_switch(pt, event, sample);
Adrian Hunter90e457f2015-07-17 19:33:41 +03001819
1820 intel_pt_log("event %s (%u): cpu %d time %"PRIu64" tsc %#"PRIx64"\n",
1821 perf_event__name(event->header.type), event->header.type,
1822 sample->cpu, sample->time, timestamp);
1823
1824 return err;
1825}
1826
1827static int intel_pt_flush(struct perf_session *session, struct perf_tool *tool)
1828{
1829 struct intel_pt *pt = container_of(session->auxtrace, struct intel_pt,
1830 auxtrace);
1831 int ret;
1832
1833 if (dump_trace)
1834 return 0;
1835
1836 if (!tool->ordered_events)
1837 return -EINVAL;
1838
1839 ret = intel_pt_update_queues(pt);
1840 if (ret < 0)
1841 return ret;
1842
1843 if (pt->timeless_decoding)
1844 return intel_pt_process_timeless_queues(pt, -1,
1845 MAX_TIMESTAMP - 1);
1846
1847 return intel_pt_process_queues(pt, MAX_TIMESTAMP);
1848}
1849
1850static void intel_pt_free_events(struct perf_session *session)
1851{
1852 struct intel_pt *pt = container_of(session->auxtrace, struct intel_pt,
1853 auxtrace);
1854 struct auxtrace_queues *queues = &pt->queues;
1855 unsigned int i;
1856
1857 for (i = 0; i < queues->nr_queues; i++) {
1858 intel_pt_free_queue(queues->queue_array[i].priv);
1859 queues->queue_array[i].priv = NULL;
1860 }
1861 intel_pt_log_disable();
1862 auxtrace_queues__free(queues);
1863}
1864
1865static void intel_pt_free(struct perf_session *session)
1866{
1867 struct intel_pt *pt = container_of(session->auxtrace, struct intel_pt,
1868 auxtrace);
1869
1870 auxtrace_heap__free(&pt->heap);
1871 intel_pt_free_events(session);
1872 session->auxtrace = NULL;
Arnaldo Carvalho de Meloabd82862015-12-11 19:11:23 -03001873 thread__put(pt->unknown_thread);
Adrian Hunter2acee102016-09-23 17:38:48 +03001874 addr_filters__exit(&pt->filts);
Adrian Hunter2b9e32c2016-09-23 17:38:46 +03001875 zfree(&pt->filter);
Adrian Hunter90e457f2015-07-17 19:33:41 +03001876 free(pt);
1877}
1878
1879static int intel_pt_process_auxtrace_event(struct perf_session *session,
1880 union perf_event *event,
1881 struct perf_tool *tool __maybe_unused)
1882{
1883 struct intel_pt *pt = container_of(session->auxtrace, struct intel_pt,
1884 auxtrace);
1885
1886 if (pt->sampling_mode)
1887 return 0;
1888
1889 if (!pt->data_queued) {
1890 struct auxtrace_buffer *buffer;
1891 off_t data_offset;
1892 int fd = perf_data_file__fd(session->file);
1893 int err;
1894
1895 if (perf_data_file__is_pipe(session->file)) {
1896 data_offset = 0;
1897 } else {
1898 data_offset = lseek(fd, 0, SEEK_CUR);
1899 if (data_offset == -1)
1900 return -errno;
1901 }
1902
1903 err = auxtrace_queues__add_event(&pt->queues, session, event,
1904 data_offset, &buffer);
1905 if (err)
1906 return err;
1907
1908 /* Dump here now we have copied a piped trace out of the pipe */
1909 if (dump_trace) {
1910 if (auxtrace_buffer__get_data(buffer, fd)) {
1911 intel_pt_dump_event(pt, buffer->data,
1912 buffer->size);
1913 auxtrace_buffer__put_data(buffer);
1914 }
1915 }
1916 }
1917
1918 return 0;
1919}
1920
1921struct intel_pt_synth {
1922 struct perf_tool dummy_tool;
1923 struct perf_session *session;
1924};
1925
1926static int intel_pt_event_synth(struct perf_tool *tool,
1927 union perf_event *event,
1928 struct perf_sample *sample __maybe_unused,
1929 struct machine *machine __maybe_unused)
1930{
1931 struct intel_pt_synth *intel_pt_synth =
1932 container_of(tool, struct intel_pt_synth, dummy_tool);
1933
1934 return perf_session__deliver_synth_event(intel_pt_synth->session, event,
1935 NULL);
1936}
1937
1938static int intel_pt_synth_event(struct perf_session *session,
1939 struct perf_event_attr *attr, u64 id)
1940{
1941 struct intel_pt_synth intel_pt_synth;
1942
1943 memset(&intel_pt_synth, 0, sizeof(struct intel_pt_synth));
1944 intel_pt_synth.session = session;
1945
1946 return perf_event__synthesize_attr(&intel_pt_synth.dummy_tool, attr, 1,
1947 &id, intel_pt_event_synth);
1948}
1949
1950static int intel_pt_synth_events(struct intel_pt *pt,
1951 struct perf_session *session)
1952{
1953 struct perf_evlist *evlist = session->evlist;
1954 struct perf_evsel *evsel;
1955 struct perf_event_attr attr;
1956 bool found = false;
1957 u64 id;
1958 int err;
1959
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -03001960 evlist__for_each_entry(evlist, evsel) {
Adrian Hunter90e457f2015-07-17 19:33:41 +03001961 if (evsel->attr.type == pt->pmu_type && evsel->ids) {
1962 found = true;
1963 break;
1964 }
1965 }
1966
1967 if (!found) {
1968 pr_debug("There are no selected events with Intel Processor Trace data\n");
1969 return 0;
1970 }
1971
1972 memset(&attr, 0, sizeof(struct perf_event_attr));
1973 attr.size = sizeof(struct perf_event_attr);
1974 attr.type = PERF_TYPE_HARDWARE;
1975 attr.sample_type = evsel->attr.sample_type & PERF_SAMPLE_MASK;
1976 attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
1977 PERF_SAMPLE_PERIOD;
1978 if (pt->timeless_decoding)
1979 attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
1980 else
1981 attr.sample_type |= PERF_SAMPLE_TIME;
1982 if (!pt->per_cpu_mmaps)
1983 attr.sample_type &= ~(u64)PERF_SAMPLE_CPU;
1984 attr.exclude_user = evsel->attr.exclude_user;
1985 attr.exclude_kernel = evsel->attr.exclude_kernel;
1986 attr.exclude_hv = evsel->attr.exclude_hv;
1987 attr.exclude_host = evsel->attr.exclude_host;
1988 attr.exclude_guest = evsel->attr.exclude_guest;
1989 attr.sample_id_all = evsel->attr.sample_id_all;
1990 attr.read_format = evsel->attr.read_format;
1991
1992 id = evsel->id[0] + 1000000000;
1993 if (!id)
1994 id = 1;
1995
1996 if (pt->synth_opts.instructions) {
1997 attr.config = PERF_COUNT_HW_INSTRUCTIONS;
1998 if (pt->synth_opts.period_type == PERF_ITRACE_PERIOD_NANOSECS)
1999 attr.sample_period =
2000 intel_pt_ns_to_ticks(pt, pt->synth_opts.period);
2001 else
2002 attr.sample_period = pt->synth_opts.period;
2003 pt->instructions_sample_period = attr.sample_period;
2004 if (pt->synth_opts.callchain)
2005 attr.sample_type |= PERF_SAMPLE_CALLCHAIN;
Adrian Hunterf14445e2015-09-25 16:15:45 +03002006 if (pt->synth_opts.last_branch)
2007 attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
Adrian Hunter90e457f2015-07-17 19:33:41 +03002008 pr_debug("Synthesizing 'instructions' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
2009 id, (u64)attr.sample_type);
2010 err = intel_pt_synth_event(session, &attr, id);
2011 if (err) {
2012 pr_err("%s: failed to synthesize 'instructions' event type\n",
2013 __func__);
2014 return err;
2015 }
2016 pt->sample_instructions = true;
2017 pt->instructions_sample_type = attr.sample_type;
2018 pt->instructions_id = id;
2019 id += 1;
2020 }
2021
2022 if (pt->synth_opts.transactions) {
2023 attr.config = PERF_COUNT_HW_INSTRUCTIONS;
2024 attr.sample_period = 1;
2025 if (pt->synth_opts.callchain)
2026 attr.sample_type |= PERF_SAMPLE_CALLCHAIN;
Adrian Hunterf14445e2015-09-25 16:15:45 +03002027 if (pt->synth_opts.last_branch)
2028 attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
Adrian Hunter90e457f2015-07-17 19:33:41 +03002029 pr_debug("Synthesizing 'transactions' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
2030 id, (u64)attr.sample_type);
2031 err = intel_pt_synth_event(session, &attr, id);
2032 if (err) {
2033 pr_err("%s: failed to synthesize 'transactions' event type\n",
2034 __func__);
2035 return err;
2036 }
2037 pt->sample_transactions = true;
2038 pt->transactions_id = id;
2039 id += 1;
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -03002040 evlist__for_each_entry(evlist, evsel) {
Adrian Hunter90e457f2015-07-17 19:33:41 +03002041 if (evsel->id && evsel->id[0] == pt->transactions_id) {
2042 if (evsel->name)
2043 zfree(&evsel->name);
2044 evsel->name = strdup("transactions");
2045 break;
2046 }
2047 }
2048 }
2049
2050 if (pt->synth_opts.branches) {
2051 attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
2052 attr.sample_period = 1;
2053 attr.sample_type |= PERF_SAMPLE_ADDR;
2054 attr.sample_type &= ~(u64)PERF_SAMPLE_CALLCHAIN;
Adrian Hunterf14445e2015-09-25 16:15:45 +03002055 attr.sample_type &= ~(u64)PERF_SAMPLE_BRANCH_STACK;
Adrian Hunter90e457f2015-07-17 19:33:41 +03002056 pr_debug("Synthesizing 'branches' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
2057 id, (u64)attr.sample_type);
2058 err = intel_pt_synth_event(session, &attr, id);
2059 if (err) {
2060 pr_err("%s: failed to synthesize 'branches' event type\n",
2061 __func__);
2062 return err;
2063 }
2064 pt->sample_branches = true;
2065 pt->branches_sample_type = attr.sample_type;
2066 pt->branches_id = id;
2067 }
2068
2069 pt->synth_needs_swap = evsel->needs_swap;
2070
2071 return 0;
2072}
2073
2074static struct perf_evsel *intel_pt_find_sched_switch(struct perf_evlist *evlist)
2075{
2076 struct perf_evsel *evsel;
2077
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -03002078 evlist__for_each_entry_reverse(evlist, evsel) {
Adrian Hunter90e457f2015-07-17 19:33:41 +03002079 const char *name = perf_evsel__name(evsel);
2080
2081 if (!strcmp(name, "sched:sched_switch"))
2082 return evsel;
2083 }
2084
2085 return NULL;
2086}
2087
Adrian Hunter86c27862015-08-13 12:40:57 +03002088static bool intel_pt_find_switch(struct perf_evlist *evlist)
2089{
2090 struct perf_evsel *evsel;
2091
Arnaldo Carvalho de Meloe5cadb92016-06-23 11:26:15 -03002092 evlist__for_each_entry(evlist, evsel) {
Adrian Hunter86c27862015-08-13 12:40:57 +03002093 if (evsel->attr.context_switch)
2094 return true;
2095 }
2096
2097 return false;
2098}
2099
Adrian Hunterba11ba62015-09-25 16:15:56 +03002100static int intel_pt_perf_config(const char *var, const char *value, void *data)
2101{
2102 struct intel_pt *pt = data;
2103
2104 if (!strcmp(var, "intel-pt.mispred-all"))
2105 pt->mispred_all = perf_config_bool(var, value);
2106
2107 return 0;
2108}
2109
Adrian Hunter90e457f2015-07-17 19:33:41 +03002110static const char * const intel_pt_info_fmts[] = {
Adrian Hunter11fa7cb2015-07-17 19:33:54 +03002111 [INTEL_PT_PMU_TYPE] = " PMU Type %"PRId64"\n",
2112 [INTEL_PT_TIME_SHIFT] = " Time Shift %"PRIu64"\n",
2113 [INTEL_PT_TIME_MULT] = " Time Muliplier %"PRIu64"\n",
2114 [INTEL_PT_TIME_ZERO] = " Time Zero %"PRIu64"\n",
2115 [INTEL_PT_CAP_USER_TIME_ZERO] = " Cap Time Zero %"PRId64"\n",
2116 [INTEL_PT_TSC_BIT] = " TSC bit %#"PRIx64"\n",
2117 [INTEL_PT_NORETCOMP_BIT] = " NoRETComp bit %#"PRIx64"\n",
2118 [INTEL_PT_HAVE_SCHED_SWITCH] = " Have sched_switch %"PRId64"\n",
2119 [INTEL_PT_SNAPSHOT_MODE] = " Snapshot mode %"PRId64"\n",
2120 [INTEL_PT_PER_CPU_MMAPS] = " Per-cpu maps %"PRId64"\n",
2121 [INTEL_PT_MTC_BIT] = " MTC bit %#"PRIx64"\n",
2122 [INTEL_PT_TSC_CTC_N] = " TSC:CTC numerator %"PRIu64"\n",
2123 [INTEL_PT_TSC_CTC_D] = " TSC:CTC denominator %"PRIu64"\n",
2124 [INTEL_PT_CYC_BIT] = " CYC bit %#"PRIx64"\n",
Adrian Hunterfa8025c2016-09-23 17:38:42 +03002125 [INTEL_PT_MAX_NONTURBO_RATIO] = " Max non-turbo ratio %"PRIu64"\n",
Adrian Hunter2b9e32c2016-09-23 17:38:46 +03002126 [INTEL_PT_FILTER_STR_LEN] = " Filter string len. %"PRIu64"\n",
Adrian Hunter90e457f2015-07-17 19:33:41 +03002127};
2128
2129static void intel_pt_print_info(u64 *arr, int start, int finish)
2130{
2131 int i;
2132
2133 if (!dump_trace)
2134 return;
2135
2136 for (i = start; i <= finish; i++)
2137 fprintf(stdout, intel_pt_info_fmts[i], arr[i]);
2138}
2139
Adrian Hunter2b9e32c2016-09-23 17:38:46 +03002140static void intel_pt_print_info_str(const char *name, const char *str)
2141{
2142 if (!dump_trace)
2143 return;
2144
2145 fprintf(stdout, " %-20s%s\n", name, str ? str : "");
2146}
2147
Adrian Hunter40b746a2016-09-23 17:38:44 +03002148static bool intel_pt_has(struct auxtrace_info_event *auxtrace_info, int pos)
2149{
2150 return auxtrace_info->header.size >=
2151 sizeof(struct auxtrace_info_event) + (sizeof(u64) * (pos + 1));
2152}
2153
Adrian Hunter90e457f2015-07-17 19:33:41 +03002154int intel_pt_process_auxtrace_info(union perf_event *event,
2155 struct perf_session *session)
2156{
2157 struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info;
2158 size_t min_sz = sizeof(u64) * INTEL_PT_PER_CPU_MMAPS;
2159 struct intel_pt *pt;
Adrian Hunter2b9e32c2016-09-23 17:38:46 +03002160 void *info_end;
2161 u64 *info;
Adrian Hunter90e457f2015-07-17 19:33:41 +03002162 int err;
2163
2164 if (auxtrace_info->header.size < sizeof(struct auxtrace_info_event) +
2165 min_sz)
2166 return -EINVAL;
2167
2168 pt = zalloc(sizeof(struct intel_pt));
2169 if (!pt)
2170 return -ENOMEM;
2171
Adrian Hunter2acee102016-09-23 17:38:48 +03002172 addr_filters__init(&pt->filts);
2173
Adrian Hunterba11ba62015-09-25 16:15:56 +03002174 perf_config(intel_pt_perf_config, pt);
2175
Adrian Hunter90e457f2015-07-17 19:33:41 +03002176 err = auxtrace_queues__init(&pt->queues);
2177 if (err)
2178 goto err_free;
2179
2180 intel_pt_log_set_name(INTEL_PT_PMU_NAME);
2181
2182 pt->session = session;
2183 pt->machine = &session->machines.host; /* No kvm support */
2184 pt->auxtrace_type = auxtrace_info->type;
2185 pt->pmu_type = auxtrace_info->priv[INTEL_PT_PMU_TYPE];
2186 pt->tc.time_shift = auxtrace_info->priv[INTEL_PT_TIME_SHIFT];
2187 pt->tc.time_mult = auxtrace_info->priv[INTEL_PT_TIME_MULT];
2188 pt->tc.time_zero = auxtrace_info->priv[INTEL_PT_TIME_ZERO];
2189 pt->cap_user_time_zero = auxtrace_info->priv[INTEL_PT_CAP_USER_TIME_ZERO];
2190 pt->tsc_bit = auxtrace_info->priv[INTEL_PT_TSC_BIT];
2191 pt->noretcomp_bit = auxtrace_info->priv[INTEL_PT_NORETCOMP_BIT];
2192 pt->have_sched_switch = auxtrace_info->priv[INTEL_PT_HAVE_SCHED_SWITCH];
2193 pt->snapshot_mode = auxtrace_info->priv[INTEL_PT_SNAPSHOT_MODE];
2194 pt->per_cpu_mmaps = auxtrace_info->priv[INTEL_PT_PER_CPU_MMAPS];
2195 intel_pt_print_info(&auxtrace_info->priv[0], INTEL_PT_PMU_TYPE,
2196 INTEL_PT_PER_CPU_MMAPS);
2197
Adrian Hunter40b746a2016-09-23 17:38:44 +03002198 if (intel_pt_has(auxtrace_info, INTEL_PT_CYC_BIT)) {
Adrian Hunter11fa7cb2015-07-17 19:33:54 +03002199 pt->mtc_bit = auxtrace_info->priv[INTEL_PT_MTC_BIT];
2200 pt->mtc_freq_bits = auxtrace_info->priv[INTEL_PT_MTC_FREQ_BITS];
2201 pt->tsc_ctc_ratio_n = auxtrace_info->priv[INTEL_PT_TSC_CTC_N];
2202 pt->tsc_ctc_ratio_d = auxtrace_info->priv[INTEL_PT_TSC_CTC_D];
2203 pt->cyc_bit = auxtrace_info->priv[INTEL_PT_CYC_BIT];
2204 intel_pt_print_info(&auxtrace_info->priv[0], INTEL_PT_MTC_BIT,
2205 INTEL_PT_CYC_BIT);
2206 }
2207
Adrian Hunter40b746a2016-09-23 17:38:44 +03002208 if (intel_pt_has(auxtrace_info, INTEL_PT_MAX_NONTURBO_RATIO)) {
Adrian Hunterfa8025c2016-09-23 17:38:42 +03002209 pt->max_non_turbo_ratio =
2210 auxtrace_info->priv[INTEL_PT_MAX_NONTURBO_RATIO];
2211 intel_pt_print_info(&auxtrace_info->priv[0],
2212 INTEL_PT_MAX_NONTURBO_RATIO,
2213 INTEL_PT_MAX_NONTURBO_RATIO);
2214 }
2215
Adrian Hunter2b9e32c2016-09-23 17:38:46 +03002216 info = &auxtrace_info->priv[INTEL_PT_FILTER_STR_LEN] + 1;
2217 info_end = (void *)info + auxtrace_info->header.size;
2218
2219 if (intel_pt_has(auxtrace_info, INTEL_PT_FILTER_STR_LEN)) {
2220 size_t len;
2221
2222 len = auxtrace_info->priv[INTEL_PT_FILTER_STR_LEN];
2223 intel_pt_print_info(&auxtrace_info->priv[0],
2224 INTEL_PT_FILTER_STR_LEN,
2225 INTEL_PT_FILTER_STR_LEN);
2226 if (len) {
2227 const char *filter = (const char *)info;
2228
2229 len = roundup(len + 1, 8);
2230 info += len >> 3;
2231 if ((void *)info > info_end) {
2232 pr_err("%s: bad filter string length\n", __func__);
2233 err = -EINVAL;
2234 goto err_free_queues;
2235 }
2236 pt->filter = memdup(filter, len);
2237 if (!pt->filter) {
2238 err = -ENOMEM;
2239 goto err_free_queues;
2240 }
2241 if (session->header.needs_swap)
2242 mem_bswap_64(pt->filter, len);
2243 if (pt->filter[len - 1]) {
2244 pr_err("%s: filter string not null terminated\n", __func__);
2245 err = -EINVAL;
2246 goto err_free_queues;
2247 }
Adrian Hunter2acee102016-09-23 17:38:48 +03002248 err = addr_filters__parse_bare_filter(&pt->filts,
2249 filter);
2250 if (err)
2251 goto err_free_queues;
Adrian Hunter2b9e32c2016-09-23 17:38:46 +03002252 }
2253 intel_pt_print_info_str("Filter string", pt->filter);
2254 }
2255
Adrian Hunter90e457f2015-07-17 19:33:41 +03002256 pt->timeless_decoding = intel_pt_timeless_decoding(pt);
2257 pt->have_tsc = intel_pt_have_tsc(pt);
2258 pt->sampling_mode = false;
2259 pt->est_tsc = !pt->timeless_decoding;
2260
2261 pt->unknown_thread = thread__new(999999999, 999999999);
2262 if (!pt->unknown_thread) {
2263 err = -ENOMEM;
2264 goto err_free_queues;
2265 }
Adrian Hunter3a4acda2016-02-01 03:21:04 +00002266
2267 /*
2268 * Since this thread will not be kept in any rbtree not in a
2269 * list, initialize its list node so that at thread__put() the
2270 * current thread lifetime assuption is kept and we don't segfault
2271 * at list_del_init().
2272 */
2273 INIT_LIST_HEAD(&pt->unknown_thread->node);
2274
Adrian Hunter90e457f2015-07-17 19:33:41 +03002275 err = thread__set_comm(pt->unknown_thread, "unknown", 0);
2276 if (err)
2277 goto err_delete_thread;
2278 if (thread__init_map_groups(pt->unknown_thread, pt->machine)) {
2279 err = -ENOMEM;
2280 goto err_delete_thread;
2281 }
2282
2283 pt->auxtrace.process_event = intel_pt_process_event;
2284 pt->auxtrace.process_auxtrace_event = intel_pt_process_auxtrace_event;
2285 pt->auxtrace.flush_events = intel_pt_flush;
2286 pt->auxtrace.free_events = intel_pt_free_events;
2287 pt->auxtrace.free = intel_pt_free;
2288 session->auxtrace = &pt->auxtrace;
2289
2290 if (dump_trace)
2291 return 0;
2292
2293 if (pt->have_sched_switch == 1) {
2294 pt->switch_evsel = intel_pt_find_sched_switch(session->evlist);
2295 if (!pt->switch_evsel) {
2296 pr_err("%s: missing sched_switch event\n", __func__);
Adrian Hunter4d34e102016-09-23 17:38:43 +03002297 err = -EINVAL;
Adrian Hunter90e457f2015-07-17 19:33:41 +03002298 goto err_delete_thread;
2299 }
Adrian Hunter86c27862015-08-13 12:40:57 +03002300 } else if (pt->have_sched_switch == 2 &&
2301 !intel_pt_find_switch(session->evlist)) {
2302 pr_err("%s: missing context_switch attribute flag\n", __func__);
Adrian Hunter4d34e102016-09-23 17:38:43 +03002303 err = -EINVAL;
Adrian Hunter86c27862015-08-13 12:40:57 +03002304 goto err_delete_thread;
Adrian Hunter90e457f2015-07-17 19:33:41 +03002305 }
2306
2307 if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
2308 pt->synth_opts = *session->itrace_synth_opts;
2309 } else {
2310 itrace_synth_opts__set_default(&pt->synth_opts);
2311 if (use_browser != -1) {
2312 pt->synth_opts.branches = false;
2313 pt->synth_opts.callchain = true;
2314 }
Adrian Hunter50f736372016-06-23 16:40:57 +03002315 if (session->itrace_synth_opts)
2316 pt->synth_opts.thread_stack =
2317 session->itrace_synth_opts->thread_stack;
Adrian Hunter90e457f2015-07-17 19:33:41 +03002318 }
2319
2320 if (pt->synth_opts.log)
2321 intel_pt_log_enable();
2322
2323 /* Maximum non-turbo ratio is TSC freq / 100 MHz */
2324 if (pt->tc.time_mult) {
2325 u64 tsc_freq = intel_pt_ns_to_ticks(pt, 1000000000);
2326
Adrian Hunterfa8025c2016-09-23 17:38:42 +03002327 if (!pt->max_non_turbo_ratio)
2328 pt->max_non_turbo_ratio =
2329 (tsc_freq + 50000000) / 100000000;
Adrian Hunter90e457f2015-07-17 19:33:41 +03002330 intel_pt_log("TSC frequency %"PRIu64"\n", tsc_freq);
2331 intel_pt_log("Maximum non-turbo ratio %u\n",
2332 pt->max_non_turbo_ratio);
2333 }
2334
2335 if (pt->synth_opts.calls)
2336 pt->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |
2337 PERF_IP_FLAG_TRACE_END;
2338 if (pt->synth_opts.returns)
2339 pt->branches_filter |= PERF_IP_FLAG_RETURN |
2340 PERF_IP_FLAG_TRACE_BEGIN;
2341
2342 if (pt->synth_opts.callchain && !symbol_conf.use_callchain) {
2343 symbol_conf.use_callchain = true;
2344 if (callchain_register_param(&callchain_param) < 0) {
2345 symbol_conf.use_callchain = false;
2346 pt->synth_opts.callchain = false;
2347 }
2348 }
2349
2350 err = intel_pt_synth_events(pt, session);
2351 if (err)
2352 goto err_delete_thread;
2353
2354 err = auxtrace_queues__process_index(&pt->queues, session);
2355 if (err)
2356 goto err_delete_thread;
2357
2358 if (pt->queues.populated)
2359 pt->data_queued = true;
2360
2361 if (pt->timeless_decoding)
2362 pr_debug2("Intel PT decoding without timestamps\n");
2363
2364 return 0;
2365
2366err_delete_thread:
Arnaldo Carvalho de Meloabd82862015-12-11 19:11:23 -03002367 thread__zput(pt->unknown_thread);
Adrian Hunter90e457f2015-07-17 19:33:41 +03002368err_free_queues:
2369 intel_pt_log_disable();
2370 auxtrace_queues__free(&pt->queues);
2371 session->auxtrace = NULL;
2372err_free:
Adrian Hunter2acee102016-09-23 17:38:48 +03002373 addr_filters__exit(&pt->filts);
Adrian Hunter2b9e32c2016-09-23 17:38:46 +03002374 zfree(&pt->filter);
Adrian Hunter90e457f2015-07-17 19:33:41 +03002375 free(pt);
2376 return err;
2377}