xref: /aosp_15_r20/external/perfetto/src/profiling/perf/perf_producer.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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