0001
0002
0003
0004
0005
0006
0007 #include <endian.h>
0008 #include <errno.h>
0009 #include <byteswap.h>
0010 #include <inttypes.h>
0011 #include <linux/kernel.h>
0012 #include <linux/types.h>
0013 #include <linux/bitops.h>
0014 #include <linux/log2.h>
0015 #include <linux/zalloc.h>
0016
0017 #include "color.h"
0018 #include "evsel.h"
0019 #include "evlist.h"
0020 #include "machine.h"
0021 #include "symbol.h"
0022 #include "session.h"
0023 #include "tool.h"
0024 #include "thread.h"
0025 #include "thread-stack.h"
0026 #include "debug.h"
0027 #include "tsc.h"
0028 #include "auxtrace.h"
0029 #include "intel-pt-decoder/intel-pt-insn-decoder.h"
0030 #include "intel-bts.h"
0031 #include "util/synthetic-events.h"
0032
0033 #define MAX_TIMESTAMP (~0ULL)
0034
0035 #define INTEL_BTS_ERR_NOINSN 5
0036 #define INTEL_BTS_ERR_LOST 9
0037
0038 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
0039 #define le64_to_cpu bswap_64
0040 #else
0041 #define le64_to_cpu
0042 #endif
0043
0044 struct intel_bts {
0045 struct auxtrace auxtrace;
0046 struct auxtrace_queues queues;
0047 struct auxtrace_heap heap;
0048 u32 auxtrace_type;
0049 struct perf_session *session;
0050 struct machine *machine;
0051 bool sampling_mode;
0052 bool snapshot_mode;
0053 bool data_queued;
0054 u32 pmu_type;
0055 struct perf_tsc_conversion tc;
0056 bool cap_user_time_zero;
0057 struct itrace_synth_opts synth_opts;
0058 bool sample_branches;
0059 u32 branches_filter;
0060 u64 branches_sample_type;
0061 u64 branches_id;
0062 size_t branches_event_size;
0063 unsigned long num_events;
0064 };
0065
0066 struct intel_bts_queue {
0067 struct intel_bts *bts;
0068 unsigned int queue_nr;
0069 struct auxtrace_buffer *buffer;
0070 bool on_heap;
0071 bool done;
0072 pid_t pid;
0073 pid_t tid;
0074 int cpu;
0075 u64 time;
0076 struct intel_pt_insn intel_pt_insn;
0077 u32 sample_flags;
0078 };
0079
0080 struct branch {
0081 u64 from;
0082 u64 to;
0083 u64 misc;
0084 };
0085
0086 static void intel_bts_dump(struct intel_bts *bts __maybe_unused,
0087 unsigned char *buf, size_t len)
0088 {
0089 struct branch *branch;
0090 size_t i, pos = 0, br_sz = sizeof(struct branch), sz;
0091 const char *color = PERF_COLOR_BLUE;
0092
0093 color_fprintf(stdout, color,
0094 ". ... Intel BTS data: size %zu bytes\n",
0095 len);
0096
0097 while (len) {
0098 if (len >= br_sz)
0099 sz = br_sz;
0100 else
0101 sz = len;
0102 printf(".");
0103 color_fprintf(stdout, color, " %08x: ", pos);
0104 for (i = 0; i < sz; i++)
0105 color_fprintf(stdout, color, " %02x", buf[i]);
0106 for (; i < br_sz; i++)
0107 color_fprintf(stdout, color, " ");
0108 if (len >= br_sz) {
0109 branch = (struct branch *)buf;
0110 color_fprintf(stdout, color, " %"PRIx64" -> %"PRIx64" %s\n",
0111 le64_to_cpu(branch->from),
0112 le64_to_cpu(branch->to),
0113 le64_to_cpu(branch->misc) & 0x10 ?
0114 "pred" : "miss");
0115 } else {
0116 color_fprintf(stdout, color, " Bad record!\n");
0117 }
0118 pos += sz;
0119 buf += sz;
0120 len -= sz;
0121 }
0122 }
0123
0124 static void intel_bts_dump_event(struct intel_bts *bts, unsigned char *buf,
0125 size_t len)
0126 {
0127 printf(".\n");
0128 intel_bts_dump(bts, buf, len);
0129 }
0130
0131 static int intel_bts_lost(struct intel_bts *bts, struct perf_sample *sample)
0132 {
0133 union perf_event event;
0134 int err;
0135
0136 auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE,
0137 INTEL_BTS_ERR_LOST, sample->cpu, sample->pid,
0138 sample->tid, 0, "Lost trace data", sample->time);
0139
0140 err = perf_session__deliver_synth_event(bts->session, &event, NULL);
0141 if (err)
0142 pr_err("Intel BTS: failed to deliver error event, error %d\n",
0143 err);
0144
0145 return err;
0146 }
0147
0148 static struct intel_bts_queue *intel_bts_alloc_queue(struct intel_bts *bts,
0149 unsigned int queue_nr)
0150 {
0151 struct intel_bts_queue *btsq;
0152
0153 btsq = zalloc(sizeof(struct intel_bts_queue));
0154 if (!btsq)
0155 return NULL;
0156
0157 btsq->bts = bts;
0158 btsq->queue_nr = queue_nr;
0159 btsq->pid = -1;
0160 btsq->tid = -1;
0161 btsq->cpu = -1;
0162
0163 return btsq;
0164 }
0165
0166 static int intel_bts_setup_queue(struct intel_bts *bts,
0167 struct auxtrace_queue *queue,
0168 unsigned int queue_nr)
0169 {
0170 struct intel_bts_queue *btsq = queue->priv;
0171
0172 if (list_empty(&queue->head))
0173 return 0;
0174
0175 if (!btsq) {
0176 btsq = intel_bts_alloc_queue(bts, queue_nr);
0177 if (!btsq)
0178 return -ENOMEM;
0179 queue->priv = btsq;
0180
0181 if (queue->cpu != -1)
0182 btsq->cpu = queue->cpu;
0183 btsq->tid = queue->tid;
0184 }
0185
0186 if (bts->sampling_mode)
0187 return 0;
0188
0189 if (!btsq->on_heap && !btsq->buffer) {
0190 int ret;
0191
0192 btsq->buffer = auxtrace_buffer__next(queue, NULL);
0193 if (!btsq->buffer)
0194 return 0;
0195
0196 ret = auxtrace_heap__add(&bts->heap, queue_nr,
0197 btsq->buffer->reference);
0198 if (ret)
0199 return ret;
0200 btsq->on_heap = true;
0201 }
0202
0203 return 0;
0204 }
0205
0206 static int intel_bts_setup_queues(struct intel_bts *bts)
0207 {
0208 unsigned int i;
0209 int ret;
0210
0211 for (i = 0; i < bts->queues.nr_queues; i++) {
0212 ret = intel_bts_setup_queue(bts, &bts->queues.queue_array[i],
0213 i);
0214 if (ret)
0215 return ret;
0216 }
0217 return 0;
0218 }
0219
0220 static inline int intel_bts_update_queues(struct intel_bts *bts)
0221 {
0222 if (bts->queues.new_data) {
0223 bts->queues.new_data = false;
0224 return intel_bts_setup_queues(bts);
0225 }
0226 return 0;
0227 }
0228
0229 static unsigned char *intel_bts_find_overlap(unsigned char *buf_a, size_t len_a,
0230 unsigned char *buf_b, size_t len_b)
0231 {
0232 size_t offs, len;
0233
0234 if (len_a > len_b)
0235 offs = len_a - len_b;
0236 else
0237 offs = 0;
0238
0239 for (; offs < len_a; offs += sizeof(struct branch)) {
0240 len = len_a - offs;
0241 if (!memcmp(buf_a + offs, buf_b, len))
0242 return buf_b + len;
0243 }
0244
0245 return buf_b;
0246 }
0247
0248 static int intel_bts_do_fix_overlap(struct auxtrace_queue *queue,
0249 struct auxtrace_buffer *b)
0250 {
0251 struct auxtrace_buffer *a;
0252 void *start;
0253
0254 if (b->list.prev == &queue->head)
0255 return 0;
0256 a = list_entry(b->list.prev, struct auxtrace_buffer, list);
0257 start = intel_bts_find_overlap(a->data, a->size, b->data, b->size);
0258 if (!start)
0259 return -EINVAL;
0260 b->use_size = b->data + b->size - start;
0261 b->use_data = start;
0262 return 0;
0263 }
0264
0265 static inline u8 intel_bts_cpumode(struct intel_bts *bts, uint64_t ip)
0266 {
0267 return machine__kernel_ip(bts->machine, ip) ?
0268 PERF_RECORD_MISC_KERNEL :
0269 PERF_RECORD_MISC_USER;
0270 }
0271
0272 static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
0273 struct branch *branch)
0274 {
0275 int ret;
0276 struct intel_bts *bts = btsq->bts;
0277 union perf_event event;
0278 struct perf_sample sample = { .ip = 0, };
0279
0280 if (bts->synth_opts.initial_skip &&
0281 bts->num_events++ <= bts->synth_opts.initial_skip)
0282 return 0;
0283
0284 sample.ip = le64_to_cpu(branch->from);
0285 sample.cpumode = intel_bts_cpumode(bts, sample.ip);
0286 sample.pid = btsq->pid;
0287 sample.tid = btsq->tid;
0288 sample.addr = le64_to_cpu(branch->to);
0289 sample.id = btsq->bts->branches_id;
0290 sample.stream_id = btsq->bts->branches_id;
0291 sample.period = 1;
0292 sample.cpu = btsq->cpu;
0293 sample.flags = btsq->sample_flags;
0294 sample.insn_len = btsq->intel_pt_insn.length;
0295 memcpy(sample.insn, btsq->intel_pt_insn.buf, INTEL_PT_INSN_BUF_SZ);
0296
0297 event.sample.header.type = PERF_RECORD_SAMPLE;
0298 event.sample.header.misc = sample.cpumode;
0299 event.sample.header.size = sizeof(struct perf_event_header);
0300
0301 if (bts->synth_opts.inject) {
0302 event.sample.header.size = bts->branches_event_size;
0303 ret = perf_event__synthesize_sample(&event,
0304 bts->branches_sample_type,
0305 0, &sample);
0306 if (ret)
0307 return ret;
0308 }
0309
0310 ret = perf_session__deliver_synth_event(bts->session, &event, &sample);
0311 if (ret)
0312 pr_err("Intel BTS: failed to deliver branch event, error %d\n",
0313 ret);
0314
0315 return ret;
0316 }
0317
0318 static int intel_bts_get_next_insn(struct intel_bts_queue *btsq, u64 ip)
0319 {
0320 struct machine *machine = btsq->bts->machine;
0321 struct thread *thread;
0322 unsigned char buf[INTEL_PT_INSN_BUF_SZ];
0323 ssize_t len;
0324 bool x86_64;
0325 int err = -1;
0326
0327 thread = machine__find_thread(machine, -1, btsq->tid);
0328 if (!thread)
0329 return -1;
0330
0331 len = thread__memcpy(thread, machine, buf, ip, INTEL_PT_INSN_BUF_SZ, &x86_64);
0332 if (len <= 0)
0333 goto out_put;
0334
0335 if (intel_pt_get_insn(buf, len, x86_64, &btsq->intel_pt_insn))
0336 goto out_put;
0337
0338 err = 0;
0339 out_put:
0340 thread__put(thread);
0341 return err;
0342 }
0343
0344 static int intel_bts_synth_error(struct intel_bts *bts, int cpu, pid_t pid,
0345 pid_t tid, u64 ip)
0346 {
0347 union perf_event event;
0348 int err;
0349
0350 auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE,
0351 INTEL_BTS_ERR_NOINSN, cpu, pid, tid, ip,
0352 "Failed to get instruction", 0);
0353
0354 err = perf_session__deliver_synth_event(bts->session, &event, NULL);
0355 if (err)
0356 pr_err("Intel BTS: failed to deliver error event, error %d\n",
0357 err);
0358
0359 return err;
0360 }
0361
0362 static int intel_bts_get_branch_type(struct intel_bts_queue *btsq,
0363 struct branch *branch)
0364 {
0365 int err;
0366
0367 if (!branch->from) {
0368 if (branch->to)
0369 btsq->sample_flags = PERF_IP_FLAG_BRANCH |
0370 PERF_IP_FLAG_TRACE_BEGIN;
0371 else
0372 btsq->sample_flags = 0;
0373 btsq->intel_pt_insn.length = 0;
0374 } else if (!branch->to) {
0375 btsq->sample_flags = PERF_IP_FLAG_BRANCH |
0376 PERF_IP_FLAG_TRACE_END;
0377 btsq->intel_pt_insn.length = 0;
0378 } else {
0379 err = intel_bts_get_next_insn(btsq, branch->from);
0380 if (err) {
0381 btsq->sample_flags = 0;
0382 btsq->intel_pt_insn.length = 0;
0383 if (!btsq->bts->synth_opts.errors)
0384 return 0;
0385 err = intel_bts_synth_error(btsq->bts, btsq->cpu,
0386 btsq->pid, btsq->tid,
0387 branch->from);
0388 return err;
0389 }
0390 btsq->sample_flags = intel_pt_insn_type(btsq->intel_pt_insn.op);
0391
0392 if (!machine__kernel_ip(btsq->bts->machine, branch->from) &&
0393 machine__kernel_ip(btsq->bts->machine, branch->to) &&
0394 btsq->sample_flags != (PERF_IP_FLAG_BRANCH |
0395 PERF_IP_FLAG_CALL |
0396 PERF_IP_FLAG_SYSCALLRET))
0397 btsq->sample_flags = PERF_IP_FLAG_BRANCH |
0398 PERF_IP_FLAG_CALL |
0399 PERF_IP_FLAG_ASYNC |
0400 PERF_IP_FLAG_INTERRUPT;
0401 }
0402
0403 return 0;
0404 }
0405
0406 static int intel_bts_process_buffer(struct intel_bts_queue *btsq,
0407 struct auxtrace_buffer *buffer,
0408 struct thread *thread)
0409 {
0410 struct branch *branch;
0411 size_t sz, bsz = sizeof(struct branch);
0412 u32 filter = btsq->bts->branches_filter;
0413 int err = 0;
0414
0415 if (buffer->use_data) {
0416 sz = buffer->use_size;
0417 branch = buffer->use_data;
0418 } else {
0419 sz = buffer->size;
0420 branch = buffer->data;
0421 }
0422
0423 if (!btsq->bts->sample_branches)
0424 return 0;
0425
0426 for (; sz > bsz; branch += 1, sz -= bsz) {
0427 if (!branch->from && !branch->to)
0428 continue;
0429 intel_bts_get_branch_type(btsq, branch);
0430 if (btsq->bts->synth_opts.thread_stack)
0431 thread_stack__event(thread, btsq->cpu, btsq->sample_flags,
0432 le64_to_cpu(branch->from),
0433 le64_to_cpu(branch->to),
0434 btsq->intel_pt_insn.length,
0435 buffer->buffer_nr + 1, true, 0, 0);
0436 if (filter && !(filter & btsq->sample_flags))
0437 continue;
0438 err = intel_bts_synth_branch_sample(btsq, branch);
0439 if (err)
0440 break;
0441 }
0442 return err;
0443 }
0444
0445 static int intel_bts_process_queue(struct intel_bts_queue *btsq, u64 *timestamp)
0446 {
0447 struct auxtrace_buffer *buffer = btsq->buffer, *old_buffer = buffer;
0448 struct auxtrace_queue *queue;
0449 struct thread *thread;
0450 int err;
0451
0452 if (btsq->done)
0453 return 1;
0454
0455 if (btsq->pid == -1) {
0456 thread = machine__find_thread(btsq->bts->machine, -1,
0457 btsq->tid);
0458 if (thread)
0459 btsq->pid = thread->pid_;
0460 } else {
0461 thread = machine__findnew_thread(btsq->bts->machine, btsq->pid,
0462 btsq->tid);
0463 }
0464
0465 queue = &btsq->bts->queues.queue_array[btsq->queue_nr];
0466
0467 if (!buffer)
0468 buffer = auxtrace_buffer__next(queue, NULL);
0469
0470 if (!buffer) {
0471 if (!btsq->bts->sampling_mode)
0472 btsq->done = 1;
0473 err = 1;
0474 goto out_put;
0475 }
0476
0477
0478 if (buffer->consecutive) {
0479 err = -EINVAL;
0480 goto out_put;
0481 }
0482
0483 if (!buffer->data) {
0484 int fd = perf_data__fd(btsq->bts->session->data);
0485
0486 buffer->data = auxtrace_buffer__get_data(buffer, fd);
0487 if (!buffer->data) {
0488 err = -ENOMEM;
0489 goto out_put;
0490 }
0491 }
0492
0493 if (btsq->bts->snapshot_mode && !buffer->consecutive &&
0494 intel_bts_do_fix_overlap(queue, buffer)) {
0495 err = -ENOMEM;
0496 goto out_put;
0497 }
0498
0499 if (!btsq->bts->synth_opts.callchain &&
0500 !btsq->bts->synth_opts.thread_stack && thread &&
0501 (!old_buffer || btsq->bts->sampling_mode ||
0502 (btsq->bts->snapshot_mode && !buffer->consecutive)))
0503 thread_stack__set_trace_nr(thread, btsq->cpu, buffer->buffer_nr + 1);
0504
0505 err = intel_bts_process_buffer(btsq, buffer, thread);
0506
0507 auxtrace_buffer__drop_data(buffer);
0508
0509 btsq->buffer = auxtrace_buffer__next(queue, buffer);
0510 if (btsq->buffer) {
0511 if (timestamp)
0512 *timestamp = btsq->buffer->reference;
0513 } else {
0514 if (!btsq->bts->sampling_mode)
0515 btsq->done = 1;
0516 }
0517 out_put:
0518 thread__put(thread);
0519 return err;
0520 }
0521
0522 static int intel_bts_flush_queue(struct intel_bts_queue *btsq)
0523 {
0524 u64 ts = 0;
0525 int ret;
0526
0527 while (1) {
0528 ret = intel_bts_process_queue(btsq, &ts);
0529 if (ret < 0)
0530 return ret;
0531 if (ret)
0532 break;
0533 }
0534 return 0;
0535 }
0536
0537 static int intel_bts_process_tid_exit(struct intel_bts *bts, pid_t tid)
0538 {
0539 struct auxtrace_queues *queues = &bts->queues;
0540 unsigned int i;
0541
0542 for (i = 0; i < queues->nr_queues; i++) {
0543 struct auxtrace_queue *queue = &bts->queues.queue_array[i];
0544 struct intel_bts_queue *btsq = queue->priv;
0545
0546 if (btsq && btsq->tid == tid)
0547 return intel_bts_flush_queue(btsq);
0548 }
0549 return 0;
0550 }
0551
0552 static int intel_bts_process_queues(struct intel_bts *bts, u64 timestamp)
0553 {
0554 while (1) {
0555 unsigned int queue_nr;
0556 struct auxtrace_queue *queue;
0557 struct intel_bts_queue *btsq;
0558 u64 ts = 0;
0559 int ret;
0560
0561 if (!bts->heap.heap_cnt)
0562 return 0;
0563
0564 if (bts->heap.heap_array[0].ordinal > timestamp)
0565 return 0;
0566
0567 queue_nr = bts->heap.heap_array[0].queue_nr;
0568 queue = &bts->queues.queue_array[queue_nr];
0569 btsq = queue->priv;
0570
0571 auxtrace_heap__pop(&bts->heap);
0572
0573 ret = intel_bts_process_queue(btsq, &ts);
0574 if (ret < 0) {
0575 auxtrace_heap__add(&bts->heap, queue_nr, ts);
0576 return ret;
0577 }
0578
0579 if (!ret) {
0580 ret = auxtrace_heap__add(&bts->heap, queue_nr, ts);
0581 if (ret < 0)
0582 return ret;
0583 } else {
0584 btsq->on_heap = false;
0585 }
0586 }
0587
0588 return 0;
0589 }
0590
0591 static int intel_bts_process_event(struct perf_session *session,
0592 union perf_event *event,
0593 struct perf_sample *sample,
0594 struct perf_tool *tool)
0595 {
0596 struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts,
0597 auxtrace);
0598 u64 timestamp;
0599 int err;
0600
0601 if (dump_trace)
0602 return 0;
0603
0604 if (!tool->ordered_events) {
0605 pr_err("Intel BTS requires ordered events\n");
0606 return -EINVAL;
0607 }
0608
0609 if (sample->time && sample->time != (u64)-1)
0610 timestamp = perf_time_to_tsc(sample->time, &bts->tc);
0611 else
0612 timestamp = 0;
0613
0614 err = intel_bts_update_queues(bts);
0615 if (err)
0616 return err;
0617
0618 err = intel_bts_process_queues(bts, timestamp);
0619 if (err)
0620 return err;
0621 if (event->header.type == PERF_RECORD_EXIT) {
0622 err = intel_bts_process_tid_exit(bts, event->fork.tid);
0623 if (err)
0624 return err;
0625 }
0626
0627 if (event->header.type == PERF_RECORD_AUX &&
0628 (event->aux.flags & PERF_AUX_FLAG_TRUNCATED) &&
0629 bts->synth_opts.errors)
0630 err = intel_bts_lost(bts, sample);
0631
0632 return err;
0633 }
0634
0635 static int intel_bts_process_auxtrace_event(struct perf_session *session,
0636 union perf_event *event,
0637 struct perf_tool *tool __maybe_unused)
0638 {
0639 struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts,
0640 auxtrace);
0641
0642 if (bts->sampling_mode)
0643 return 0;
0644
0645 if (!bts->data_queued) {
0646 struct auxtrace_buffer *buffer;
0647 off_t data_offset;
0648 int fd = perf_data__fd(session->data);
0649 int err;
0650
0651 if (perf_data__is_pipe(session->data)) {
0652 data_offset = 0;
0653 } else {
0654 data_offset = lseek(fd, 0, SEEK_CUR);
0655 if (data_offset == -1)
0656 return -errno;
0657 }
0658
0659 err = auxtrace_queues__add_event(&bts->queues, session, event,
0660 data_offset, &buffer);
0661 if (err)
0662 return err;
0663
0664
0665 if (dump_trace) {
0666 if (auxtrace_buffer__get_data(buffer, fd)) {
0667 intel_bts_dump_event(bts, buffer->data,
0668 buffer->size);
0669 auxtrace_buffer__put_data(buffer);
0670 }
0671 }
0672 }
0673
0674 return 0;
0675 }
0676
0677 static int intel_bts_flush(struct perf_session *session,
0678 struct perf_tool *tool __maybe_unused)
0679 {
0680 struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts,
0681 auxtrace);
0682 int ret;
0683
0684 if (dump_trace || bts->sampling_mode)
0685 return 0;
0686
0687 if (!tool->ordered_events)
0688 return -EINVAL;
0689
0690 ret = intel_bts_update_queues(bts);
0691 if (ret < 0)
0692 return ret;
0693
0694 return intel_bts_process_queues(bts, MAX_TIMESTAMP);
0695 }
0696
0697 static void intel_bts_free_queue(void *priv)
0698 {
0699 struct intel_bts_queue *btsq = priv;
0700
0701 if (!btsq)
0702 return;
0703 free(btsq);
0704 }
0705
0706 static void intel_bts_free_events(struct perf_session *session)
0707 {
0708 struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts,
0709 auxtrace);
0710 struct auxtrace_queues *queues = &bts->queues;
0711 unsigned int i;
0712
0713 for (i = 0; i < queues->nr_queues; i++) {
0714 intel_bts_free_queue(queues->queue_array[i].priv);
0715 queues->queue_array[i].priv = NULL;
0716 }
0717 auxtrace_queues__free(queues);
0718 }
0719
0720 static void intel_bts_free(struct perf_session *session)
0721 {
0722 struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts,
0723 auxtrace);
0724
0725 auxtrace_heap__free(&bts->heap);
0726 intel_bts_free_events(session);
0727 session->auxtrace = NULL;
0728 free(bts);
0729 }
0730
0731 static bool intel_bts_evsel_is_auxtrace(struct perf_session *session,
0732 struct evsel *evsel)
0733 {
0734 struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts,
0735 auxtrace);
0736
0737 return evsel->core.attr.type == bts->pmu_type;
0738 }
0739
0740 struct intel_bts_synth {
0741 struct perf_tool dummy_tool;
0742 struct perf_session *session;
0743 };
0744
0745 static int intel_bts_event_synth(struct perf_tool *tool,
0746 union perf_event *event,
0747 struct perf_sample *sample __maybe_unused,
0748 struct machine *machine __maybe_unused)
0749 {
0750 struct intel_bts_synth *intel_bts_synth =
0751 container_of(tool, struct intel_bts_synth, dummy_tool);
0752
0753 return perf_session__deliver_synth_event(intel_bts_synth->session,
0754 event, NULL);
0755 }
0756
0757 static int intel_bts_synth_event(struct perf_session *session,
0758 struct perf_event_attr *attr, u64 id)
0759 {
0760 struct intel_bts_synth intel_bts_synth;
0761
0762 memset(&intel_bts_synth, 0, sizeof(struct intel_bts_synth));
0763 intel_bts_synth.session = session;
0764
0765 return perf_event__synthesize_attr(&intel_bts_synth.dummy_tool, attr, 1,
0766 &id, intel_bts_event_synth);
0767 }
0768
0769 static int intel_bts_synth_events(struct intel_bts *bts,
0770 struct perf_session *session)
0771 {
0772 struct evlist *evlist = session->evlist;
0773 struct evsel *evsel;
0774 struct perf_event_attr attr;
0775 bool found = false;
0776 u64 id;
0777 int err;
0778
0779 evlist__for_each_entry(evlist, evsel) {
0780 if (evsel->core.attr.type == bts->pmu_type && evsel->core.ids) {
0781 found = true;
0782 break;
0783 }
0784 }
0785
0786 if (!found) {
0787 pr_debug("There are no selected events with Intel BTS data\n");
0788 return 0;
0789 }
0790
0791 memset(&attr, 0, sizeof(struct perf_event_attr));
0792 attr.size = sizeof(struct perf_event_attr);
0793 attr.type = PERF_TYPE_HARDWARE;
0794 attr.sample_type = evsel->core.attr.sample_type & PERF_SAMPLE_MASK;
0795 attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
0796 PERF_SAMPLE_PERIOD;
0797 attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
0798 attr.sample_type &= ~(u64)PERF_SAMPLE_CPU;
0799 attr.exclude_user = evsel->core.attr.exclude_user;
0800 attr.exclude_kernel = evsel->core.attr.exclude_kernel;
0801 attr.exclude_hv = evsel->core.attr.exclude_hv;
0802 attr.exclude_host = evsel->core.attr.exclude_host;
0803 attr.exclude_guest = evsel->core.attr.exclude_guest;
0804 attr.sample_id_all = evsel->core.attr.sample_id_all;
0805 attr.read_format = evsel->core.attr.read_format;
0806
0807 id = evsel->core.id[0] + 1000000000;
0808 if (!id)
0809 id = 1;
0810
0811 if (bts->synth_opts.branches) {
0812 attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
0813 attr.sample_period = 1;
0814 attr.sample_type |= PERF_SAMPLE_ADDR;
0815 pr_debug("Synthesizing 'branches' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
0816 id, (u64)attr.sample_type);
0817 err = intel_bts_synth_event(session, &attr, id);
0818 if (err) {
0819 pr_err("%s: failed to synthesize 'branches' event type\n",
0820 __func__);
0821 return err;
0822 }
0823 bts->sample_branches = true;
0824 bts->branches_sample_type = attr.sample_type;
0825 bts->branches_id = id;
0826
0827
0828
0829
0830 bts->branches_event_size = sizeof(struct perf_record_sample) +
0831 __evsel__sample_size(attr.sample_type);
0832 }
0833
0834 return 0;
0835 }
0836
0837 static const char * const intel_bts_info_fmts[] = {
0838 [INTEL_BTS_PMU_TYPE] = " PMU Type %"PRId64"\n",
0839 [INTEL_BTS_TIME_SHIFT] = " Time Shift %"PRIu64"\n",
0840 [INTEL_BTS_TIME_MULT] = " Time Muliplier %"PRIu64"\n",
0841 [INTEL_BTS_TIME_ZERO] = " Time Zero %"PRIu64"\n",
0842 [INTEL_BTS_CAP_USER_TIME_ZERO] = " Cap Time Zero %"PRId64"\n",
0843 [INTEL_BTS_SNAPSHOT_MODE] = " Snapshot mode %"PRId64"\n",
0844 };
0845
0846 static void intel_bts_print_info(__u64 *arr, int start, int finish)
0847 {
0848 int i;
0849
0850 if (!dump_trace)
0851 return;
0852
0853 for (i = start; i <= finish; i++)
0854 fprintf(stdout, intel_bts_info_fmts[i], arr[i]);
0855 }
0856
0857 int intel_bts_process_auxtrace_info(union perf_event *event,
0858 struct perf_session *session)
0859 {
0860 struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
0861 size_t min_sz = sizeof(u64) * INTEL_BTS_SNAPSHOT_MODE;
0862 struct intel_bts *bts;
0863 int err;
0864
0865 if (auxtrace_info->header.size < sizeof(struct perf_record_auxtrace_info) +
0866 min_sz)
0867 return -EINVAL;
0868
0869 bts = zalloc(sizeof(struct intel_bts));
0870 if (!bts)
0871 return -ENOMEM;
0872
0873 err = auxtrace_queues__init(&bts->queues);
0874 if (err)
0875 goto err_free;
0876
0877 bts->session = session;
0878 bts->machine = &session->machines.host;
0879 bts->auxtrace_type = auxtrace_info->type;
0880 bts->pmu_type = auxtrace_info->priv[INTEL_BTS_PMU_TYPE];
0881 bts->tc.time_shift = auxtrace_info->priv[INTEL_BTS_TIME_SHIFT];
0882 bts->tc.time_mult = auxtrace_info->priv[INTEL_BTS_TIME_MULT];
0883 bts->tc.time_zero = auxtrace_info->priv[INTEL_BTS_TIME_ZERO];
0884 bts->cap_user_time_zero =
0885 auxtrace_info->priv[INTEL_BTS_CAP_USER_TIME_ZERO];
0886 bts->snapshot_mode = auxtrace_info->priv[INTEL_BTS_SNAPSHOT_MODE];
0887
0888 bts->sampling_mode = false;
0889
0890 bts->auxtrace.process_event = intel_bts_process_event;
0891 bts->auxtrace.process_auxtrace_event = intel_bts_process_auxtrace_event;
0892 bts->auxtrace.flush_events = intel_bts_flush;
0893 bts->auxtrace.free_events = intel_bts_free_events;
0894 bts->auxtrace.free = intel_bts_free;
0895 bts->auxtrace.evsel_is_auxtrace = intel_bts_evsel_is_auxtrace;
0896 session->auxtrace = &bts->auxtrace;
0897
0898 intel_bts_print_info(&auxtrace_info->priv[0], INTEL_BTS_PMU_TYPE,
0899 INTEL_BTS_SNAPSHOT_MODE);
0900
0901 if (dump_trace)
0902 return 0;
0903
0904 if (session->itrace_synth_opts->set) {
0905 bts->synth_opts = *session->itrace_synth_opts;
0906 } else {
0907 itrace_synth_opts__set_default(&bts->synth_opts,
0908 session->itrace_synth_opts->default_no_sample);
0909 bts->synth_opts.thread_stack =
0910 session->itrace_synth_opts->thread_stack;
0911 }
0912
0913 if (bts->synth_opts.calls)
0914 bts->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |
0915 PERF_IP_FLAG_TRACE_END;
0916 if (bts->synth_opts.returns)
0917 bts->branches_filter |= PERF_IP_FLAG_RETURN |
0918 PERF_IP_FLAG_TRACE_BEGIN;
0919
0920 err = intel_bts_synth_events(bts, session);
0921 if (err)
0922 goto err_free_queues;
0923
0924 err = auxtrace_queues__process_index(&bts->queues, session);
0925 if (err)
0926 goto err_free_queues;
0927
0928 if (bts->queues.populated)
0929 bts->data_queued = true;
0930
0931 return 0;
0932
0933 err_free_queues:
0934 auxtrace_queues__free(&bts->queues);
0935 session->auxtrace = NULL;
0936 err_free:
0937 free(bts);
0938 return err;
0939 }