xref: /aosp_15_r20/external/perfetto/src/profiling/perf/event_config.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #ifndef SRC_PROFILING_PERF_EVENT_CONFIG_H_
18*6dbdd20aSAndroid Build Coastguard Worker #define SRC_PROFILING_PERF_EVENT_CONFIG_H_
19*6dbdd20aSAndroid Build Coastguard Worker 
20*6dbdd20aSAndroid Build Coastguard Worker #include <cinttypes>
21*6dbdd20aSAndroid Build Coastguard Worker #include <functional>
22*6dbdd20aSAndroid Build Coastguard Worker #include <string>
23*6dbdd20aSAndroid Build Coastguard Worker #include <vector>
24*6dbdd20aSAndroid Build Coastguard Worker 
25*6dbdd20aSAndroid Build Coastguard Worker #include <linux/perf_event.h>
26*6dbdd20aSAndroid Build Coastguard Worker #include <stdint.h>
27*6dbdd20aSAndroid Build Coastguard Worker #include <sys/types.h>
28*6dbdd20aSAndroid Build Coastguard Worker #include <optional>
29*6dbdd20aSAndroid Build Coastguard Worker 
30*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/flat_set.h"
31*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/core/data_source_config.h"
32*6dbdd20aSAndroid Build Coastguard Worker 
33*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/common/perf_events.gen.h"
34*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
35*6dbdd20aSAndroid Build Coastguard Worker 
36*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
37*6dbdd20aSAndroid Build Coastguard Worker namespace protos {
38*6dbdd20aSAndroid Build Coastguard Worker namespace gen {
39*6dbdd20aSAndroid Build Coastguard Worker class PerfEventConfig;
40*6dbdd20aSAndroid Build Coastguard Worker }  // namespace gen
41*6dbdd20aSAndroid Build Coastguard Worker }  // namespace protos
42*6dbdd20aSAndroid Build Coastguard Worker 
43*6dbdd20aSAndroid Build Coastguard Worker namespace profiling {
44*6dbdd20aSAndroid Build Coastguard Worker 
45*6dbdd20aSAndroid Build Coastguard Worker // Callstack sampling parameter for unwinding only a fraction of seen processes
46*6dbdd20aSAndroid Build Coastguard Worker // (without enumerating them in the config).
47*6dbdd20aSAndroid Build Coastguard Worker struct ProcessSharding {
48*6dbdd20aSAndroid Build Coastguard Worker   uint32_t shard_count = 0;
49*6dbdd20aSAndroid Build Coastguard Worker   uint32_t chosen_shard = 0;
50*6dbdd20aSAndroid Build Coastguard Worker };
51*6dbdd20aSAndroid Build Coastguard Worker 
52*6dbdd20aSAndroid Build Coastguard Worker // Parsed allow/deny-list for filtering samples.
53*6dbdd20aSAndroid Build Coastguard Worker // An empty allow-list means that all targets are allowed unless explicitly
54*6dbdd20aSAndroid Build Coastguard Worker // denied.
55*6dbdd20aSAndroid Build Coastguard Worker struct TargetFilter {
56*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> cmdlines;
57*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> exclude_cmdlines;
58*6dbdd20aSAndroid Build Coastguard Worker   base::FlatSet<pid_t> pids;
59*6dbdd20aSAndroid Build Coastguard Worker   base::FlatSet<pid_t> exclude_pids;
60*6dbdd20aSAndroid Build Coastguard Worker   std::optional<ProcessSharding> process_sharding;
61*6dbdd20aSAndroid Build Coastguard Worker   uint32_t additional_cmdline_count = 0;
62*6dbdd20aSAndroid Build Coastguard Worker };
63*6dbdd20aSAndroid Build Coastguard Worker 
64*6dbdd20aSAndroid Build Coastguard Worker // Describes a perf event for two purposes:
65*6dbdd20aSAndroid Build Coastguard Worker // * encoding the event in the perf_event_open syscall
66*6dbdd20aSAndroid Build Coastguard Worker // * echoing the counter's config in the trace packet defaults, so that the
67*6dbdd20aSAndroid Build Coastguard Worker //   parser can tell which datastream belongs to which counter.
68*6dbdd20aSAndroid Build Coastguard Worker // Note: It's slightly odd to decode & pass around values we don't use outside
69*6dbdd20aSAndroid Build Coastguard Worker // of reencoding back into a defaults proto. One option would be to carry the
70*6dbdd20aSAndroid Build Coastguard Worker // Timebase proto, but this won't fit with the eventual support of multiple
71*6dbdd20aSAndroid Build Coastguard Worker // counters, as at the proto level it'll be a distinct message from Timebase.
72*6dbdd20aSAndroid Build Coastguard Worker struct PerfCounter {
73*6dbdd20aSAndroid Build Coastguard Worker   enum class Type { kBuiltinCounter, kTracepoint, kRawEvent };
74*6dbdd20aSAndroid Build Coastguard Worker 
75*6dbdd20aSAndroid Build Coastguard Worker   Type type = Type::kBuiltinCounter;
76*6dbdd20aSAndroid Build Coastguard Worker 
77*6dbdd20aSAndroid Build Coastguard Worker   // Optional config-supplied name for the counter, to identify it during
78*6dbdd20aSAndroid Build Coastguard Worker   // trace parsing, does not affect the syscall.
79*6dbdd20aSAndroid Build Coastguard Worker   std::string name;
80*6dbdd20aSAndroid Build Coastguard Worker 
81*6dbdd20aSAndroid Build Coastguard Worker   // valid if kBuiltinCounter
82*6dbdd20aSAndroid Build Coastguard Worker   protos::gen::PerfEvents::Counter counter =
83*6dbdd20aSAndroid Build Coastguard Worker       protos::gen::PerfEvents::PerfEvents::UNKNOWN_COUNTER;
84*6dbdd20aSAndroid Build Coastguard Worker   // valid if kTracepoint. Example: "sched:sched_switch".
85*6dbdd20aSAndroid Build Coastguard Worker   std::string tracepoint_name;
86*6dbdd20aSAndroid Build Coastguard Worker   // valid if kTracepoint
87*6dbdd20aSAndroid Build Coastguard Worker   std::string tracepoint_filter;
88*6dbdd20aSAndroid Build Coastguard Worker 
89*6dbdd20aSAndroid Build Coastguard Worker   // sycall-level description of the event (perf_event_attr):
90*6dbdd20aSAndroid Build Coastguard Worker   uint32_t attr_type = 0;
91*6dbdd20aSAndroid Build Coastguard Worker   uint64_t attr_config = 0;
92*6dbdd20aSAndroid Build Coastguard Worker   uint64_t attr_config1 = 0;  // optional extension
93*6dbdd20aSAndroid Build Coastguard Worker   uint64_t attr_config2 = 0;  // optional extension
94*6dbdd20aSAndroid Build Coastguard Worker 
event_typePerfCounter95*6dbdd20aSAndroid Build Coastguard Worker   Type event_type() const { return type; }
96*6dbdd20aSAndroid Build Coastguard Worker 
97*6dbdd20aSAndroid Build Coastguard Worker   static PerfCounter BuiltinCounter(std::string name,
98*6dbdd20aSAndroid Build Coastguard Worker                                     protos::gen::PerfEvents::Counter counter,
99*6dbdd20aSAndroid Build Coastguard Worker                                     uint32_t type,
100*6dbdd20aSAndroid Build Coastguard Worker                                     uint64_t config);
101*6dbdd20aSAndroid Build Coastguard Worker 
102*6dbdd20aSAndroid Build Coastguard Worker   static PerfCounter Tracepoint(std::string name,
103*6dbdd20aSAndroid Build Coastguard Worker                                 std::string tracepoint_name,
104*6dbdd20aSAndroid Build Coastguard Worker                                 std::string tracepoint_filter,
105*6dbdd20aSAndroid Build Coastguard Worker                                 uint64_t id);
106*6dbdd20aSAndroid Build Coastguard Worker 
107*6dbdd20aSAndroid Build Coastguard Worker   static PerfCounter RawEvent(std::string name,
108*6dbdd20aSAndroid Build Coastguard Worker                               uint32_t type,
109*6dbdd20aSAndroid Build Coastguard Worker                               uint64_t config,
110*6dbdd20aSAndroid Build Coastguard Worker                               uint64_t config1,
111*6dbdd20aSAndroid Build Coastguard Worker                               uint64_t config2);
112*6dbdd20aSAndroid Build Coastguard Worker };
113*6dbdd20aSAndroid Build Coastguard Worker 
114*6dbdd20aSAndroid Build Coastguard Worker // Describes a single profiling configuration. Bridges the gap between the data
115*6dbdd20aSAndroid Build Coastguard Worker // source config proto, and the raw "perf_event_attr" structs to pass to the
116*6dbdd20aSAndroid Build Coastguard Worker // perf_event_open syscall.
117*6dbdd20aSAndroid Build Coastguard Worker class EventConfig {
118*6dbdd20aSAndroid Build Coastguard Worker  public:
119*6dbdd20aSAndroid Build Coastguard Worker   using tracepoint_id_fn_t =
120*6dbdd20aSAndroid Build Coastguard Worker       std::function<uint32_t(const std::string&, const std::string&)>;
121*6dbdd20aSAndroid Build Coastguard Worker 
122*6dbdd20aSAndroid Build Coastguard Worker   static std::optional<EventConfig> Create(
123*6dbdd20aSAndroid Build Coastguard Worker       const protos::gen::PerfEventConfig& pb_config,
124*6dbdd20aSAndroid Build Coastguard Worker       const DataSourceConfig& raw_ds_config,
125*6dbdd20aSAndroid Build Coastguard Worker       std::optional<ProcessSharding> process_sharding,
126*6dbdd20aSAndroid Build Coastguard Worker       tracepoint_id_fn_t tracepoint_id_lookup);
127*6dbdd20aSAndroid Build Coastguard Worker 
ring_buffer_pages()128*6dbdd20aSAndroid Build Coastguard Worker   uint32_t ring_buffer_pages() const { return ring_buffer_pages_; }
read_tick_period_ms()129*6dbdd20aSAndroid Build Coastguard Worker   uint32_t read_tick_period_ms() const { return read_tick_period_ms_; }
samples_per_tick_limit()130*6dbdd20aSAndroid Build Coastguard Worker   uint64_t samples_per_tick_limit() const { return samples_per_tick_limit_; }
remote_descriptor_timeout_ms()131*6dbdd20aSAndroid Build Coastguard Worker   uint32_t remote_descriptor_timeout_ms() const {
132*6dbdd20aSAndroid Build Coastguard Worker     return remote_descriptor_timeout_ms_;
133*6dbdd20aSAndroid Build Coastguard Worker   }
unwind_state_clear_period_ms()134*6dbdd20aSAndroid Build Coastguard Worker   uint32_t unwind_state_clear_period_ms() const {
135*6dbdd20aSAndroid Build Coastguard Worker     return unwind_state_clear_period_ms_;
136*6dbdd20aSAndroid Build Coastguard Worker   }
max_enqueued_footprint_bytes()137*6dbdd20aSAndroid Build Coastguard Worker   uint64_t max_enqueued_footprint_bytes() const {
138*6dbdd20aSAndroid Build Coastguard Worker     return max_enqueued_footprint_bytes_;
139*6dbdd20aSAndroid Build Coastguard Worker   }
sample_callstacks()140*6dbdd20aSAndroid Build Coastguard Worker   bool sample_callstacks() const { return user_frames() || kernel_frames_; }
user_frames()141*6dbdd20aSAndroid Build Coastguard Worker   bool user_frames() const { return IsUserFramesEnabled(unwind_mode_); }
kernel_frames()142*6dbdd20aSAndroid Build Coastguard Worker   bool kernel_frames() const { return kernel_frames_; }
unwind_mode()143*6dbdd20aSAndroid Build Coastguard Worker   protos::gen::PerfEventConfig::UnwindMode unwind_mode() const {
144*6dbdd20aSAndroid Build Coastguard Worker     return unwind_mode_;
145*6dbdd20aSAndroid Build Coastguard Worker   }
filter()146*6dbdd20aSAndroid Build Coastguard Worker   const TargetFilter& filter() const { return target_filter_; }
perf_attr()147*6dbdd20aSAndroid Build Coastguard Worker   perf_event_attr* perf_attr() const {
148*6dbdd20aSAndroid Build Coastguard Worker     return const_cast<perf_event_attr*>(&perf_event_attr_);
149*6dbdd20aSAndroid Build Coastguard Worker   }
perf_attr_followers()150*6dbdd20aSAndroid Build Coastguard Worker   const std::vector<perf_event_attr>& perf_attr_followers() const {
151*6dbdd20aSAndroid Build Coastguard Worker     return perf_event_followers_;
152*6dbdd20aSAndroid Build Coastguard Worker   }
timebase_event()153*6dbdd20aSAndroid Build Coastguard Worker   const PerfCounter& timebase_event() const { return timebase_event_; }
154*6dbdd20aSAndroid Build Coastguard Worker 
follower_events()155*6dbdd20aSAndroid Build Coastguard Worker   const std::vector<PerfCounter>& follower_events() const {
156*6dbdd20aSAndroid Build Coastguard Worker     return follower_events_;
157*6dbdd20aSAndroid Build Coastguard Worker   }
158*6dbdd20aSAndroid Build Coastguard Worker 
target_installed_by()159*6dbdd20aSAndroid Build Coastguard Worker   const std::vector<std::string>& target_installed_by() const {
160*6dbdd20aSAndroid Build Coastguard Worker     return target_installed_by_;
161*6dbdd20aSAndroid Build Coastguard Worker   }
raw_ds_config()162*6dbdd20aSAndroid Build Coastguard Worker   const DataSourceConfig& raw_ds_config() const { return raw_ds_config_; }
163*6dbdd20aSAndroid Build Coastguard Worker 
164*6dbdd20aSAndroid Build Coastguard Worker  private:
165*6dbdd20aSAndroid Build Coastguard Worker   static bool IsUserFramesEnabled(
166*6dbdd20aSAndroid Build Coastguard Worker       const protos::gen::PerfEventConfig::UnwindMode unwind_mode);
167*6dbdd20aSAndroid Build Coastguard Worker 
168*6dbdd20aSAndroid Build Coastguard Worker   EventConfig(const DataSourceConfig& raw_ds_config,
169*6dbdd20aSAndroid Build Coastguard Worker               const perf_event_attr& pe_timebase,
170*6dbdd20aSAndroid Build Coastguard Worker               std::vector<perf_event_attr> pe_followers,
171*6dbdd20aSAndroid Build Coastguard Worker               const PerfCounter& timebase_event,
172*6dbdd20aSAndroid Build Coastguard Worker               std::vector<PerfCounter> follower_events,
173*6dbdd20aSAndroid Build Coastguard Worker               bool kernel_frames,
174*6dbdd20aSAndroid Build Coastguard Worker               protos::gen::PerfEventConfig::UnwindMode unwind_mode,
175*6dbdd20aSAndroid Build Coastguard Worker               TargetFilter target_filter,
176*6dbdd20aSAndroid Build Coastguard Worker               uint32_t ring_buffer_pages,
177*6dbdd20aSAndroid Build Coastguard Worker               uint32_t read_tick_period_ms,
178*6dbdd20aSAndroid Build Coastguard Worker               uint64_t samples_per_tick_limit,
179*6dbdd20aSAndroid Build Coastguard Worker               uint32_t remote_descriptor_timeout_ms,
180*6dbdd20aSAndroid Build Coastguard Worker               uint32_t unwind_state_clear_period_ms,
181*6dbdd20aSAndroid Build Coastguard Worker               uint64_t max_enqueued_footprint_bytes,
182*6dbdd20aSAndroid Build Coastguard Worker               std::vector<std::string> target_installed_by);
183*6dbdd20aSAndroid Build Coastguard Worker 
184*6dbdd20aSAndroid Build Coastguard Worker   // Parameter struct for the timebase perf_event_open syscall.
185*6dbdd20aSAndroid Build Coastguard Worker   perf_event_attr perf_event_attr_ = {};
186*6dbdd20aSAndroid Build Coastguard Worker 
187*6dbdd20aSAndroid Build Coastguard Worker   std::vector<perf_event_attr> perf_event_followers_ = {};
188*6dbdd20aSAndroid Build Coastguard Worker 
189*6dbdd20aSAndroid Build Coastguard Worker   // Timebase event, which is already described by |perf_event_attr_|. But this
190*6dbdd20aSAndroid Build Coastguard Worker   // additionally carries a tracepoint filter if that needs to be set via an
191*6dbdd20aSAndroid Build Coastguard Worker   // ioctl after creating the event.
192*6dbdd20aSAndroid Build Coastguard Worker   const PerfCounter timebase_event_;
193*6dbdd20aSAndroid Build Coastguard Worker 
194*6dbdd20aSAndroid Build Coastguard Worker   // Timebase event, which are already described by |perf_event_followers_|.
195*6dbdd20aSAndroid Build Coastguard Worker   std::vector<PerfCounter> follower_events_;
196*6dbdd20aSAndroid Build Coastguard Worker 
197*6dbdd20aSAndroid Build Coastguard Worker   // If true, include kernel frames in sampled callstacks.
198*6dbdd20aSAndroid Build Coastguard Worker   const bool kernel_frames_;
199*6dbdd20aSAndroid Build Coastguard Worker 
200*6dbdd20aSAndroid Build Coastguard Worker   // Userspace unwinding mode.
201*6dbdd20aSAndroid Build Coastguard Worker   const protos::gen::PerfEventConfig::UnwindMode unwind_mode_;
202*6dbdd20aSAndroid Build Coastguard Worker 
203*6dbdd20aSAndroid Build Coastguard Worker   // Parsed allow/deny-list for filtering samples.
204*6dbdd20aSAndroid Build Coastguard Worker   const TargetFilter target_filter_;
205*6dbdd20aSAndroid Build Coastguard Worker 
206*6dbdd20aSAndroid Build Coastguard Worker   // Size (in 4k pages) of each per-cpu ring buffer shared with the kernel.
207*6dbdd20aSAndroid Build Coastguard Worker   // Must be a power of two.
208*6dbdd20aSAndroid Build Coastguard Worker   const uint32_t ring_buffer_pages_;
209*6dbdd20aSAndroid Build Coastguard Worker 
210*6dbdd20aSAndroid Build Coastguard Worker   // How often the ring buffers should be read.
211*6dbdd20aSAndroid Build Coastguard Worker   const uint32_t read_tick_period_ms_;
212*6dbdd20aSAndroid Build Coastguard Worker 
213*6dbdd20aSAndroid Build Coastguard Worker   // Guardrail for the amount of samples a given read attempt will extract from
214*6dbdd20aSAndroid Build Coastguard Worker   // *each* per-cpu buffer.
215*6dbdd20aSAndroid Build Coastguard Worker   const uint64_t samples_per_tick_limit_;
216*6dbdd20aSAndroid Build Coastguard Worker 
217*6dbdd20aSAndroid Build Coastguard Worker   // Timeout for proc-fd lookup.
218*6dbdd20aSAndroid Build Coastguard Worker   const uint32_t remote_descriptor_timeout_ms_;
219*6dbdd20aSAndroid Build Coastguard Worker 
220*6dbdd20aSAndroid Build Coastguard Worker   // Optional period for clearing cached unwinder state. Skipped if zero.
221*6dbdd20aSAndroid Build Coastguard Worker   const uint32_t unwind_state_clear_period_ms_;
222*6dbdd20aSAndroid Build Coastguard Worker 
223*6dbdd20aSAndroid Build Coastguard Worker   const uint64_t max_enqueued_footprint_bytes_;
224*6dbdd20aSAndroid Build Coastguard Worker 
225*6dbdd20aSAndroid Build Coastguard Worker   // Only profile target if it was installed by one of the packages given.
226*6dbdd20aSAndroid Build Coastguard Worker   // Special values are:
227*6dbdd20aSAndroid Build Coastguard Worker   // * "@system": installed on the system partition
228*6dbdd20aSAndroid Build Coastguard Worker   // * "@product": installed on the product partition
229*6dbdd20aSAndroid Build Coastguard Worker   // * "@null": sideloaded
230*6dbdd20aSAndroid Build Coastguard Worker   const std::vector<std::string> target_installed_by_;
231*6dbdd20aSAndroid Build Coastguard Worker 
232*6dbdd20aSAndroid Build Coastguard Worker   // The raw data source config, as a pbzero-generated C++ class.
233*6dbdd20aSAndroid Build Coastguard Worker   const DataSourceConfig raw_ds_config_;
234*6dbdd20aSAndroid Build Coastguard Worker };
235*6dbdd20aSAndroid Build Coastguard Worker 
236*6dbdd20aSAndroid Build Coastguard Worker }  // namespace profiling
237*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
238*6dbdd20aSAndroid Build Coastguard Worker 
239*6dbdd20aSAndroid Build Coastguard Worker #endif  // SRC_PROFILING_PERF_EVENT_CONFIG_H_
240