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