Linux Perf
cs-etm.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright(C) 2015-2018 Linaro Limited.
4  *
5  * Author: Tor Jeremiassen <tor@ti.com>
6  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
7  */
8 
9 #include <linux/bitops.h>
10 #include <linux/err.h>
11 #include <linux/kernel.h>
12 #include <linux/log2.h>
13 #include <linux/types.h>
14 
15 #include <stdlib.h>
16 
17 #include "auxtrace.h"
18 #include "color.h"
19 #include "cs-etm.h"
21 #include "debug.h"
22 #include "evlist.h"
23 #include "intlist.h"
24 #include "machine.h"
25 #include "map.h"
26 #include "perf.h"
27 #include "thread.h"
28 #include "thread_map.h"
29 #include "thread-stack.h"
30 #include "util.h"
31 
32 #define MAX_TIMESTAMP (~0ULL)
33 
34 /*
35  * A64 instructions are always 4 bytes
36  *
37  * Only A64 is supported, so can use this constant for converting between
38  * addresses and instruction counts, calculting offsets etc
39  */
40 #define A64_INSTR_SIZE 4
41 
48  struct machine *machine;
50 
56 
57  int num_cpu;
64  u64 **metadata;
66  unsigned int pmu_type;
67 };
68 
69 struct cs_etm_queue {
71  struct thread *thread;
74  const struct cs_etm_state *state;
76  unsigned int queue_nr;
77  pid_t pid, tid;
78  int cpu;
79  u64 time;
80  u64 timestamp;
81  u64 offset;
88 };
89 
90 static int cs_etm__update_queues(struct cs_etm_auxtrace *etm);
92  pid_t tid, u64 time_);
93 
94 static void cs_etm__packet_dump(const char *pkt_string)
95 {
96  const char *color = PERF_COLOR_BLUE;
97  int len = strlen(pkt_string);
98 
99  if (len && (pkt_string[len-1] == '\n'))
100  color_fprintf(stdout, color, " %s", pkt_string);
101  else
102  color_fprintf(stdout, color, " %s\n", pkt_string);
103 
104  fflush(stdout);
105 }
106 
107 static void cs_etm__dump_event(struct cs_etm_auxtrace *etm,
108  struct auxtrace_buffer *buffer)
109 {
110  int i, ret;
111  const char *color = PERF_COLOR_BLUE;
112  struct cs_etm_decoder_params d_params;
113  struct cs_etm_trace_params *t_params;
114  struct cs_etm_decoder *decoder;
115  size_t buffer_used = 0;
116 
117  fprintf(stdout, "\n");
118  color_fprintf(stdout, color,
119  ". ... CoreSight ETM Trace data: size %zu bytes\n",
120  buffer->size);
121 
122  /* Use metadata to fill in trace parameters for trace decoder */
123  t_params = zalloc(sizeof(*t_params) * etm->num_cpu);
124  for (i = 0; i < etm->num_cpu; i++) {
125  t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
126  t_params[i].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
127  t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
128  t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
129  t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
130  t_params[i].etmv4.reg_configr =
131  etm->metadata[i][CS_ETMV4_TRCCONFIGR];
132  t_params[i].etmv4.reg_traceidr =
134  }
135 
136  /* Set decoder parameters to simply print the trace packets */
139  d_params.formatted = true;
140  d_params.fsyncs = false;
141  d_params.hsyncs = false;
142  d_params.frame_aligned = true;
143 
144  decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params);
145 
146  zfree(&t_params);
147 
148  if (!decoder)
149  return;
150  do {
151  size_t consumed;
152 
154  decoder, buffer->offset,
155  &((u8 *)buffer->data)[buffer_used],
156  buffer->size - buffer_used, &consumed);
157  if (ret)
158  break;
159 
160  buffer_used += consumed;
161  } while (buffer_used < buffer->size);
162 
163  cs_etm_decoder__free(decoder);
164 }
165 
167  struct perf_tool *tool)
168 {
169  int ret;
170  struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
171  struct cs_etm_auxtrace,
172  auxtrace);
173  if (dump_trace)
174  return 0;
175 
176  if (!tool->ordered_events)
177  return -EINVAL;
178 
179  if (!etm->timeless_decoding)
180  return -EINVAL;
181 
182  ret = cs_etm__update_queues(etm);
183 
184  if (ret < 0)
185  return ret;
186 
187  return cs_etm__process_timeless_queues(etm, -1, MAX_TIMESTAMP - 1);
188 }
189 
190 static void cs_etm__free_queue(void *priv)
191 {
192  struct cs_etm_queue *etmq = priv;
193 
194  if (!etmq)
195  return;
196 
197  thread__zput(etmq->thread);
199  zfree(&etmq->event_buf);
200  zfree(&etmq->last_branch);
201  zfree(&etmq->last_branch_rb);
202  zfree(&etmq->prev_packet);
203  zfree(&etmq->packet);
204  free(etmq);
205 }
206 
208 {
209  unsigned int i;
210  struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
211  struct cs_etm_auxtrace,
212  auxtrace);
213  struct auxtrace_queues *queues = &aux->queues;
214 
215  for (i = 0; i < queues->nr_queues; i++) {
216  cs_etm__free_queue(queues->queue_array[i].priv);
217  queues->queue_array[i].priv = NULL;
218  }
219 
220  auxtrace_queues__free(queues);
221 }
222 
223 static void cs_etm__free(struct perf_session *session)
224 {
225  int i;
226  struct int_node *inode, *tmp;
227  struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
228  struct cs_etm_auxtrace,
229  auxtrace);
230  cs_etm__free_events(session);
231  session->auxtrace = NULL;
232 
233  /* First remove all traceID/CPU# nodes for the RB tree */
236  /* Then the RB tree itself */
238 
239  for (i = 0; i < aux->num_cpu; i++)
240  zfree(&aux->metadata[i]);
241 
243  zfree(&aux->metadata);
244  zfree(&aux);
245 }
246 
247 static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u64 address,
248  size_t size, u8 *buffer)
249 {
250  u8 cpumode;
251  u64 offset;
252  int len;
253  struct thread *thread;
254  struct machine *machine;
255  struct addr_location al;
256 
257  if (!etmq)
258  return -1;
259 
260  machine = etmq->etm->machine;
261  if (address >= etmq->etm->kernel_start)
262  cpumode = PERF_RECORD_MISC_KERNEL;
263  else
264  cpumode = PERF_RECORD_MISC_USER;
265 
266  thread = etmq->thread;
267  if (!thread) {
268  if (cpumode != PERF_RECORD_MISC_KERNEL)
269  return -EINVAL;
270  thread = etmq->etm->unknown_thread;
271  }
272 
273  if (!thread__find_map(thread, cpumode, address, &al) || !al.map->dso)
274  return 0;
275 
276  if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
278  return 0;
279 
280  offset = al.map->map_ip(al.map, address);
281 
282  map__load(al.map);
283 
284  len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
285 
286  if (len <= 0)
287  return 0;
288 
289  return len;
290 }
291 
293  unsigned int queue_nr)
294 {
295  int i;
296  struct cs_etm_decoder_params d_params;
297  struct cs_etm_trace_params *t_params;
298  struct cs_etm_queue *etmq;
299  size_t szp = sizeof(struct cs_etm_packet);
300 
301  etmq = zalloc(sizeof(*etmq));
302  if (!etmq)
303  return NULL;
304 
305  etmq->packet = zalloc(szp);
306  if (!etmq->packet)
307  goto out_free;
308 
309  if (etm->synth_opts.last_branch || etm->sample_branches) {
310  etmq->prev_packet = zalloc(szp);
311  if (!etmq->prev_packet)
312  goto out_free;
313  }
314 
315  if (etm->synth_opts.last_branch) {
316  size_t sz = sizeof(struct branch_stack);
317 
318  sz += etm->synth_opts.last_branch_sz *
319  sizeof(struct branch_entry);
320  etmq->last_branch = zalloc(sz);
321  if (!etmq->last_branch)
322  goto out_free;
323  etmq->last_branch_rb = zalloc(sz);
324  if (!etmq->last_branch_rb)
325  goto out_free;
326  }
327 
329  if (!etmq->event_buf)
330  goto out_free;
331 
332  etmq->etm = etm;
333  etmq->queue_nr = queue_nr;
334  etmq->pid = -1;
335  etmq->tid = -1;
336  etmq->cpu = -1;
337 
338  /* Use metadata to fill in trace parameters for trace decoder */
339  t_params = zalloc(sizeof(*t_params) * etm->num_cpu);
340 
341  if (!t_params)
342  goto out_free;
343 
344  for (i = 0; i < etm->num_cpu; i++) {
345  t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
346  t_params[i].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
347  t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
348  t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
349  t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
350  t_params[i].etmv4.reg_configr =
351  etm->metadata[i][CS_ETMV4_TRCCONFIGR];
352  t_params[i].etmv4.reg_traceidr =
354  }
355 
356  /* Set decoder parameters to simply print the trace packets */
359  d_params.formatted = true;
360  d_params.fsyncs = false;
361  d_params.hsyncs = false;
362  d_params.frame_aligned = true;
363  d_params.data = etmq;
364 
365  etmq->decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params);
366 
367  zfree(&t_params);
368 
369  if (!etmq->decoder)
370  goto out_free;
371 
372  /*
373  * Register a function to handle all memory accesses required by
374  * the trace decoder library.
375  */
377  0x0L, ((u64) -1L),
379  goto out_free_decoder;
380 
381  etmq->offset = 0;
382  etmq->period_instructions = 0;
383 
384  return etmq;
385 
386 out_free_decoder:
388 out_free:
389  zfree(&etmq->event_buf);
390  zfree(&etmq->last_branch);
391  zfree(&etmq->last_branch_rb);
392  zfree(&etmq->prev_packet);
393  zfree(&etmq->packet);
394  free(etmq);
395 
396  return NULL;
397 }
398 
399 static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm,
400  struct auxtrace_queue *queue,
401  unsigned int queue_nr)
402 {
403  struct cs_etm_queue *etmq = queue->priv;
404 
405  if (list_empty(&queue->head) || etmq)
406  return 0;
407 
408  etmq = cs_etm__alloc_queue(etm, queue_nr);
409 
410  if (!etmq)
411  return -ENOMEM;
412 
413  queue->priv = etmq;
414 
415  if (queue->cpu != -1)
416  etmq->cpu = queue->cpu;
417 
418  etmq->tid = queue->tid;
419 
420  return 0;
421 }
422 
424 {
425  unsigned int i;
426  int ret;
427 
428  for (i = 0; i < etm->queues.nr_queues; i++) {
429  ret = cs_etm__setup_queue(etm, &etm->queues.queue_array[i], i);
430  if (ret)
431  return ret;
432  }
433 
434  return 0;
435 }
436 
438 {
439  if (etm->queues.new_data) {
440  etm->queues.new_data = false;
441  return cs_etm__setup_queues(etm);
442  }
443 
444  return 0;
445 }
446 
447 static inline void cs_etm__copy_last_branch_rb(struct cs_etm_queue *etmq)
448 {
449  struct branch_stack *bs_src = etmq->last_branch_rb;
450  struct branch_stack *bs_dst = etmq->last_branch;
451  size_t nr = 0;
452 
453  /*
454  * Set the number of records before early exit: ->nr is used to
455  * determine how many branches to copy from ->entries.
456  */
457  bs_dst->nr = bs_src->nr;
458 
459  /*
460  * Early exit when there is nothing to copy.
461  */
462  if (!bs_src->nr)
463  return;
464 
465  /*
466  * As bs_src->entries is a circular buffer, we need to copy from it in
467  * two steps. First, copy the branches from the most recently inserted
468  * branch ->last_branch_pos until the end of bs_src->entries buffer.
469  */
470  nr = etmq->etm->synth_opts.last_branch_sz - etmq->last_branch_pos;
471  memcpy(&bs_dst->entries[0],
472  &bs_src->entries[etmq->last_branch_pos],
473  sizeof(struct branch_entry) * nr);
474 
475  /*
476  * If we wrapped around at least once, the branches from the beginning
477  * of the bs_src->entries buffer and until the ->last_branch_pos element
478  * are older valid branches: copy them over. The total number of
479  * branches copied over will be equal to the number of branches asked by
480  * the user in last_branch_sz.
481  */
482  if (bs_src->nr >= etmq->etm->synth_opts.last_branch_sz) {
483  memcpy(&bs_dst->entries[nr],
484  &bs_src->entries[0],
485  sizeof(struct branch_entry) * etmq->last_branch_pos);
486  }
487 }
488 
489 static inline void cs_etm__reset_last_branch_rb(struct cs_etm_queue *etmq)
490 {
491  etmq->last_branch_pos = 0;
492  etmq->last_branch_rb->nr = 0;
493 }
494 
495 static inline u64 cs_etm__last_executed_instr(struct cs_etm_packet *packet)
496 {
497  /*
498  * The packet records the execution range with an exclusive end address
499  *
500  * A64 instructions are constant size, so the last executed
501  * instruction is A64_INSTR_SIZE before the end address
502  * Will need to do instruction level decode for T32 instructions as
503  * they can be variable size (not yet supported).
504  */
505  return packet->end_addr - A64_INSTR_SIZE;
506 }
507 
508 static inline u64 cs_etm__instr_count(const struct cs_etm_packet *packet)
509 {
510  /*
511  * Only A64 instructions are currently supported, so can get
512  * instruction count by dividing.
513  * Will need to do instruction level decode for T32 instructions as
514  * they can be variable size (not yet supported).
515  */
516  return (packet->end_addr - packet->start_addr) / A64_INSTR_SIZE;
517 }
518 
519 static inline u64 cs_etm__instr_addr(const struct cs_etm_packet *packet,
520  u64 offset)
521 {
522  /*
523  * Only A64 instructions are currently supported, so can get
524  * instruction address by muliplying.
525  * Will need to do instruction level decode for T32 instructions as
526  * they can be variable size (not yet supported).
527  */
528  return packet->start_addr + offset * A64_INSTR_SIZE;
529 }
530 
532 {
533  struct branch_stack *bs = etmq->last_branch_rb;
534  struct branch_entry *be;
535 
536  /*
537  * The branches are recorded in a circular buffer in reverse
538  * chronological order: we start recording from the last element of the
539  * buffer down. After writing the first element of the stack, move the
540  * insert position back to the end of the buffer.
541  */
542  if (!etmq->last_branch_pos)
544 
545  etmq->last_branch_pos -= 1;
546 
547  be = &bs->entries[etmq->last_branch_pos];
549  be->to = etmq->packet->start_addr;
550  /* No support for mispredict */
551  be->flags.mispred = 0;
552  be->flags.predicted = 1;
553 
554  /*
555  * Increment bs->nr until reaching the number of last branches asked by
556  * the user on the command line.
557  */
558  if (bs->nr < etmq->etm->synth_opts.last_branch_sz)
559  bs->nr += 1;
560 }
561 
563  struct perf_sample *sample, u64 type)
564 {
565  event->header.size = perf_event__sample_event_size(sample, type, 0);
566  return perf_event__synthesize_sample(event, type, 0, sample);
567 }
568 
569 
570 static int
571 cs_etm__get_trace(struct cs_etm_buffer *buff, struct cs_etm_queue *etmq)
572 {
573  struct auxtrace_buffer *aux_buffer = etmq->buffer;
574  struct auxtrace_buffer *old_buffer = aux_buffer;
575  struct auxtrace_queue *queue;
576 
577  queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
578 
579  aux_buffer = auxtrace_buffer__next(queue, aux_buffer);
580 
581  /* If no more data, drop the previous auxtrace_buffer and return */
582  if (!aux_buffer) {
583  if (old_buffer)
584  auxtrace_buffer__drop_data(old_buffer);
585  buff->len = 0;
586  return 0;
587  }
588 
589  etmq->buffer = aux_buffer;
590 
591  /* If the aux_buffer doesn't have data associated, try to load it */
592  if (!aux_buffer->data) {
593  /* get the file desc associated with the perf data file */
594  int fd = perf_data__fd(etmq->etm->session->data);
595 
596  aux_buffer->data = auxtrace_buffer__get_data(aux_buffer, fd);
597  if (!aux_buffer->data)
598  return -ENOMEM;
599  }
600 
601  /* If valid, drop the previous buffer */
602  if (old_buffer)
603  auxtrace_buffer__drop_data(old_buffer);
604 
605  buff->offset = aux_buffer->offset;
606  buff->len = aux_buffer->size;
607  buff->buf = aux_buffer->data;
608 
609  buff->ref_timestamp = aux_buffer->reference;
610 
611  return buff->len;
612 }
613 
614 static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm,
615  struct auxtrace_queue *queue)
616 {
617  struct cs_etm_queue *etmq = queue->priv;
618 
619  /* CPU-wide tracing isn't supported yet */
620  if (queue->tid == -1)
621  return;
622 
623  if ((!etmq->thread) && (etmq->tid != -1))
624  etmq->thread = machine__find_thread(etm->machine, -1,
625  etmq->tid);
626 
627  if (etmq->thread) {
628  etmq->pid = etmq->thread->pid_;
629  if (queue->cpu == -1)
630  etmq->cpu = etmq->thread->cpu;
631  }
632 }
633 
635  u64 addr, u64 period)
636 {
637  int ret = 0;
638  struct cs_etm_auxtrace *etm = etmq->etm;
639  union perf_event *event = etmq->event_buf;
640  struct perf_sample sample = {.ip = 0,};
641 
642  event->sample.header.type = PERF_RECORD_SAMPLE;
643  event->sample.header.misc = PERF_RECORD_MISC_USER;
644  event->sample.header.size = sizeof(struct perf_event_header);
645 
646  sample.ip = addr;
647  sample.pid = etmq->pid;
648  sample.tid = etmq->tid;
649  sample.id = etmq->etm->instructions_id;
650  sample.stream_id = etmq->etm->instructions_id;
651  sample.period = period;
652  sample.cpu = etmq->packet->cpu;
653  sample.flags = 0;
654  sample.insn_len = 1;
655  sample.cpumode = event->header.misc;
656 
657  if (etm->synth_opts.last_branch) {
659  sample.branch_stack = etmq->last_branch;
660  }
661 
662  if (etm->synth_opts.inject) {
663  ret = cs_etm__inject_event(event, &sample,
665  if (ret)
666  return ret;
667  }
668 
669  ret = perf_session__deliver_synth_event(etm->session, event, &sample);
670 
671  if (ret)
672  pr_err(
673  "CS ETM Trace: failed to deliver instruction event, error %d\n",
674  ret);
675 
676  if (etm->synth_opts.last_branch)
678 
679  return ret;
680 }
681 
682 /*
683  * The cs etm packet encodes an instruction range between a branch target
684  * and the next taken branch. Generate sample accordingly.
685  */
687 {
688  int ret = 0;
689  struct cs_etm_auxtrace *etm = etmq->etm;
690  struct perf_sample sample = {.ip = 0,};
691  union perf_event *event = etmq->event_buf;
692  struct dummy_branch_stack {
693  u64 nr;
694  struct branch_entry entries;
695  } dummy_bs;
696 
697  event->sample.header.type = PERF_RECORD_SAMPLE;
698  event->sample.header.misc = PERF_RECORD_MISC_USER;
699  event->sample.header.size = sizeof(struct perf_event_header);
700 
702  sample.pid = etmq->pid;
703  sample.tid = etmq->tid;
704  sample.addr = etmq->packet->start_addr;
705  sample.id = etmq->etm->branches_id;
706  sample.stream_id = etmq->etm->branches_id;
707  sample.period = 1;
708  sample.cpu = etmq->packet->cpu;
709  sample.flags = 0;
710  sample.cpumode = PERF_RECORD_MISC_USER;
711 
712  /*
713  * perf report cannot handle events without a branch stack
714  */
715  if (etm->synth_opts.last_branch) {
716  dummy_bs = (struct dummy_branch_stack){
717  .nr = 1,
718  .entries = {
719  .from = sample.ip,
720  .to = sample.addr,
721  },
722  };
723  sample.branch_stack = (struct branch_stack *)&dummy_bs;
724  }
725 
726  if (etm->synth_opts.inject) {
727  ret = cs_etm__inject_event(event, &sample,
728  etm->branches_sample_type);
729  if (ret)
730  return ret;
731  }
732 
733  ret = perf_session__deliver_synth_event(etm->session, event, &sample);
734 
735  if (ret)
736  pr_err(
737  "CS ETM Trace: failed to deliver instruction event, error %d\n",
738  ret);
739 
740  return ret;
741 }
742 
743 struct cs_etm_synth {
744  struct perf_tool dummy_tool;
746 };
747 
748 static int cs_etm__event_synth(struct perf_tool *tool,
749  union perf_event *event,
750  struct perf_sample *sample __maybe_unused,
751  struct machine *machine __maybe_unused)
752 {
753  struct cs_etm_synth *cs_etm_synth =
754  container_of(tool, struct cs_etm_synth, dummy_tool);
755 
756  return perf_session__deliver_synth_event(cs_etm_synth->session,
757  event, NULL);
758 }
759 
761  struct perf_event_attr *attr, u64 id)
762 {
763  struct cs_etm_synth cs_etm_synth;
764 
765  memset(&cs_etm_synth, 0, sizeof(struct cs_etm_synth));
766  cs_etm_synth.session = session;
767 
768  return perf_event__synthesize_attr(&cs_etm_synth.dummy_tool, attr, 1,
769  &id, cs_etm__event_synth);
770 }
771 
772 static int cs_etm__synth_events(struct cs_etm_auxtrace *etm,
773  struct perf_session *session)
774 {
775  struct perf_evlist *evlist = session->evlist;
776  struct perf_evsel *evsel;
777  struct perf_event_attr attr;
778  bool found = false;
779  u64 id;
780  int err;
781 
782  evlist__for_each_entry(evlist, evsel) {
783  if (evsel->attr.type == etm->pmu_type) {
784  found = true;
785  break;
786  }
787  }
788 
789  if (!found) {
790  pr_debug("No selected events with CoreSight Trace data\n");
791  return 0;
792  }
793 
794  memset(&attr, 0, sizeof(struct perf_event_attr));
795  attr.size = sizeof(struct perf_event_attr);
796  attr.type = PERF_TYPE_HARDWARE;
797  attr.sample_type = evsel->attr.sample_type & PERF_SAMPLE_MASK;
798  attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
799  PERF_SAMPLE_PERIOD;
800  if (etm->timeless_decoding)
801  attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
802  else
803  attr.sample_type |= PERF_SAMPLE_TIME;
804 
805  attr.exclude_user = evsel->attr.exclude_user;
806  attr.exclude_kernel = evsel->attr.exclude_kernel;
807  attr.exclude_hv = evsel->attr.exclude_hv;
808  attr.exclude_host = evsel->attr.exclude_host;
809  attr.exclude_guest = evsel->attr.exclude_guest;
810  attr.sample_id_all = evsel->attr.sample_id_all;
811  attr.read_format = evsel->attr.read_format;
812 
813  /* create new id val to be a fixed offset from evsel id */
814  id = evsel->id[0] + 1000000000;
815 
816  if (!id)
817  id = 1;
818 
819  if (etm->synth_opts.branches) {
820  attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
821  attr.sample_period = 1;
822  attr.sample_type |= PERF_SAMPLE_ADDR;
823  err = cs_etm__synth_event(session, &attr, id);
824  if (err)
825  return err;
826  etm->sample_branches = true;
827  etm->branches_sample_type = attr.sample_type;
828  etm->branches_id = id;
829  id += 1;
830  attr.sample_type &= ~(u64)PERF_SAMPLE_ADDR;
831  }
832 
833  if (etm->synth_opts.last_branch)
834  attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
835 
836  if (etm->synth_opts.instructions) {
837  attr.config = PERF_COUNT_HW_INSTRUCTIONS;
838  attr.sample_period = etm->synth_opts.period;
839  etm->instructions_sample_period = attr.sample_period;
840  err = cs_etm__synth_event(session, &attr, id);
841  if (err)
842  return err;
843  etm->sample_instructions = true;
844  etm->instructions_sample_type = attr.sample_type;
845  etm->instructions_id = id;
846  id += 1;
847  }
848 
849  return 0;
850 }
851 
852 static int cs_etm__sample(struct cs_etm_queue *etmq)
853 {
854  struct cs_etm_auxtrace *etm = etmq->etm;
855  struct cs_etm_packet *tmp;
856  int ret;
857  u64 instrs_executed;
858 
859  instrs_executed = cs_etm__instr_count(etmq->packet);
860  etmq->period_instructions += instrs_executed;
861 
862  /*
863  * Record a branch when the last instruction in
864  * PREV_PACKET is a branch.
865  */
866  if (etm->synth_opts.last_branch &&
867  etmq->prev_packet &&
871 
872  if (etm->sample_instructions &&
874  /*
875  * Emit instruction sample periodically
876  * TODO: allow period to be defined in cycles and clock time
877  */
878 
879  /* Get number of instructions executed after the sample point */
880  u64 instrs_over = etmq->period_instructions -
882 
883  /*
884  * Calculate the address of the sampled instruction (-1 as
885  * sample is reported as though instruction has just been
886  * executed, but PC has not advanced to next instruction)
887  */
888  u64 offset = (instrs_executed - instrs_over - 1);
889  u64 addr = cs_etm__instr_addr(etmq->packet, offset);
890 
892  etmq, addr, etm->instructions_sample_period);
893  if (ret)
894  return ret;
895 
896  /* Carry remaining instructions into next sample period */
897  etmq->period_instructions = instrs_over;
898  }
899 
900  if (etm->sample_branches &&
901  etmq->prev_packet &&
904  ret = cs_etm__synth_branch_sample(etmq);
905  if (ret)
906  return ret;
907  }
908 
909  if (etm->sample_branches || etm->synth_opts.last_branch) {
910  /*
911  * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for
912  * the next incoming packet.
913  */
914  tmp = etmq->packet;
915  etmq->packet = etmq->prev_packet;
916  etmq->prev_packet = tmp;
917  }
918 
919  return 0;
920 }
921 
922 static int cs_etm__flush(struct cs_etm_queue *etmq)
923 {
924  int err = 0;
925  struct cs_etm_packet *tmp;
926 
927  if (etmq->etm->synth_opts.last_branch &&
928  etmq->prev_packet &&
930  /*
931  * Generate a last branch event for the branches left in the
932  * circular buffer at the end of the trace.
933  *
934  * Use the address of the end of the last reported execution
935  * range
936  */
937  u64 addr = cs_etm__last_executed_instr(etmq->prev_packet);
938 
940  etmq, addr,
941  etmq->period_instructions);
942  etmq->period_instructions = 0;
943 
944  /*
945  * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for
946  * the next incoming packet.
947  */
948  tmp = etmq->packet;
949  etmq->packet = etmq->prev_packet;
950  etmq->prev_packet = tmp;
951  }
952 
953  return err;
954 }
955 
956 static int cs_etm__run_decoder(struct cs_etm_queue *etmq)
957 {
958  struct cs_etm_auxtrace *etm = etmq->etm;
959  struct cs_etm_buffer buffer;
960  size_t buffer_used, processed;
961  int err = 0;
962 
963  if (!etm->kernel_start)
965 
966  /* Go through each buffer in the queue and decode them one by one */
967  while (1) {
968  buffer_used = 0;
969  memset(&buffer, 0, sizeof(buffer));
970  err = cs_etm__get_trace(&buffer, etmq);
971  if (err <= 0)
972  return err;
973  /*
974  * We cannot assume consecutive blocks in the data file are
975  * contiguous, reset the decoder to force re-sync.
976  */
977  err = cs_etm_decoder__reset(etmq->decoder);
978  if (err != 0)
979  return err;
980 
981  /* Run trace decoder until buffer consumed or end of trace */
982  do {
983  processed = 0;
985  etmq->decoder,
986  etmq->offset,
987  &buffer.buf[buffer_used],
988  buffer.len - buffer_used,
989  &processed);
990  if (err)
991  return err;
992 
993  etmq->offset += processed;
994  buffer_used += processed;
995 
996  /* Process each packet in this chunk */
997  while (1) {
999  etmq->packet);
1000  if (err <= 0)
1001  /*
1002  * Stop processing this chunk on
1003  * end of data or error
1004  */
1005  break;
1006 
1007  switch (etmq->packet->sample_type) {
1008  case CS_ETM_RANGE:
1009  /*
1010  * If the packet contains an instruction
1011  * range, generate instruction sequence
1012  * events.
1013  */
1014  cs_etm__sample(etmq);
1015  break;
1016  case CS_ETM_TRACE_ON:
1017  /*
1018  * Discontinuity in trace, flush
1019  * previous branch stack
1020  */
1021  cs_etm__flush(etmq);
1022  break;
1023  default:
1024  break;
1025  }
1026  }
1027  } while (buffer.len > buffer_used);
1028 
1029  if (err == 0)
1030  /* Flush any remaining branch stack entries */
1031  err = cs_etm__flush(etmq);
1032  }
1033 
1034  return err;
1035 }
1036 
1038  pid_t tid, u64 time_)
1039 {
1040  unsigned int i;
1041  struct auxtrace_queues *queues = &etm->queues;
1042 
1043  for (i = 0; i < queues->nr_queues; i++) {
1044  struct auxtrace_queue *queue = &etm->queues.queue_array[i];
1045  struct cs_etm_queue *etmq = queue->priv;
1046 
1047  if (etmq && ((tid == -1) || (etmq->tid == tid))) {
1048  etmq->time = time_;
1049  cs_etm__set_pid_tid_cpu(etm, queue);
1050  cs_etm__run_decoder(etmq);
1051  }
1052  }
1053 
1054  return 0;
1055 }
1056 
1058  union perf_event *event,
1059  struct perf_sample *sample,
1060  struct perf_tool *tool)
1061 {
1062  int err = 0;
1063  u64 timestamp;
1064  struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
1065  struct cs_etm_auxtrace,
1066  auxtrace);
1067 
1068  if (dump_trace)
1069  return 0;
1070 
1071  if (!tool->ordered_events) {
1072  pr_err("CoreSight ETM Trace requires ordered events\n");
1073  return -EINVAL;
1074  }
1075 
1076  if (!etm->timeless_decoding)
1077  return -EINVAL;
1078 
1079  if (sample->time && (sample->time != (u64) -1))
1080  timestamp = sample->time;
1081  else
1082  timestamp = 0;
1083 
1084  if (timestamp || etm->timeless_decoding) {
1085  err = cs_etm__update_queues(etm);
1086  if (err)
1087  return err;
1088  }
1089 
1090  if (event->header.type == PERF_RECORD_EXIT)
1092  event->fork.tid,
1093  sample->time);
1094 
1095  return 0;
1096 }
1097 
1099  union perf_event *event,
1100  struct perf_tool *tool __maybe_unused)
1101 {
1102  struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
1103  struct cs_etm_auxtrace,
1104  auxtrace);
1105  if (!etm->data_queued) {
1106  struct auxtrace_buffer *buffer;
1107  off_t data_offset;
1108  int fd = perf_data__fd(session->data);
1109  bool is_pipe = perf_data__is_pipe(session->data);
1110  int err;
1111 
1112  if (is_pipe)
1113  data_offset = 0;
1114  else {
1115  data_offset = lseek(fd, 0, SEEK_CUR);
1116  if (data_offset == -1)
1117  return -errno;
1118  }
1119 
1120  err = auxtrace_queues__add_event(&etm->queues, session,
1121  event, data_offset, &buffer);
1122  if (err)
1123  return err;
1124 
1125  if (dump_trace)
1126  if (auxtrace_buffer__get_data(buffer, fd)) {
1127  cs_etm__dump_event(etm, buffer);
1128  auxtrace_buffer__put_data(buffer);
1129  }
1130  }
1131 
1132  return 0;
1133 }
1134 
1136 {
1137  struct perf_evsel *evsel;
1138  struct perf_evlist *evlist = etm->session->evlist;
1139  bool timeless_decoding = true;
1140 
1141  /*
1142  * Circle through the list of event and complain if we find one
1143  * with the time bit set.
1144  */
1145  evlist__for_each_entry(evlist, evsel) {
1146  if ((evsel->attr.sample_type & PERF_SAMPLE_TIME))
1147  timeless_decoding = false;
1148  }
1149 
1150  return timeless_decoding;
1151 }
1152 
1153 static const char * const cs_etm_global_header_fmts[] = {
1154  [CS_HEADER_VERSION_0] = " Header version %llx\n",
1155  [CS_PMU_TYPE_CPUS] = " PMU type/num cpus %llx\n",
1156  [CS_ETM_SNAPSHOT] = " Snapshot %llx\n",
1157 };
1158 
1159 static const char * const cs_etm_priv_fmts[] = {
1160  [CS_ETM_MAGIC] = " Magic number %llx\n",
1161  [CS_ETM_CPU] = " CPU %lld\n",
1162  [CS_ETM_ETMCR] = " ETMCR %llx\n",
1163  [CS_ETM_ETMTRACEIDR] = " ETMTRACEIDR %llx\n",
1164  [CS_ETM_ETMCCER] = " ETMCCER %llx\n",
1165  [CS_ETM_ETMIDR] = " ETMIDR %llx\n",
1166 };
1167 
1168 static const char * const cs_etmv4_priv_fmts[] = {
1169  [CS_ETM_MAGIC] = " Magic number %llx\n",
1170  [CS_ETM_CPU] = " CPU %lld\n",
1171  [CS_ETMV4_TRCCONFIGR] = " TRCCONFIGR %llx\n",
1172  [CS_ETMV4_TRCTRACEIDR] = " TRCTRACEIDR %llx\n",
1173  [CS_ETMV4_TRCIDR0] = " TRCIDR0 %llx\n",
1174  [CS_ETMV4_TRCIDR1] = " TRCIDR1 %llx\n",
1175  [CS_ETMV4_TRCIDR2] = " TRCIDR2 %llx\n",
1176  [CS_ETMV4_TRCIDR8] = " TRCIDR8 %llx\n",
1177  [CS_ETMV4_TRCAUTHSTATUS] = " TRCAUTHSTATUS %llx\n",
1178 };
1179 
1180 static void cs_etm__print_auxtrace_info(u64 *val, int num)
1181 {
1182  int i, j, cpu = 0;
1183 
1184  for (i = 0; i < CS_HEADER_VERSION_0_MAX; i++)
1185  fprintf(stdout, cs_etm_global_header_fmts[i], val[i]);
1186 
1187  for (i = CS_HEADER_VERSION_0_MAX; cpu < num; cpu++) {
1188  if (val[i] == __perf_cs_etmv3_magic)
1189  for (j = 0; j < CS_ETM_PRIV_MAX; j++, i++)
1190  fprintf(stdout, cs_etm_priv_fmts[j], val[i]);
1191  else if (val[i] == __perf_cs_etmv4_magic)
1192  for (j = 0; j < CS_ETMV4_PRIV_MAX; j++, i++)
1193  fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]);
1194  else
1195  /* failure.. return */
1196  return;
1197  }
1198 }
1199 
1201  struct perf_session *session)
1202 {
1203  struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info;
1204  struct cs_etm_auxtrace *etm = NULL;
1205  struct int_node *inode;
1206  unsigned int pmu_type;
1207  int event_header_size = sizeof(struct perf_event_header);
1208  int info_header_size;
1209  int total_size = auxtrace_info->header.size;
1210  int priv_size = 0;
1211  int num_cpu;
1212  int err = 0, idx = -1;
1213  int i, j, k;
1214  u64 *ptr, *hdr = NULL;
1215  u64 **metadata = NULL;
1216 
1217  /*
1218  * sizeof(auxtrace_info_event::type) +
1219  * sizeof(auxtrace_info_event::reserved) == 8
1220  */
1221  info_header_size = 8;
1222 
1223  if (total_size < (event_header_size + info_header_size))
1224  return -EINVAL;
1225 
1226  priv_size = total_size - event_header_size - info_header_size;
1227 
1228  /* First the global part */
1229  ptr = (u64 *) auxtrace_info->priv;
1230 
1231  /* Look for version '0' of the header */
1232  if (ptr[0] != 0)
1233  return -EINVAL;
1234 
1235  hdr = zalloc(sizeof(*hdr) * CS_HEADER_VERSION_0_MAX);
1236  if (!hdr)
1237  return -ENOMEM;
1238 
1239  /* Extract header information - see cs-etm.h for format */
1240  for (i = 0; i < CS_HEADER_VERSION_0_MAX; i++)
1241  hdr[i] = ptr[i];
1242  num_cpu = hdr[CS_PMU_TYPE_CPUS] & 0xffffffff;
1243  pmu_type = (unsigned int) ((hdr[CS_PMU_TYPE_CPUS] >> 32) &
1244  0xffffffff);
1245 
1246  /*
1247  * Create an RB tree for traceID-CPU# tuple. Since the conversion has
1248  * to be made for each packet that gets decoded, optimizing access in
1249  * anything other than a sequential array is worth doing.
1250  */
1251  traceid_list = intlist__new(NULL);
1252  if (!traceid_list) {
1253  err = -ENOMEM;
1254  goto err_free_hdr;
1255  }
1256 
1257  metadata = zalloc(sizeof(*metadata) * num_cpu);
1258  if (!metadata) {
1259  err = -ENOMEM;
1260  goto err_free_traceid_list;
1261  }
1262 
1263  /*
1264  * The metadata is stored in the auxtrace_info section and encodes
1265  * the configuration of the ARM embedded trace macrocell which is
1266  * required by the trace decoder to properly decode the trace due
1267  * to its highly compressed nature.
1268  */
1269  for (j = 0; j < num_cpu; j++) {
1270  if (ptr[i] == __perf_cs_etmv3_magic) {
1271  metadata[j] = zalloc(sizeof(*metadata[j]) *
1272  CS_ETM_PRIV_MAX);
1273  if (!metadata[j]) {
1274  err = -ENOMEM;
1275  goto err_free_metadata;
1276  }
1277  for (k = 0; k < CS_ETM_PRIV_MAX; k++)
1278  metadata[j][k] = ptr[i + k];
1279 
1280  /* The traceID is our handle */
1281  idx = metadata[j][CS_ETM_ETMTRACEIDR];
1282  i += CS_ETM_PRIV_MAX;
1283  } else if (ptr[i] == __perf_cs_etmv4_magic) {
1284  metadata[j] = zalloc(sizeof(*metadata[j]) *
1286  if (!metadata[j]) {
1287  err = -ENOMEM;
1288  goto err_free_metadata;
1289  }
1290  for (k = 0; k < CS_ETMV4_PRIV_MAX; k++)
1291  metadata[j][k] = ptr[i + k];
1292 
1293  /* The traceID is our handle */
1294  idx = metadata[j][CS_ETMV4_TRCTRACEIDR];
1295  i += CS_ETMV4_PRIV_MAX;
1296  }
1297 
1298  /* Get an RB node for this CPU */
1299  inode = intlist__findnew(traceid_list, idx);
1300 
1301  /* Something went wrong, no need to continue */
1302  if (!inode) {
1303  err = PTR_ERR(inode);
1304  goto err_free_metadata;
1305  }
1306 
1307  /*
1308  * The node for that CPU should not be taken.
1309  * Back out if that's the case.
1310  */
1311  if (inode->priv) {
1312  err = -EINVAL;
1313  goto err_free_metadata;
1314  }
1315  /* All good, associate the traceID with the CPU# */
1316  inode->priv = &metadata[j][CS_ETM_CPU];
1317  }
1318 
1319  /*
1320  * Each of CS_HEADER_VERSION_0_MAX, CS_ETM_PRIV_MAX and
1321  * CS_ETMV4_PRIV_MAX mark how many double words are in the
1322  * global metadata, and each cpu's metadata respectively.
1323  * The following tests if the correct number of double words was
1324  * present in the auxtrace info section.
1325  */
1326  if (i * 8 != priv_size) {
1327  err = -EINVAL;
1328  goto err_free_metadata;
1329  }
1330 
1331  etm = zalloc(sizeof(*etm));
1332 
1333  if (!etm) {
1334  err = -ENOMEM;
1335  goto err_free_metadata;
1336  }
1337 
1338  err = auxtrace_queues__init(&etm->queues);
1339  if (err)
1340  goto err_free_etm;
1341 
1342  etm->session = session;
1343  etm->machine = &session->machines.host;
1344 
1345  etm->num_cpu = num_cpu;
1346  etm->pmu_type = pmu_type;
1347  etm->snapshot_mode = (hdr[CS_ETM_SNAPSHOT] != 0);
1348  etm->metadata = metadata;
1349  etm->auxtrace_type = auxtrace_info->type;
1351 
1356  etm->auxtrace.free = cs_etm__free;
1357  session->auxtrace = &etm->auxtrace;
1358 
1359  etm->unknown_thread = thread__new(999999999, 999999999);
1360  if (!etm->unknown_thread)
1361  goto err_free_queues;
1362 
1363  /*
1364  * Initialize list node so that at thread__zput() we can avoid
1365  * segmentation fault at list_del_init().
1366  */
1367  INIT_LIST_HEAD(&etm->unknown_thread->node);
1368 
1369  err = thread__set_comm(etm->unknown_thread, "unknown", 0);
1370  if (err)
1371  goto err_delete_thread;
1372 
1374  goto err_delete_thread;
1375 
1376  if (dump_trace) {
1377  cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu);
1378  return 0;
1379  }
1380 
1381  if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
1382  etm->synth_opts = *session->itrace_synth_opts;
1383  } else {
1385  etm->synth_opts.callchain = false;
1386  }
1387 
1388  err = cs_etm__synth_events(etm, session);
1389  if (err)
1390  goto err_delete_thread;
1391 
1392  err = auxtrace_queues__process_index(&etm->queues, session);
1393  if (err)
1394  goto err_delete_thread;
1395 
1396  etm->data_queued = etm->queues.populated;
1397 
1398  return 0;
1399 
1400 err_delete_thread:
1402 err_free_queues:
1404  session->auxtrace = NULL;
1405 err_free_etm:
1406  zfree(&etm);
1407 err_free_metadata:
1408  /* No need to check @metadata[j], free(NULL) is supported */
1409  for (j = 0; j < num_cpu; j++)
1410  free(metadata[j]);
1411  zfree(&metadata);
1412 err_free_traceid_list:
1414 err_free_hdr:
1415  zfree(&hdr);
1416 
1417  return -EINVAL;
1418 }
u64 period_instructions
Definition: cs-etm.c:82
int color_fprintf(FILE *fp, const char *color, const char *fmt,...)
Definition: color.c:123
u64(* map_ip)(struct map *, u64)
Definition: map.h:41
static int cs_etm__flush(struct cs_etm_queue *etmq)
Definition: cs-etm.c:922
struct perf_evlist * evlist
Definition: session.h:25
struct perf_data * data
Definition: session.h:36
int(* process_event)(struct perf_session *session, union perf_event *event, struct perf_sample *sample, struct perf_tool *tool)
Definition: auxtrace.h:139
struct perf_tool dummy_tool
Definition: cs-etm.c:744
void(* packet_printer)(const char *msg)
void * priv
Definition: intlist.h:13
int cpu
Definition: cs-etm.c:78
static u64 cs_etm__instr_addr(const struct cs_etm_packet *packet, u64 offset)
Definition: cs-etm.c:519
#define intlist__for_each_entry_safe(pos, n, ilist)
Definition: intlist.h:75
struct perf_event_header header
Definition: event.h:504
static int cs_etm__run_decoder(struct cs_etm_queue *etmq)
Definition: cs-etm.c:956
static const u64 __perf_cs_etmv3_magic
Definition: cs-etm.h:64
static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm)
Definition: cs-etm.c:1135
pid_t pid_
Definition: thread.h:24
int auxtrace_queues__process_index(struct auxtrace_queues *queues, struct perf_session *session)
Definition: auxtrace.c:764
size_t size
Definition: evsel.c:60
u32 tid
Definition: event.h:53
struct dso::@70 data
struct perf_session * session
Definition: cs-etm.c:745
void * auxtrace_buffer__get_data(struct auxtrace_buffer *buffer, int fd)
Definition: auxtrace.c:804
struct auxtrace_queue * queue_array
Definition: auxtrace.h:219
struct itrace_synth_opts synth_opts
Definition: cs-etm.c:46
struct machine host
Definition: machine.h:136
struct auxtrace * auxtrace
Definition: session.h:26
#define thread__zput(thread)
Definition: thread.h:64
struct auxtrace auxtrace
Definition: cs-etm.c:43
u64 addr
Definition: event.h:195
void intlist__delete(struct intlist *ilist)
Definition: intlist.c:130
static void cs_etm__free_queue(void *priv)
Definition: cs-etm.c:190
u16 insn_len
Definition: event.h:206
static int cs_etm__process_auxtrace_event(struct perf_session *session, union perf_event *event, struct perf_tool *tool __maybe_unused)
Definition: cs-etm.c:1098
static int cs_etm__sample(struct cs_etm_queue *etmq)
Definition: cs-etm.c:852
static int cs_etm__get_trace(struct cs_etm_buffer *buff, struct cs_etm_queue *etmq)
Definition: cs-etm.c:571
static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq, u64 addr, u64 period)
Definition: cs-etm.c:634
u8 sample_branches
Definition: cs-etm.c:54
int perf_session__deliver_synth_event(struct perf_session *session, union perf_event *event, struct perf_sample *sample)
Definition: session.c:1413
struct map * thread__find_map(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al)
Definition: event.c:1511
int int err
Definition: 5sec.c:44
u64 nr
Definition: event.h:157
struct perf_session * session
Definition: cs-etm.c:47
struct auxtrace_buffer * auxtrace_buffer__next(struct auxtrace_queue *queue, struct auxtrace_buffer *buffer)
Definition: auxtrace.c:788
static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq)
Definition: cs-etm.c:531
#define A64_INSTR_SIZE
Definition: cs-etm.c:40
struct itrace_synth_opts * itrace_synth_opts
Definition: session.h:27
struct list_head node
Definition: thread.h:21
void * priv
Definition: auxtrace.h:207
u64 instructions_sample_period
Definition: cs-etm.c:62
u64 from
Definition: event.h:151
int auxtrace_queues__add_event(struct auxtrace_queues *queues, struct perf_session *session, union perf_event *event, off_t data_offset, struct auxtrace_buffer **buffer_ptr)
Definition: auxtrace.c:357
static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq)
Definition: cs-etm.c:686
u64 offset
Definition: cs-etm.c:81
enum cs_etm_sample_type sample_type
struct auxtrace_buffer * buffer
Definition: cs-etm.c:73
unsigned int queue_nr
Definition: cs-etm.c:76
static int cs_etm__event_synth(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused)
Definition: cs-etm.c:748
struct cs_etmv4_trace_params etmv4
u64 ip
Definition: event.h:192
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
#define pr_err(fmt,...)
Definition: json.h:21
u8 timeless_decoding
Definition: cs-etm.c:51
int thread__init_map_groups(struct thread *thread, struct machine *machine)
Definition: thread.c:19
static u64 cs_etm__instr_count(const struct cs_etm_packet *packet)
Definition: cs-etm.c:508
static const u64 __perf_cs_etmv4_magic
Definition: cs-etm.h:65
unsigned int nr_queues
Definition: auxtrace.h:220
u32 auxtrace_type
Definition: cs-etm.c:58
struct branch_entry entries[0]
Definition: event.h:158
u64 id
Definition: event.h:196
void * malloc(YYSIZE_T)
if(!yyg->yy_init)
struct thread * machine__find_thread(struct machine *machine, pid_t pid, pid_t tid)
Definition: machine.c:504
struct map * map
Definition: symbol.h:210
static void cs_etm__free(struct perf_session *session)
Definition: cs-etm.c:223
Definition: thread.h:18
static void cs_etm__print_auxtrace_info(u64 *val, int num)
Definition: cs-etm.c:1180
struct cs_etm_packet * packet
Definition: cs-etm.c:87
int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format, const struct perf_sample *sample)
Definition: evsel.c:2490
static void cs_etm__packet_dump(const char *pkt_string)
Definition: cs-etm.c:94
#define PERF_COLOR_BLUE
Definition: color.h:16
#define pr_debug(fmt,...)
Definition: json.h:27
Definition: tool.h:44
pid_t pid
Definition: cs-etm.c:77
static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm, pid_t tid, u64 time_)
Definition: cs-etm.c:1037
void intlist__remove(struct intlist *ilist, struct int_node *node)
Definition: intlist.c:56
static const char *const cs_etm_global_header_fmts[]
Definition: cs-etm.c:1153
#define evlist__for_each_entry(evlist, evsel)
Definition: evlist.h:247
int cs_etm_decoder__reset(struct cs_etm_decoder *decoder)
void auxtrace_buffer__put_data(struct auxtrace_buffer *buffer)
Definition: auxtrace.c:826
int cpu
Definition: thread.h:27
struct dso * dso
Definition: map.h:45
size_t last_branch_pos
Definition: cs-etm.c:85
u8 snapshot_mode
Definition: cs-etm.c:52
struct int_node * intlist__findnew(struct intlist *ilist, int i)
Definition: intlist.c:86
void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts)
Definition: auxtrace.c:961
static int cs_etm__synth_events(struct cs_etm_auxtrace *etm, struct perf_session *session)
Definition: cs-etm.c:772
static struct perf_tool tool
Definition: builtin-diff.c:362
u64 period
Definition: event.h:198
u64 predicted
Definition: event.h:142
static int cs_etm__inject_event(union perf_event *event, struct perf_sample *sample, u64 type)
Definition: cs-etm.c:562
u32 pid
Definition: event.h:193
int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder, u64 start, u64 end, cs_etm_mem_cb_type cb_func)
u32 tid
Definition: event.h:193
u64 kernel_start
Definition: cs-etm.c:65
#define MAX_TIMESTAMP
Definition: cs-etm.c:32
unsigned long long period
Definition: auxtrace.h:98
static int cs_etm__setup_queues(struct cs_etm_auxtrace *etm)
Definition: cs-etm.c:423
bool ordered_events
Definition: tool.h:76
u8 last_instr_taken_branch
static const char *const cs_etmv4_priv_fmts[]
Definition: cs-etm.c:1168
void auxtrace_buffer__drop_data(struct auxtrace_buffer *buffer)
Definition: auxtrace.c:837
#define event
struct cs_etm_decoder * cs_etm_decoder__new(int num_cpu, struct cs_etm_decoder_params *d_params, struct cs_etm_trace_params t_params[])
struct fork_event fork
Definition: event.h:629
struct branch_stack * branch_stack
Definition: event.h:212
u32 cpu
Definition: event.h:201
struct cs_etm_decoder * decoder
Definition: cs-etm.c:72
struct list_head head
Definition: auxtrace.h:203
u64 ** metadata
Definition: cs-etm.c:64
static int perf_data__fd(struct perf_data *data)
Definition: data.h:40
x86 movsq based memcpy() in arch/x86/lib/memcpy_64.S") MEMCPY_FN(memcpy_erms
int cs_etm_decoder__process_data_block(struct cs_etm_decoder *decoder, u64 indx, const u8 *buf, size_t len, size_t *consumed)
off_t data_offset
Definition: auxtrace.h:182
union perf_event * event_buf
Definition: cs-etm.c:75
#define zfree(ptr)
Definition: util.h:25
unsigned int last_branch_sz
Definition: auxtrace.h:97
const struct cs_etm_state * state
Definition: cs-etm.c:74
static int cs_etm__process_event(struct perf_session *session, union perf_event *event, struct perf_sample *sample, struct perf_tool *tool)
Definition: cs-etm.c:1057
int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process)
Definition: header.c:3348
u8 sample_instructions
Definition: cs-etm.c:55
struct perf_event_header header
Definition: event.h:624
Definition: event.h:150
u32 pid
Definition: hists_common.c:15
static int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp)
Definition: thread.h:77
struct intlist * intlist__new(const char *slist)
Definition: intlist.c:110
static int perf_data__is_pipe(struct perf_data *data)
Definition: data.h:35
struct auxtrace_heap heap
Definition: cs-etm.c:45
u64 instructions_id
Definition: cs-etm.c:63
void(* free_events)(struct perf_session *session)
Definition: auxtrace.h:148
struct auxtrace_queues queues
Definition: cs-etm.c:44
struct thread * thread
Definition: cs-etm.c:71
int(* flush_events)(struct perf_session *session, struct perf_tool *tool)
Definition: auxtrace.h:146
static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm, struct auxtrace_queue *queue, unsigned int queue_nr)
Definition: cs-etm.c:399
struct branch_stack * last_branch
Definition: cs-etm.c:83
int status
Definition: dso.h:183
u64 instructions_sample_type
Definition: cs-etm.c:61
unsigned int pmu_type
Definition: cs-etm.c:66
u32 flags
Definition: event.h:205
static int cs_etm__update_queues(struct cs_etm_auxtrace *etm)
Definition: cs-etm.c:437
u64 time
Definition: event.h:194
static const char *const cs_etm_priv_fmts[]
Definition: cs-etm.c:1159
struct thread * thread__new(pid_t pid, pid_t tid)
Definition: thread.c:36
size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format)
Definition: evsel.c:2382
#define PERF_SAMPLE_MASK
Definition: event.h:87
#define PERF_SAMPLE_MAX_SIZE
Definition: event.h:95
static u64 cs_etm__last_executed_instr(struct cs_etm_packet *packet)
Definition: cs-etm.c:495
bool dump_trace
Definition: debug.c:27
void auxtrace_queues__free(struct auxtrace_queues *queues)
Definition: auxtrace.c:404
u64 timestamp
Definition: cs-etm.c:80
void free(void *)
static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u64 address, size_t size, u8 *buffer)
Definition: cs-etm.c:247
u64 time
Definition: cs-etm.c:79
static int cs_etm__flush_events(struct perf_session *session, struct perf_tool *tool)
Definition: cs-etm.c:166
pid_t tid
Definition: cs-etm.c:77
u8 data_queued
Definition: cs-etm.c:53
Definition: attr.py:1
u64 branches_sample_type
Definition: cs-etm.c:59
struct intlist * traceid_list
Definition: cs-etm.h:57
ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, u64 offset, u8 *data, ssize_t size)
Definition: dso.c:986
struct cs_etm_auxtrace * etm
Definition: cs-etm.c:70
void(* free)(struct perf_session *session)
Definition: auxtrace.h:149
int auxtrace_queues__init(struct auxtrace_queues *queues)
Definition: auxtrace.c:173
u64 stream_id
Definition: event.h:197
void cs_etm_decoder__free(struct cs_etm_decoder *decoder)
int map__load(struct map *map)
Definition: map.c:307
struct machine * machine
Definition: cs-etm.c:48
static u64 machine__kernel_start(struct machine *machine)
Definition: machine.h:88
int cs_etm__process_auxtrace_info(union perf_event *event, struct perf_session *session)
Definition: cs-etm.c:1200
int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder, struct cs_etm_packet *packet)
u8 cpumode
Definition: event.h:207
u64 * id
Definition: evsel.h:97
static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm, struct auxtrace_queue *queue)
Definition: cs-etm.c:614
struct machines machines
Definition: session.h:24
u64 to
Definition: event.h:152
static void cs_etm__copy_last_branch_rb(struct cs_etm_queue *etmq)
Definition: cs-etm.c:447
struct perf_event_attr attr
Definition: evsel.h:93
struct cs_etm_packet * prev_packet
Definition: cs-etm.c:86
u64 branches_id
Definition: cs-etm.c:60
static struct cs_etm_queue * cs_etm__alloc_queue(struct cs_etm_auxtrace *etm, unsigned int queue_nr)
Definition: cs-etm.c:292
const unsigned char * buf
static int cs_etm__synth_event(struct perf_session *session, struct perf_event_attr *attr, u64 id)
Definition: cs-etm.c:760
struct branch_flags flags
Definition: event.h:153
static void cs_etm__dump_event(struct cs_etm_auxtrace *etm, struct auxtrace_buffer *buffer)
Definition: cs-etm.c:107
struct branch_stack * last_branch_rb
Definition: cs-etm.c:84
bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by)
Definition: dso.c:699
static void cs_etm__free_events(struct perf_session *session)
Definition: cs-etm.c:207
u64 mispred
Definition: event.h:141
int(* process_auxtrace_event)(struct perf_session *session, union perf_event *event, struct perf_tool *tool)
Definition: auxtrace.h:143
void static void * zalloc(size_t size)
Definition: util.h:20
static void cs_etm__reset_last_branch_rb(struct cs_etm_queue *etmq)
Definition: cs-etm.c:489
struct thread * unknown_thread
Definition: cs-etm.c:49