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