Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * intel-bts.c: Intel Processor Trace support
0004  * Copyright (c) 2013-2015, Intel Corporation.
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         /* Check for an async branch into the kernel */
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     /* Currently there is no support for split buffers */
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         /* Dump here now we have copied a piped trace out of the pipe */
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          * We only use sample types from PERF_SAMPLE_MASK so we can use
0828          * __evsel__sample_size() here.
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; /* No kvm support */
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 }