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_PERF_PRODUCER_H_ 18 #define SRC_PROFILING_PERF_PERF_PRODUCER_H_ 19 20 #include <unistd.h> 21 #include <map> 22 #include <memory> 23 #include <optional> 24 25 #include <unwindstack/Error.h> 26 #include <unwindstack/Regs.h> 27 28 #include "perfetto/base/task_runner.h" 29 #include "perfetto/ext/base/scoped_file.h" 30 #include "perfetto/ext/base/unix_socket.h" 31 #include "perfetto/ext/base/weak_ptr.h" 32 #include "perfetto/ext/tracing/core/basic_types.h" 33 #include "perfetto/ext/tracing/core/producer.h" 34 #include "perfetto/ext/tracing/core/trace_writer.h" 35 #include "perfetto/ext/tracing/core/tracing_service.h" 36 #include "src/profiling/common/callstack_trie.h" 37 #include "src/profiling/common/interning_output.h" 38 #include "src/profiling/common/unwind_support.h" 39 #include "src/profiling/perf/common_types.h" 40 #include "src/profiling/perf/event_config.h" 41 #include "src/profiling/perf/event_reader.h" 42 #include "src/profiling/perf/proc_descriptors.h" 43 #include "src/profiling/perf/unwinding.h" 44 #include "src/tracing/service/metatrace_writer.h" 45 // TODO(rsavitski): move to e.g. src/tracefs/. 46 #include "src/traced/probes/ftrace/ftrace_procfs.h" 47 48 namespace perfetto { 49 namespace profiling { 50 51 // TODO(rsavitski): describe the high-level architecture and threading. Rough 52 // summary in the mean time: three stages: (1) kernel buffer reader that parses 53 // the samples -> (2) callstack unwinder -> (3) interning and serialization of 54 // samples. This class handles stages (1) and (3) on the main thread. Unwinding 55 // is done by |Unwinder| on a dedicated thread. 56 class PerfProducer : public Producer, 57 public ProcDescriptorDelegate, 58 public Unwinder::Delegate { 59 public: 60 PerfProducer(ProcDescriptorGetter* proc_fd_getter, 61 base::TaskRunner* task_runner); 62 ~PerfProducer() override = default; 63 64 PerfProducer(const PerfProducer&) = delete; 65 PerfProducer& operator=(const PerfProducer&) = delete; 66 PerfProducer(PerfProducer&&) = delete; 67 PerfProducer& operator=(PerfProducer&&) = delete; 68 69 void ConnectWithRetries(const char* socket_name); 70 71 // Producer impl: 72 void OnConnect() override; 73 void OnDisconnect() override; OnTracingSetup()74 void OnTracingSetup() override {} 75 void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&) override; 76 void StartDataSource(DataSourceInstanceID instance_id, 77 const DataSourceConfig& config) override; 78 void StopDataSource(DataSourceInstanceID instance_id) override; 79 void Flush(FlushRequestID flush_id, 80 const DataSourceInstanceID* data_source_ids, 81 size_t num_data_sources, 82 FlushFlags) override; 83 void ClearIncrementalState(const DataSourceInstanceID* data_source_ids, 84 size_t num_data_sources) override; 85 86 // ProcDescriptorDelegate impl: 87 void OnProcDescriptors(pid_t pid, 88 uid_t uid, 89 base::ScopedFile maps_fd, 90 base::ScopedFile mem_fd) override; 91 92 // Unwinder::Delegate impl (callbacks from unwinder): 93 void PostEmitSample(DataSourceInstanceID ds_id, 94 CompletedSample sample) override; 95 void PostEmitUnwinderSkippedSample(DataSourceInstanceID ds_id, 96 ParsedSample sample) override; 97 void PostFinishDataSourceStop(DataSourceInstanceID ds_id) override; 98 99 // Calls `cb` when all data sources have been registered. SetAllDataSourcesRegisteredCb(std::function<void ()> cb)100 void SetAllDataSourcesRegisteredCb(std::function<void()> cb) { 101 all_data_sources_registered_cb_ = cb; 102 } 103 104 // public for testing: 105 static bool ShouldRejectDueToFilter( 106 pid_t pid, 107 const TargetFilter& filter, 108 bool skip_cmdline, 109 base::FlatSet<std::string>* additional_cmdlines, 110 std::function<bool(std::string*)> read_proc_pid_cmdline); 111 112 private: 113 // State of the producer's connection to tracing service (traced). 114 enum State { 115 kNotStarted = 0, 116 kNotConnected, 117 kConnecting, 118 kConnected, 119 }; 120 121 // Represents the data source scoped view of a process: 122 // * whether the process is in scope of the tracing session (if the latter 123 // specifies a callstack sampling target filter). 124 // * for userspace processes, the state of the (possibly asynchronous) lookup 125 // of /proc/<pid>/{maps,mem} file descriptors, which are necessary for 126 // callstack unwinding of samples. 127 // For kernel threads (or when sampling only kernelspace callstacks) the 128 // proc-fds are not necessary, so those processes transition directly to 129 // either kAccepted or kRejected. 130 // TODO(rsavitski): double-check and clarify pid reuse semantics. For 131 // userspace sampling, at most one incarnation of the pid is handled since we 132 // do not obtain new proc descriptors. But counter-only and kernel-only cases 133 // aren't as stateful and will keep emitting samples. 134 enum class ProcessTrackingStatus { 135 kInitial = 0, 136 kFdsResolving, // waiting on proc-fd lookup 137 kAccepted, // process relevant and ready for unwinding (for userspace - 138 // procfds received) 139 kFdsTimedOut, // proc-fd lookup timed out 140 kRejected // process not considered relevant for the data source 141 }; 142 143 struct DataSourceState { 144 enum class Status { kActive, kShuttingDown }; 145 DataSourceStateDataSourceState146 DataSourceState(EventConfig _event_config, 147 uint64_t _tracing_session_id, 148 std::unique_ptr<TraceWriter> _trace_writer, 149 std::vector<EventReader> _per_cpu_readers) 150 : event_config(std::move(_event_config)), 151 tracing_session_id(_tracing_session_id), 152 trace_writer(std::move(_trace_writer)), 153 per_cpu_readers(std::move(_per_cpu_readers)) {} 154 155 Status status = Status::kActive; 156 const EventConfig event_config; 157 uint64_t tracing_session_id; 158 std::unique_ptr<TraceWriter> trace_writer; 159 // Indexed by cpu, vector never resized. 160 std::vector<EventReader> per_cpu_readers; 161 // Tracks the incremental state for interned entries. 162 InterningOutputTracker interning_output; 163 // Producer thread's view of sampled processes. This is the primary tracking 164 // structure, but a subset of updates are replicated to a similar structure 165 // in the |Unwinder|, which needs to track whether the necessary unwinding 166 // inputs for a given process' samples are ready. 167 std::map<pid_t, ProcessTrackingStatus> process_states; 168 // Additional state for EventConfig.TargetFilter: command lines we have 169 // decided to unwind, up to a total of additional_cmdline_count values. 170 base::FlatSet<std::string> additional_cmdlines; 171 }; 172 173 // For |EmitSkippedSample|. 174 enum class SampleSkipReason { 175 kReadStage = 0, // discarded at read stage 176 kUnwindEnqueue, // discarded due to unwinder queue being full 177 kUnwindStage, // discarded at unwind stage 178 }; 179 180 void ConnectService(); 181 void Restart(); 182 void ResetConnectionBackoff(); 183 void IncreaseConnectionBackoff(); 184 185 // Periodic read task which reads a batch of samples from all kernel ring 186 // buffers associated with the given data source. 187 void TickDataSourceRead(DataSourceInstanceID ds_id); 188 // Returns *false* if the reader has caught up with the writer position, true 189 // otherwise. Return value is only useful if the underlying perf_event has 190 // been paused (to identify when the buffer is empty). |max_samples| is a cap 191 // on the amount of samples that will be parsed, which might be more than the 192 // number of underlying records (as there might be non-sample records). 193 bool ReadAndParsePerCpuBuffer(EventReader* reader, 194 uint64_t max_samples, 195 DataSourceInstanceID ds_id, 196 DataSourceState* ds); 197 198 void InitiateDescriptorLookup(DataSourceInstanceID ds_id, 199 pid_t pid, 200 uint32_t timeout_ms); 201 // Do not call directly, use |InitiateDescriptorLookup|. 202 void StartDescriptorLookup(DataSourceInstanceID ds_id, 203 pid_t pid, 204 uint32_t timeout_ms); 205 void EvaluateDescriptorLookupTimeout(DataSourceInstanceID ds_id, pid_t pid); 206 207 void EmitSample(DataSourceInstanceID ds_id, CompletedSample sample); 208 void EmitRingBufferLoss(DataSourceInstanceID ds_id, 209 size_t cpu, 210 uint64_t records_lost); 211 212 void PostEmitSkippedSample(DataSourceInstanceID ds_id, 213 ParsedSample sample, 214 SampleSkipReason reason); 215 // Emit a packet indicating that a sample was relevant, but skipped as it was 216 // considered to be not unwindable (e.g. the process no longer exists). 217 void EmitSkippedSample(DataSourceInstanceID ds_id, 218 ParsedSample sample, 219 SampleSkipReason reason); 220 221 // Starts the shutdown of the given data source instance, starting with 222 // pausing the reader frontend. Once the reader reaches the point where all 223 // kernel buffers have been fully consumed, it will notify the |Unwinder| to 224 // proceed with the shutdown sequence. The unwinder in turn will call back to 225 // this producer once there are no more outstanding samples for the data 226 // source at the unwinding stage. 227 void InitiateReaderStop(DataSourceState* ds); 228 // Destroys the state belonging to this instance, and acks the stop to the 229 // tracing service. 230 void FinishDataSourceStop(DataSourceInstanceID ds_id); 231 // Immediately destroys the data source state, and instructs the unwinder to 232 // do the same. This is used for abrupt stops. 233 void PurgeDataSource(DataSourceInstanceID ds_id); 234 235 // Immediately stops the data source if this daemon's overall memory footprint 236 // is above the given threshold. This periodic task is started only for data 237 // sources that specify a limit. 238 void CheckMemoryFootprintPeriodic(DataSourceInstanceID ds_id, 239 uint32_t max_daemon_memory_kb); 240 241 // Chooses a random parameter for a callstack sampling option. Done at this 242 // level as the choice is shared by all data sources within a tracing session. 243 std::optional<ProcessSharding> GetOrChooseCallstackProcessShard( 244 uint64_t tracing_session_id, 245 uint32_t shard_count); 246 247 void StartMetatraceSource(DataSourceInstanceID ds_id, BufferID target_buffer); 248 249 // Task runner owned by the main thread. 250 base::TaskRunner* const task_runner_; 251 State state_ = kNotStarted; 252 const char* producer_socket_name_ = nullptr; 253 uint32_t connection_backoff_ms_ = 0; 254 255 // Valid and stable for the lifetime of this class. 256 ProcDescriptorGetter* const proc_fd_getter_; 257 258 // Owns shared memory, must outlive trace writing. 259 std::unique_ptr<TracingService::ProducerEndpoint> endpoint_; 260 261 // If multiple metatrace sources are enabled concurrently, 262 // only the first one becomes active. 263 std::map<DataSourceInstanceID, MetatraceWriter> metatrace_writers_; 264 265 // Interns callstacks across all data sources. 266 // TODO(rsavitski): for long profiling sessions, consider purging trie when it 267 // grows too large (at the moment purged only when no sources are active). 268 // TODO(rsavitski): interning sequences are monotonic for the lifetime of the 269 // daemon. Consider resetting them at safe points - possible when no sources 270 // are active, and tricky otherwise. In the latter case, it'll require 271 // emitting incremental sequence invalidation packets on all relevant 272 // sequences. 273 GlobalCallstackTrie callstack_trie_; 274 275 // State associated with perf-sampling data sources. 276 std::map<DataSourceInstanceID, DataSourceState> data_sources_; 277 278 // Unwinding stage, running on a dedicated thread. 279 UnwinderHandle unwinding_worker_; 280 281 // Used for tracepoint name -> id lookups. Initialized lazily, and in general 282 // best effort - can be null if tracefs isn't accessible. 283 std::unique_ptr<FtraceProcfs> tracefs_; 284 285 std::function<void()> all_data_sources_registered_cb_; 286 287 base::WeakPtrFactory<PerfProducer> weak_factory_; // keep last 288 }; 289 290 } // namespace profiling 291 } // namespace perfetto 292 293 #endif // SRC_PROFILING_PERF_PERF_PRODUCER_H_ 294