Linux Perf
cs-etm.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright(C) 2015 Linaro Limited. All rights reserved.
4  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
5  */
6 
7 #include <api/fs/fs.h>
8 #include <linux/bitops.h>
9 #include <linux/compiler.h>
10 #include <linux/coresight-pmu.h>
11 #include <linux/kernel.h>
12 #include <linux/log2.h>
13 #include <linux/types.h>
14 
15 #include "cs-etm.h"
16 #include "../../perf.h"
17 #include "../../util/auxtrace.h"
18 #include "../../util/cpumap.h"
19 #include "../../util/evlist.h"
20 #include "../../util/evsel.h"
21 #include "../../util/pmu.h"
22 #include "../../util/thread_map.h"
23 #include "../../util/cs-etm.h"
24 
25 #include <stdlib.h>
26 #include <sys/stat.h>
27 
28 #define ENABLE_SINK_MAX 128
29 #define CS_BUS_DEVICE_PATH "/bus/coresight/devices/"
30 
36  size_t snapshot_size;
37 };
38 
39 static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu);
40 
42  struct record_opts *opts,
43  const char *str)
44 {
45  struct cs_etm_recording *ptr =
46  container_of(itr, struct cs_etm_recording, itr);
47  unsigned long long snapshot_size = 0;
48  char *endptr;
49 
50  if (str) {
51  snapshot_size = strtoull(str, &endptr, 0);
52  if (*endptr || snapshot_size > SIZE_MAX)
53  return -1;
54  }
55 
56  opts->auxtrace_snapshot_mode = true;
59 
60  return 0;
61 }
62 
64  struct perf_evlist *evlist,
65  struct record_opts *opts)
66 {
67  struct cs_etm_recording *ptr =
68  container_of(itr, struct cs_etm_recording, itr);
69  struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
70  struct perf_evsel *evsel, *cs_etm_evsel = NULL;
71  const struct cpu_map *cpus = evlist->cpus;
72  bool privileged = (geteuid() == 0 || perf_event_paranoid() < 0);
73 
74  ptr->evlist = evlist;
76 
77  evlist__for_each_entry(evlist, evsel) {
78  if (evsel->attr.type == cs_etm_pmu->type) {
79  if (cs_etm_evsel) {
80  pr_err("There may be only one %s event\n",
81  CORESIGHT_ETM_PMU_NAME);
82  return -EINVAL;
83  }
84  evsel->attr.freq = 0;
85  evsel->attr.sample_period = 1;
86  cs_etm_evsel = evsel;
87  opts->full_auxtrace = true;
88  }
89  }
90 
91  /* no need to continue if at least one event of interest was found */
92  if (!cs_etm_evsel)
93  return 0;
94 
95  if (opts->use_clockid) {
96  pr_err("Cannot use clockid (-k option) with %s\n",
97  CORESIGHT_ETM_PMU_NAME);
98  return -EINVAL;
99  }
100 
101  /* we are in snapshot mode */
102  if (opts->auxtrace_snapshot_mode) {
103  /*
104  * No size were given to '-S' or '-m,', so go with
105  * the default
106  */
107  if (!opts->auxtrace_snapshot_size &&
108  !opts->auxtrace_mmap_pages) {
109  if (privileged) {
110  opts->auxtrace_mmap_pages = MiB(4) / page_size;
111  } else {
112  opts->auxtrace_mmap_pages =
113  KiB(128) / page_size;
114  if (opts->mmap_pages == UINT_MAX)
115  opts->mmap_pages = KiB(256) / page_size;
116  }
117  } else if (!opts->auxtrace_mmap_pages && !privileged &&
118  opts->mmap_pages == UINT_MAX) {
119  opts->mmap_pages = KiB(256) / page_size;
120  }
121 
122  /*
123  * '-m,xyz' was specified but no snapshot size, so make the
124  * snapshot size as big as the auxtrace mmap area.
125  */
126  if (!opts->auxtrace_snapshot_size) {
127  opts->auxtrace_snapshot_size =
128  opts->auxtrace_mmap_pages * (size_t)page_size;
129  }
130 
131  /*
132  * -Sxyz was specified but no auxtrace mmap area, so make the
133  * auxtrace mmap area big enough to fit the requested snapshot
134  * size.
135  */
136  if (!opts->auxtrace_mmap_pages) {
137  size_t sz = opts->auxtrace_snapshot_size;
138 
139  sz = round_up(sz, page_size) / page_size;
140  opts->auxtrace_mmap_pages = roundup_pow_of_two(sz);
141  }
142 
143  /* Snapshost size can't be bigger than the auxtrace area */
144  if (opts->auxtrace_snapshot_size >
145  opts->auxtrace_mmap_pages * (size_t)page_size) {
146  pr_err("Snapshot size %zu must not be greater than AUX area tracing mmap size %zu\n",
148  opts->auxtrace_mmap_pages * (size_t)page_size);
149  return -EINVAL;
150  }
151 
152  /* Something went wrong somewhere - this shouldn't happen */
153  if (!opts->auxtrace_snapshot_size ||
154  !opts->auxtrace_mmap_pages) {
155  pr_err("Failed to calculate default snapshot size and/or AUX area tracing mmap pages\n");
156  return -EINVAL;
157  }
158  }
159 
160  /* We are in full trace mode but '-m,xyz' wasn't specified */
161  if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) {
162  if (privileged) {
163  opts->auxtrace_mmap_pages = MiB(4) / page_size;
164  } else {
165  opts->auxtrace_mmap_pages = KiB(128) / page_size;
166  if (opts->mmap_pages == UINT_MAX)
167  opts->mmap_pages = KiB(256) / page_size;
168  }
169 
170  }
171 
172  /* Validate auxtrace_mmap_pages provided by user */
173  if (opts->auxtrace_mmap_pages) {
174  unsigned int max_page = (KiB(128) / page_size);
175  size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size;
176 
177  if (!privileged &&
178  opts->auxtrace_mmap_pages > max_page) {
179  opts->auxtrace_mmap_pages = max_page;
180  pr_err("auxtrace too big, truncating to %d\n",
181  max_page);
182  }
183 
184  if (!is_power_of_2(sz)) {
185  pr_err("Invalid mmap size for %s: must be a power of 2\n",
186  CORESIGHT_ETM_PMU_NAME);
187  return -EINVAL;
188  }
189  }
190 
191  if (opts->auxtrace_snapshot_mode)
192  pr_debug2("%s snapshot size: %zu\n", CORESIGHT_ETM_PMU_NAME,
193  opts->auxtrace_snapshot_size);
194 
195  /*
196  * To obtain the auxtrace buffer file descriptor, the auxtrace
197  * event must come first.
198  */
199  perf_evlist__to_front(evlist, cs_etm_evsel);
200 
201  /*
202  * In the case of per-cpu mmaps, we need the CPU on the
203  * AUX event.
204  */
205  if (!cpu_map__empty(cpus))
206  perf_evsel__set_sample_bit(cs_etm_evsel, CPU);
207 
208  /* Add dummy event to keep tracking */
209  if (opts->full_auxtrace) {
210  struct perf_evsel *tracking_evsel;
211  int err;
212 
213  err = parse_events(evlist, "dummy:u", NULL);
214  if (err)
215  return err;
216 
217  tracking_evsel = perf_evlist__last(evlist);
218  perf_evlist__set_tracking_event(evlist, tracking_evsel);
219 
220  tracking_evsel->attr.freq = 0;
221  tracking_evsel->attr.sample_period = 1;
222 
223  /* In per-cpu case, always need the time of mmap events etc */
224  if (!cpu_map__empty(cpus))
225  perf_evsel__set_sample_bit(tracking_evsel, TIME);
226  }
227 
228  return 0;
229 }
230 
232 {
233  u64 config = 0;
234  struct cs_etm_recording *ptr =
235  container_of(itr, struct cs_etm_recording, itr);
236  struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
237  struct perf_evlist *evlist = ptr->evlist;
238  struct perf_evsel *evsel;
239 
240  evlist__for_each_entry(evlist, evsel) {
241  if (evsel->attr.type == cs_etm_pmu->type) {
242  /*
243  * Variable perf_event_attr::config is assigned to
244  * ETMv3/PTM. The bit fields have been made to match
245  * the ETMv3.5 ETRMCR register specification. See the
246  * PMU_FORMAT_ATTR() declarations in
247  * drivers/hwtracing/coresight/coresight-perf.c for
248  * details.
249  */
250  config = evsel->attr.config;
251  break;
252  }
253  }
254 
255  return config;
256 }
257 
258 #ifndef BIT
259 #define BIT(N) (1UL << (N))
260 #endif
261 
263 {
264  u64 config = 0;
265  u64 config_opts = 0;
266 
267  /*
268  * The perf event variable config bits represent both
269  * the command line options and register programming
270  * bits in ETMv3/PTM. For ETMv4 we must remap options
271  * to real bits
272  */
273  config_opts = cs_etm_get_config(itr);
274  if (config_opts & BIT(ETM_OPT_CYCACC))
275  config |= BIT(ETM4_CFG_BIT_CYCACC);
276  if (config_opts & BIT(ETM_OPT_TS))
277  config |= BIT(ETM4_CFG_BIT_TS);
278  if (config_opts & BIT(ETM_OPT_RETSTK))
279  config |= BIT(ETM4_CFG_BIT_RETSTK);
280 
281  return config;
282 }
283 
284 static size_t
286  struct perf_evlist *evlist __maybe_unused)
287 {
288  int i;
289  int etmv3 = 0, etmv4 = 0;
290  struct cpu_map *event_cpus = evlist->cpus;
291  struct cpu_map *online_cpus = cpu_map__new(NULL);
292 
293  /* cpu map is not empty, we have specific CPUs to work with */
294  if (!cpu_map__empty(event_cpus)) {
295  for (i = 0; i < cpu__max_cpu(); i++) {
296  if (!cpu_map__has(event_cpus, i) ||
297  !cpu_map__has(online_cpus, i))
298  continue;
299 
300  if (cs_etm_is_etmv4(itr, i))
301  etmv4++;
302  else
303  etmv3++;
304  }
305  } else {
306  /* get configuration for all CPUs in the system */
307  for (i = 0; i < cpu__max_cpu(); i++) {
308  if (!cpu_map__has(online_cpus, i))
309  continue;
310 
311  if (cs_etm_is_etmv4(itr, i))
312  etmv4++;
313  else
314  etmv3++;
315  }
316  }
317 
318  cpu_map__put(online_cpus);
319 
320  return (CS_ETM_HEADER_SIZE +
321  (etmv4 * CS_ETMV4_PRIV_SIZE) +
322  (etmv3 * CS_ETMV3_PRIV_SIZE));
323 }
324 
325 static const char *metadata_etmv3_ro[CS_ETM_PRIV_MAX] = {
326  [CS_ETM_ETMCCER] = "mgmt/etmccer",
327  [CS_ETM_ETMIDR] = "mgmt/etmidr",
328 };
329 
330 static const char *metadata_etmv4_ro[CS_ETMV4_PRIV_MAX] = {
331  [CS_ETMV4_TRCIDR0] = "trcidr/trcidr0",
332  [CS_ETMV4_TRCIDR1] = "trcidr/trcidr1",
333  [CS_ETMV4_TRCIDR2] = "trcidr/trcidr2",
334  [CS_ETMV4_TRCIDR8] = "trcidr/trcidr8",
335  [CS_ETMV4_TRCAUTHSTATUS] = "mgmt/trcauthstatus",
336 };
337 
338 static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu)
339 {
340  bool ret = false;
341  char path[PATH_MAX];
342  int scan;
343  unsigned int val;
344  struct cs_etm_recording *ptr =
345  container_of(itr, struct cs_etm_recording, itr);
346  struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
347 
348  /* Take any of the RO files for ETMv4 and see if it present */
349  snprintf(path, PATH_MAX, "cpu%d/%s",
351  scan = perf_pmu__scan_file(cs_etm_pmu, path, "%x", &val);
352 
353  /* The file was read successfully, we have a winner */
354  if (scan == 1)
355  ret = true;
356 
357  return ret;
358 }
359 
360 static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu, const char *path)
361 {
362  char pmu_path[PATH_MAX];
363  int scan;
364  unsigned int val = 0;
365 
366  /* Get RO metadata from sysfs */
367  snprintf(pmu_path, PATH_MAX, "cpu%d/%s", cpu, path);
368 
369  scan = perf_pmu__scan_file(pmu, pmu_path, "%x", &val);
370  if (scan != 1)
371  pr_err("%s: error reading: %s\n", __func__, pmu_path);
372 
373  return val;
374 }
375 
376 static void cs_etm_get_metadata(int cpu, u32 *offset,
377  struct auxtrace_record *itr,
378  struct auxtrace_info_event *info)
379 {
380  u32 increment;
381  u64 magic;
382  struct cs_etm_recording *ptr =
383  container_of(itr, struct cs_etm_recording, itr);
384  struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
385 
386  /* first see what kind of tracer this cpu is affined to */
387  if (cs_etm_is_etmv4(itr, cpu)) {
388  magic = __perf_cs_etmv4_magic;
389  /* Get trace configuration register */
390  info->priv[*offset + CS_ETMV4_TRCCONFIGR] =
391  cs_etmv4_get_config(itr);
392  /* Get traceID from the framework */
393  info->priv[*offset + CS_ETMV4_TRCTRACEIDR] =
394  coresight_get_trace_id(cpu);
395  /* Get read-only information from sysFS */
396  info->priv[*offset + CS_ETMV4_TRCIDR0] =
397  cs_etm_get_ro(cs_etm_pmu, cpu,
399  info->priv[*offset + CS_ETMV4_TRCIDR1] =
400  cs_etm_get_ro(cs_etm_pmu, cpu,
402  info->priv[*offset + CS_ETMV4_TRCIDR2] =
403  cs_etm_get_ro(cs_etm_pmu, cpu,
405  info->priv[*offset + CS_ETMV4_TRCIDR8] =
406  cs_etm_get_ro(cs_etm_pmu, cpu,
408  info->priv[*offset + CS_ETMV4_TRCAUTHSTATUS] =
409  cs_etm_get_ro(cs_etm_pmu, cpu,
412 
413  /* How much space was used */
414  increment = CS_ETMV4_PRIV_MAX;
415  } else {
416  magic = __perf_cs_etmv3_magic;
417  /* Get configuration register */
418  info->priv[*offset + CS_ETM_ETMCR] = cs_etm_get_config(itr);
419  /* Get traceID from the framework */
420  info->priv[*offset + CS_ETM_ETMTRACEIDR] =
421  coresight_get_trace_id(cpu);
422  /* Get read-only information from sysFS */
423  info->priv[*offset + CS_ETM_ETMCCER] =
424  cs_etm_get_ro(cs_etm_pmu, cpu,
426  info->priv[*offset + CS_ETM_ETMIDR] =
427  cs_etm_get_ro(cs_etm_pmu, cpu,
429 
430  /* How much space was used */
431  increment = CS_ETM_PRIV_MAX;
432  }
433 
434  /* Build generic header portion */
435  info->priv[*offset + CS_ETM_MAGIC] = magic;
436  info->priv[*offset + CS_ETM_CPU] = cpu;
437  /* Where the next CPU entry should start from */
438  *offset += increment;
439 }
440 
442  struct perf_session *session,
443  struct auxtrace_info_event *info,
444  size_t priv_size)
445 {
446  int i;
447  u32 offset;
448  u64 nr_cpu, type;
449  struct cpu_map *cpu_map;
450  struct cpu_map *event_cpus = session->evlist->cpus;
451  struct cpu_map *online_cpus = cpu_map__new(NULL);
452  struct cs_etm_recording *ptr =
453  container_of(itr, struct cs_etm_recording, itr);
454  struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
455 
456  if (priv_size != cs_etm_info_priv_size(itr, session->evlist))
457  return -EINVAL;
458 
459  if (!session->evlist->nr_mmaps)
460  return -EINVAL;
461 
462  /* If the cpu_map is empty all online CPUs are involved */
463  if (cpu_map__empty(event_cpus)) {
464  cpu_map = online_cpus;
465  } else {
466  /* Make sure all specified CPUs are online */
467  for (i = 0; i < cpu_map__nr(event_cpus); i++) {
468  if (cpu_map__has(event_cpus, i) &&
469  !cpu_map__has(online_cpus, i))
470  return -EINVAL;
471  }
472 
473  cpu_map = event_cpus;
474  }
475 
476  nr_cpu = cpu_map__nr(cpu_map);
477  /* Get PMU type as dynamically assigned by the core */
478  type = cs_etm_pmu->type;
479 
480  /* First fill out the session header */
481  info->type = PERF_AUXTRACE_CS_ETM;
482  info->priv[CS_HEADER_VERSION_0] = 0;
483  info->priv[CS_PMU_TYPE_CPUS] = type << 32;
484  info->priv[CS_PMU_TYPE_CPUS] |= nr_cpu;
485  info->priv[CS_ETM_SNAPSHOT] = ptr->snapshot_mode;
486 
487  offset = CS_ETM_SNAPSHOT + 1;
488 
489  for (i = 0; i < cpu__max_cpu() && offset < priv_size; i++)
490  if (cpu_map__has(cpu_map, i))
491  cs_etm_get_metadata(i, &offset, itr, info);
492 
493  cpu_map__put(online_cpus);
494 
495  return 0;
496 }
497 
498 static int cs_etm_find_snapshot(struct auxtrace_record *itr __maybe_unused,
499  int idx, struct auxtrace_mmap *mm,
500  unsigned char *data __maybe_unused,
501  u64 *head, u64 *old)
502 {
503  pr_debug3("%s: mmap index %d old head %zu new head %zu size %zu\n",
504  __func__, idx, (size_t)*old, (size_t)*head, mm->len);
505 
506  *old = *head;
507  *head += mm->len;
508 
509  return 0;
510 }
511 
513 {
514  struct cs_etm_recording *ptr =
515  container_of(itr, struct cs_etm_recording, itr);
516  struct perf_evsel *evsel;
517 
518  evlist__for_each_entry(ptr->evlist, evsel) {
519  if (evsel->attr.type == ptr->cs_etm_pmu->type)
520  return perf_evsel__disable(evsel);
521  }
522  return -EINVAL;
523 }
524 
526 {
527  struct cs_etm_recording *ptr =
528  container_of(itr, struct cs_etm_recording, itr);
529  struct perf_evsel *evsel;
530 
531  evlist__for_each_entry(ptr->evlist, evsel) {
532  if (evsel->attr.type == ptr->cs_etm_pmu->type)
533  return perf_evsel__enable(evsel);
534  }
535  return -EINVAL;
536 }
537 
538 static u64 cs_etm_reference(struct auxtrace_record *itr __maybe_unused)
539 {
540  return (((u64) rand() << 0) & 0x00000000FFFFFFFFull) |
541  (((u64) rand() << 32) & 0xFFFFFFFF00000000ull);
542 }
543 
545 {
546  struct cs_etm_recording *ptr =
547  container_of(itr, struct cs_etm_recording, itr);
548  free(ptr);
549 }
550 
551 static int cs_etm_read_finish(struct auxtrace_record *itr, int idx)
552 {
553  struct cs_etm_recording *ptr =
554  container_of(itr, struct cs_etm_recording, itr);
555  struct perf_evsel *evsel;
556 
557  evlist__for_each_entry(ptr->evlist, evsel) {
558  if (evsel->attr.type == ptr->cs_etm_pmu->type)
560  evsel, idx);
561  }
562 
563  return -EINVAL;
564 }
565 
567 {
568  struct perf_pmu *cs_etm_pmu;
569  struct cs_etm_recording *ptr;
570 
571  cs_etm_pmu = perf_pmu__find(CORESIGHT_ETM_PMU_NAME);
572 
573  if (!cs_etm_pmu) {
574  *err = -EINVAL;
575  goto out;
576  }
577 
578  ptr = zalloc(sizeof(struct cs_etm_recording));
579  if (!ptr) {
580  *err = -ENOMEM;
581  goto out;
582  }
583 
584  ptr->cs_etm_pmu = cs_etm_pmu;
595 
596  *err = 0;
597  return &ptr->itr;
598 out:
599  return NULL;
600 }
601 
602 static FILE *cs_device__open_file(const char *name)
603 {
604  struct stat st;
605  char path[PATH_MAX];
606  const char *sysfs;
607 
608  sysfs = sysfs__mountpoint();
609  if (!sysfs)
610  return NULL;
611 
612  snprintf(path, PATH_MAX,
613  "%s" CS_BUS_DEVICE_PATH "%s", sysfs, name);
614 
615  if (stat(path, &st) < 0)
616  return NULL;
617 
618  return fopen(path, "w");
619 
620 }
621 
622 static int __printf(2, 3) cs_device__print_file(const char *name, const char *fmt, ...)
623 {
624  va_list args;
625  FILE *file;
626  int ret = -EINVAL;
627 
628  va_start(args, fmt);
629  file = cs_device__open_file(name);
630  if (file) {
631  ret = vfprintf(file, fmt, args);
632  fclose(file);
633  }
634  va_end(args);
635  return ret;
636 }
637 
639 {
640  int ret;
641  char enable_sink[ENABLE_SINK_MAX];
642 
643  snprintf(enable_sink, ENABLE_SINK_MAX, "%s/%s",
644  term->val.drv_cfg, "enable_sink");
645 
646  ret = cs_device__print_file(enable_sink, "%d", 1);
647  if (ret < 0)
648  return ret;
649 
650  return 0;
651 }
size_t auxtrace_snapshot_size
Definition: perf.h:75
#define CS_BUS_DEVICE_PATH
Definition: cs-etm.c:29
struct perf_evlist * evlist
Definition: session.h:25
int(* snapshot_start)(struct auxtrace_record *itr)
Definition: auxtrace.h:318
int cpu__max_cpu(void)
Definition: cpumap.c:517
union perf_evsel_config_term::@112 val
#define CS_ETMV4_PRIV_SIZE
Definition: cs-etm.h:67
static const u64 __perf_cs_etmv3_magic
Definition: cs-etm.h:64
static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu)
Definition: cs-etm.c:338
size_t len
Definition: auxtrace.h:265
#define MiB(x)
Definition: arm-spe.c:24
static int cpu_map__nr(const struct cpu_map *map)
Definition: cpumap.h:53
static u64 cs_etm_get_config(struct auxtrace_record *itr)
Definition: cs-etm.c:231
unsigned int page_size
Definition: util.c:40
dictionary data
Definition: stat-cpi.py:4
bool full_auxtrace
Definition: perf.h:55
int int err
Definition: 5sec.c:44
int(* snapshot_finish)(struct auxtrace_record *itr)
Definition: auxtrace.h:319
int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,...)
Definition: pmu.c:1431
#define config
#define pr_debug2(fmt,...)
Definition: debug.h:33
static const char * metadata_etmv4_ro[CS_ETMV4_PRIV_MAX]
Definition: cs-etm.c:330
size_t(* info_priv_size)(struct auxtrace_record *itr, struct perf_evlist *evlist)
Definition: auxtrace.h:311
static int term(yyscan_t scanner, int type)
#define perf_evsel__set_sample_bit(evsel, bit)
Definition: evsel.h:260
Definition: cpumap.h:12
int perf_evsel__disable(struct perf_evsel *evsel)
Definition: evsel.c:1182
Definition: pmu.h:22
static void cs_etm_recording_free(struct auxtrace_record *itr)
Definition: cs-etm.c:544
#define pr_err(fmt,...)
Definition: json.h:21
#define BIT(N)
Definition: cs-etm.c:259
bool use_clockid
Definition: perf.h:79
#define KiB(x)
Definition: arm-spe.c:23
static const u64 __perf_cs_etmv4_magic
Definition: cs-etm.h:65
static int cs_etm_snapshot_start(struct auxtrace_record *itr)
Definition: cs-etm.c:512
int parse_events(struct perf_evlist *evlist, const char *str, struct parse_events_error *err)
struct auxtrace_record itr
Definition: cs-etm.c:32
struct perf_evlist * evlist
Definition: cs-etm.c:34
void cpu_map__put(struct cpu_map *map)
Definition: cpumap.c:298
void perf_evlist__set_tracking_event(struct perf_evlist *evlist, struct perf_evsel *tracking_evsel)
Definition: evlist.c:1697
static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu, const char *path)
Definition: cs-etm.c:360
int(* read_finish)(struct auxtrace_record *itr, int idx)
Definition: auxtrace.h:327
const char * name
bool snapshot_mode
Definition: cs-etm.c:35
u64(* reference)(struct auxtrace_record *itr)
Definition: auxtrace.h:326
const char * fmt
Definition: dso.c:193
static struct perf_session * session
Definition: builtin-lock.c:34
static int cs_etm_find_snapshot(struct auxtrace_record *itr __maybe_unused, int idx, struct auxtrace_mmap *mm, unsigned char *data __maybe_unused, u64 *head, u64 *old)
Definition: cs-etm.c:498
static void cs_etm_get_metadata(int cpu, u32 *offset, struct auxtrace_record *itr, struct auxtrace_info_event *info)
Definition: cs-etm.c:376
#define evlist__for_each_entry(evlist, evsel)
Definition: evlist.h:247
static bool cpu_map__empty(const struct cpu_map *map)
Definition: cpumap.h:58
size_t snapshot_size
Definition: cs-etm.c:36
struct perf_pmu * cs_etm_pmu
Definition: cs-etm.c:33
void(* free)(struct auxtrace_record *itr)
Definition: auxtrace.h:317
static size_t cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, struct perf_evlist *evlist __maybe_unused)
Definition: cs-etm.c:285
int(* recording_options)(struct auxtrace_record *itr, struct perf_evlist *evlist, struct record_opts *opts)
Definition: auxtrace.h:308
#define PATH_MAX
Definition: jevents.c:1042
static int str(yyscan_t scanner, int token)
list cpus
Definition: stat-cpi.py:7
int cs_etm_set_drv_config(struct perf_evsel_config_term *term)
Definition: cs-etm.c:638
unsigned int mmap_pages
Definition: perf.h:67
#define CPU(he)
void perf_evlist__to_front(struct perf_evlist *evlist, struct perf_evsel *move_evsel)
Definition: evlist.c:1680
static const char * metadata_etmv3_ro[CS_ETM_PRIV_MAX]
Definition: cs-etm.c:325
static int cs_etm_read_finish(struct auxtrace_record *itr, int idx)
Definition: cs-etm.c:551
bool cpu_map__has(struct cpu_map *cpus, int cpu)
Definition: cpumap.c:616
static int __printf(2, 3)
Definition: cs-etm.c:622
int(* parse_snapshot_options)(struct auxtrace_record *itr, struct record_opts *opts, const char *str)
Definition: auxtrace.h:323
int perf_event_paranoid(void)
Definition: util.c:388
static u64 cs_etmv4_get_config(struct auxtrace_record *itr)
Definition: cs-etm.c:262
int nr_mmaps
Definition: evlist.h:32
int(* find_snapshot)(struct auxtrace_record *itr, int idx, struct auxtrace_mmap *mm, unsigned char *data, u64 *head, u64 *old)
Definition: auxtrace.h:320
bool auxtrace_snapshot_mode
Definition: perf.h:56
struct perf_pmu * perf_pmu__find(const char *name)
Definition: pmu.c:778
#define CS_ETMV3_PRIV_SIZE
Definition: cs-etm.h:66
#define CS_ETM_HEADER_SIZE
Definition: cs-etm.h:62
static int cs_etm_info_fill(struct auxtrace_record *itr, struct perf_session *session, struct auxtrace_info_event *info, size_t priv_size)
Definition: cs-etm.c:441
static FILE * cs_device__open_file(const char *name)
Definition: cs-etm.c:602
#define ENABLE_SINK_MAX
Definition: cs-etm.c:28
int perf_evsel__enable(struct perf_evsel *evsel)
Definition: evsel.c:1175
static int cs_etm_snapshot_finish(struct auxtrace_record *itr)
Definition: cs-etm.c:525
void free(void *)
static int cs_etm_parse_snapshot_options(struct auxtrace_record *itr, struct record_opts *opts, const char *str)
Definition: cs-etm.c:41
struct cpu_map * cpus
Definition: evlist.h:48
__u32 type
Definition: pmu.h:24
static struct perf_evsel * perf_evlist__last(struct perf_evlist *evlist)
Definition: evlist.h:220
struct cpu_map * cpu_map__new(const char *cpu_list)
Definition: cpumap.c:125
unsigned int auxtrace_mmap_pages
Definition: perf.h:68
int(* info_fill)(struct auxtrace_record *itr, struct perf_session *session, struct auxtrace_info_event *auxtrace_info, size_t priv_size)
Definition: auxtrace.h:313
struct auxtrace_record * cs_etm_record_init(int *err)
Definition: cs-etm.c:566
static int cs_etm_recording_options(struct auxtrace_record *itr, struct perf_evlist *evlist, struct record_opts *opts)
Definition: cs-etm.c:63
#define pr_debug3(fmt,...)
Definition: debug.h:34
struct perf_event_attr attr
Definition: evsel.h:93
static u64 cs_etm_reference(struct auxtrace_record *itr __maybe_unused)
Definition: cs-etm.c:538
int perf_evlist__enable_event_idx(struct perf_evlist *evlist, struct perf_evsel *evsel, int idx)
Definition: evlist.c:422
void static void * zalloc(size_t size)
Definition: util.h:20