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 <functional> 21 #include <string> 22 #include <vector> 23 24 #include <inttypes.h> 25 #include <linux/perf_event.h> 26 #include <stdint.h> 27 #include <sys/types.h> 28 29 #include "perfetto/base/flat_set.h" 30 #include "perfetto/ext/base/optional.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 // Parsed allow/deny-list for filtering samples. 45 // An empty filter set means that all targets are allowed. 46 struct TargetFilter { 47 base::FlatSet<std::string> cmdlines; 48 base::FlatSet<std::string> exclude_cmdlines; 49 base::FlatSet<pid_t> pids; 50 base::FlatSet<pid_t> exclude_pids; 51 uint32_t additional_cmdline_count = 0; 52 }; 53 54 struct PerfCounter { 55 // Either a predefined counter, or a tracepoint: 56 protos::gen::PerfEvents::Counter counter = 57 protos::gen::PerfEvents::PerfEvents::UNKNOWN_COUNTER; 58 protos::gen::PerfEvents::Tracepoint tracepoint; 59 60 // sycall-level description of the event: 61 uint32_t type = 0; // perf_event_attr.type 62 uint32_t config = 0; // perf_event_attr.config 63 is_counterPerfCounter64 bool is_counter() const { 65 return counter != protos::gen::PerfEvents::PerfEvents::UNKNOWN_COUNTER; 66 } is_tracepointPerfCounter67 bool is_tracepoint() const { return type == PERF_TYPE_TRACEPOINT; } 68 69 static PerfCounter Counter(protos::gen::PerfEvents::Counter counter, 70 uint32_t type, 71 uint32_t config); 72 73 static PerfCounter Tracepoint(protos::gen::PerfEvents::Tracepoint tracepoint, 74 uint32_t id); 75 }; 76 77 // Describes a single profiling configuration. Bridges the gap between the data 78 // source config proto, and the raw "perf_event_attr" structs to pass to the 79 // perf_event_open syscall. 80 class EventConfig { 81 public: 82 using tracepoint_id_fn_t = 83 std::function<uint32_t(const std::string&, const std::string&)>; 84 85 static base::Optional<EventConfig> Create( 86 const DataSourceConfig& ds_config, 87 tracepoint_id_fn_t tracepoint_id_lookup = 88 [](const std::string&, const std::string&) { return 0; }); 89 90 static base::Optional<EventConfig> Create( 91 const protos::gen::PerfEventConfig& pb_config, 92 const DataSourceConfig& raw_ds_config, 93 tracepoint_id_fn_t tracepoint_id_lookup); 94 ring_buffer_pages()95 uint32_t ring_buffer_pages() const { return ring_buffer_pages_; } read_tick_period_ms()96 uint32_t read_tick_period_ms() const { return read_tick_period_ms_; } samples_per_tick_limit()97 uint64_t samples_per_tick_limit() const { return samples_per_tick_limit_; } remote_descriptor_timeout_ms()98 uint32_t remote_descriptor_timeout_ms() const { 99 return remote_descriptor_timeout_ms_; 100 } unwind_state_clear_period_ms()101 uint32_t unwind_state_clear_period_ms() const { 102 return unwind_state_clear_period_ms_; 103 } max_enqueued_footprint_bytes()104 uint64_t max_enqueued_footprint_bytes() const { 105 return max_enqueued_footprint_bytes_; 106 } sample_callstacks()107 bool sample_callstacks() const { return sample_callstacks_; } filter()108 const TargetFilter& filter() const { return target_filter_; } kernel_frames()109 bool kernel_frames() const { return kernel_frames_; } perf_attr()110 perf_event_attr* perf_attr() const { 111 return const_cast<perf_event_attr*>(&perf_event_attr_); 112 } timebase_event()113 const PerfCounter& timebase_event() const { return timebase_event_; } target_installed_by()114 const std::vector<std::string>& target_installed_by() const { 115 return target_installed_by_; 116 } raw_ds_config()117 const DataSourceConfig& raw_ds_config() const { return raw_ds_config_; } 118 119 private: 120 EventConfig(const DataSourceConfig& raw_ds_config, 121 const perf_event_attr& pe, 122 const PerfCounter& timebase_event, 123 bool sample_callstacks, 124 TargetFilter target_filter, 125 bool kernel_frames, 126 uint32_t ring_buffer_pages, 127 uint32_t read_tick_period_ms, 128 uint64_t samples_per_tick_limit, 129 uint32_t remote_descriptor_timeout_ms, 130 uint32_t unwind_state_clear_period_ms, 131 uint64_t max_enqueued_footprint_bytes, 132 std::vector<std::string> target_installed_by); 133 134 // Parameter struct for the leader (timebase) perf_event_open syscall. 135 perf_event_attr perf_event_attr_ = {}; 136 137 // Leader event, which is already described by |perf_event_attr_|. But this 138 // additionally carries a tracepoint filter if that needs to be set via an 139 // ioctl after creating the event. 140 const PerfCounter timebase_event_; 141 142 // TODO(rsavitski): consider adding an Optional<CallstackSampling> that 143 // contains the kernel_frames_ and target_filter, once the complexity warrants 144 // it. 145 const bool sample_callstacks_; 146 147 // Parsed allow/deny-list for filtering samples. 148 const TargetFilter target_filter_; 149 150 // If true, include kernel frames in the callstacks. 151 const bool kernel_frames_; 152 153 // Size (in 4k pages) of each per-cpu ring buffer shared with the kernel. 154 // Must be a power of two. 155 const uint32_t ring_buffer_pages_; 156 157 // How often the ring buffers should be read. 158 const uint32_t read_tick_period_ms_; 159 160 // Guardrail for the amount of samples a given read attempt will extract from 161 // *each* per-cpu buffer. 162 const uint64_t samples_per_tick_limit_; 163 164 // Timeout for proc-fd lookup. 165 const uint32_t remote_descriptor_timeout_ms_; 166 167 // Optional period for clearing cached unwinder state. Skipped if zero. 168 const uint32_t unwind_state_clear_period_ms_; 169 170 const uint64_t max_enqueued_footprint_bytes_; 171 172 // Only profile target if it was installed by one of the packages given. 173 // Special values are: 174 // * @system: installed on the system partition 175 // * @product: installed on the product partition 176 // * @null: sideloaded 177 const std::vector<std::string> target_installed_by_; 178 179 // The raw data source config, as a pbzero-generated C++ class. 180 const DataSourceConfig raw_ds_config_; 181 }; 182 183 } // namespace profiling 184 } // namespace perfetto 185 186 #endif // SRC_PROFILING_PERF_EVENT_CONFIG_H_ 187