evsel.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __LIBPERF_INTERNAL_EVSEL_H
  3. #define __LIBPERF_INTERNAL_EVSEL_H
  4. #include <linux/types.h>
  5. #include <linux/perf_event.h>
  6. #include <stdbool.h>
  7. #include <sys/types.h>
  8. #include <internal/cpumap.h>
  9. struct perf_thread_map;
  10. struct xyarray;
  11. /**
  12. * The per-thread accumulated period storage node.
  13. */
  14. struct perf_sample_id_period {
  15. struct list_head node;
  16. struct hlist_node hnode;
  17. /* Holds total ID period value for PERF_SAMPLE_READ processing. */
  18. u64 period;
  19. /* The TID that the values belongs to */
  20. u32 tid;
  21. };
  22. /**
  23. * perf_evsel_for_each_per_thread_period_safe - safely iterate thru all the
  24. * per_stream_periods
  25. * @evlist:perf_evsel instance to iterate
  26. * @item: struct perf_sample_id_period iterator
  27. * @tmp: struct perf_sample_id_period temp iterator
  28. */
  29. #define perf_evsel_for_each_per_thread_period_safe(evsel, tmp, item) \
  30. list_for_each_entry_safe(item, tmp, &(evsel)->per_stream_periods, node)
  31. #define PERF_SAMPLE_ID__HLIST_BITS 4
  32. #define PERF_SAMPLE_ID__HLIST_SIZE (1 << PERF_SAMPLE_ID__HLIST_BITS)
  33. /*
  34. * Per fd, to map back from PERF_SAMPLE_ID to evsel, only used when there are
  35. * more than one entry in the evlist.
  36. */
  37. struct perf_sample_id {
  38. struct hlist_node node;
  39. u64 id;
  40. struct perf_evsel *evsel;
  41. /*
  42. * 'idx' will be used for AUX area sampling. A sample will have AUX area
  43. * data that will be queued for decoding, where there are separate
  44. * queues for each CPU (per-cpu tracing) or task (per-thread tracing).
  45. * The sample ID can be used to lookup 'idx' which is effectively the
  46. * queue number.
  47. */
  48. int idx;
  49. struct perf_cpu cpu;
  50. pid_t tid;
  51. /* Guest machine pid and VCPU, valid only if machine_pid is non-zero */
  52. pid_t machine_pid;
  53. struct perf_cpu vcpu;
  54. /*
  55. * Per-thread, and global event counts are mutually exclusive:
  56. * Whilst it is possible to combine events into a group with differing
  57. * values of PERF_SAMPLE_READ, it is not valid to have inconsistent
  58. * values for `inherit`. Therefore it is not possible to have a
  59. * situation where a per-thread event is sampled as a global event;
  60. * all !inherit groups are global, and all groups where the sampling
  61. * event is inherit + PERF_SAMPLE_READ will be per-thread. Any event
  62. * that is part of such a group that is inherit but not PERF_SAMPLE_READ
  63. * will be read as per-thread. If such an event can also trigger a
  64. * sample (such as with sample_period > 0) then it will not cause
  65. * `read_format` to be included in its PERF_RECORD_SAMPLE, and
  66. * therefore will not expose the per-thread group members as global.
  67. */
  68. union {
  69. /*
  70. * Holds total ID period value for PERF_SAMPLE_READ processing
  71. * (when period is not per-thread).
  72. */
  73. u64 period;
  74. /*
  75. * Holds total ID period value for PERF_SAMPLE_READ processing
  76. * (when period is per-thread).
  77. */
  78. struct hlist_head periods[PERF_SAMPLE_ID__HLIST_SIZE];
  79. };
  80. };
  81. struct perf_evsel {
  82. struct list_head node;
  83. struct perf_event_attr attr;
  84. /** The commonly used cpu map of CPUs the event should be opened upon, etc. */
  85. struct perf_cpu_map *cpus;
  86. /**
  87. * The cpu map read from the PMU. For core PMUs this is the list of all
  88. * CPUs the event can be opened upon. For other PMUs this is the default
  89. * cpu map for opening the event on, for example, the first CPU on a
  90. * socket for an uncore event.
  91. */
  92. struct perf_cpu_map *pmu_cpus;
  93. struct perf_thread_map *threads;
  94. struct xyarray *fd;
  95. struct xyarray *mmap;
  96. struct xyarray *sample_id;
  97. u64 *id;
  98. u32 ids;
  99. struct perf_evsel *leader;
  100. /* For events where the read_format value is per-thread rather than
  101. * global, stores the per-thread cumulative period */
  102. struct list_head per_stream_periods;
  103. /* parse modifier helper */
  104. int nr_members;
  105. /*
  106. * system_wide is for events that need to be on every CPU, irrespective
  107. * of user requested CPUs or threads. Tha main example of this is the
  108. * dummy event. Map propagation will set cpus for this event to all CPUs
  109. * as software PMU events like dummy, have a CPU map that is empty.
  110. */
  111. bool system_wide;
  112. /*
  113. * Some events, for example uncore events, require a CPU.
  114. * i.e. it cannot be the 'any CPU' value of -1.
  115. */
  116. bool requires_cpu;
  117. /** Is the PMU for the event a core one? Effects the handling of own_cpus. */
  118. bool is_pmu_core;
  119. /** Does the evsel on read on the first CPU index such as tool time events? */
  120. bool reads_only_on_cpu_idx0;
  121. int idx;
  122. };
  123. void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr,
  124. int idx);
  125. void perf_evsel__exit(struct perf_evsel *evsel);
  126. int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
  127. void perf_evsel__close_fd(struct perf_evsel *evsel);
  128. void perf_evsel__free_fd(struct perf_evsel *evsel);
  129. int perf_evsel__read_size(struct perf_evsel *evsel);
  130. int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter);
  131. int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
  132. void perf_evsel__free_id(struct perf_evsel *evsel);
  133. bool perf_evsel__attr_has_per_thread_sample_period(struct perf_evsel *evsel);
  134. u64 *perf_sample_id__get_period_storage(struct perf_sample_id *sid, u32 tid,
  135. bool per_thread);
  136. #endif /* __LIBPERF_INTERNAL_EVSEL_H */