xref: /aosp_15_r20/external/perfetto/src/traced/probes/ftrace/ftrace_controller.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2017 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_TRACED_PROBES_FTRACE_FTRACE_CONTROLLER_H_
18 #define SRC_TRACED_PROBES_FTRACE_FTRACE_CONTROLLER_H_
19 
20 #include <stdint.h>
21 #include <unistd.h>
22 
23 #include <map>
24 #include <memory>
25 #include <set>
26 #include <string>
27 
28 #include "perfetto/base/task_runner.h"
29 #include "perfetto/ext/base/weak_ptr.h"
30 #include "perfetto/ext/tracing/core/basic_types.h"
31 #include "src/kallsyms/lazy_kernel_symbolizer.h"
32 #include "src/traced/probes/ftrace/atrace_wrapper.h"
33 #include "src/traced/probes/ftrace/cpu_reader.h"
34 #include "src/traced/probes/ftrace/ftrace_config_utils.h"
35 
36 namespace perfetto {
37 
38 class FtraceConfigMuxer;
39 class FtraceDataSource;
40 class FtraceProcfs;
41 class LazyKernelSymbolizer;
42 class ProtoTranslationTable;
43 struct FtraceStats;
44 
45 // Method of last resort to reset ftrace state.
46 bool HardResetFtraceState();
47 
48 // Stores the a snapshot of the timestamps from ftrace's trace clock
49 // and CLOCK_BOOTITME.
50 //
51 // This is used when the "boot" (i.e. CLOCK_BOOTITME) is not available
52 // for timestamping trace events (on Android O- and 3.x Linux kernels).
53 // Trace processor can use this data to sync clocks just as it would
54 // with ClockSnapshot packets.
55 struct FtraceClockSnapshot {
56   // The timestamp according to the ftrace clock.
57   int64_t ftrace_clock_ts = 0;
58 
59   // The timestamp according to CLOCK_BOOTTIME.
60   int64_t boot_clock_ts = 0;
61 };
62 
63 // Utility class for controlling ftrace.
64 class FtraceController {
65  public:
66   class Observer {
67    public:
68     virtual ~Observer();
69     virtual void OnFtraceDataWrittenIntoDataSourceBuffers() = 0;
70   };
71 
72   // The passed Observer must outlive the returned FtraceController instance.
73   static std::unique_ptr<FtraceController> Create(base::TaskRunner*, Observer*);
74   virtual ~FtraceController();
75 
76   bool AddDataSource(FtraceDataSource*) PERFETTO_WARN_UNUSED_RESULT;
77   bool StartDataSource(FtraceDataSource*);
78   void RemoveDataSource(FtraceDataSource*);
79 
80   // Force a read of the ftrace buffers. Will call OnFtraceFlushComplete() on
81   // all started data sources.
82   void Flush(FlushRequestID);
83 
84   void DumpFtraceStats(FtraceDataSource*, FtraceStats*);
85 
GetWeakPtr()86   base::WeakPtr<FtraceController> GetWeakPtr() {
87     return weak_factory_.GetWeakPtr();
88   }
89 
90   // public for testing
91   static std::optional<std::string> AbsolutePathForInstance(
92       const std::string& tracefs_root,
93       const std::string& raw_cfg_name);
94 
95   // public for testing
96   static bool PollSupportedOnKernelVersion(const char* uts_release);
97 
98  protected:
99   // Everything protected/virtual for testing:
100 
101   FtraceController(std::unique_ptr<FtraceProcfs>,
102                    std::unique_ptr<ProtoTranslationTable>,
103                    std::unique_ptr<AtraceWrapper>,
104                    std::unique_ptr<FtraceConfigMuxer>,
105                    base::TaskRunner*,
106                    Observer*);
107 
108   struct FtraceInstanceState {
109     FtraceInstanceState(std::unique_ptr<FtraceProcfs>,
110                         std::unique_ptr<ProtoTranslationTable>,
111                         std::unique_ptr<FtraceConfigMuxer>);
112 
113     std::unique_ptr<FtraceProcfs> ftrace_procfs;
114     std::unique_ptr<ProtoTranslationTable> table;
115     std::unique_ptr<FtraceConfigMuxer> ftrace_config_muxer;
116     std::vector<CpuReader> cpu_readers;  // empty if no started data sources
117     std::set<FtraceDataSource*> started_data_sources;
118     bool buffer_watches_posted = false;
119   };
120 
121   FtraceInstanceState* GetInstance(const std::string& instance_name);
122   // TODO(rsavitski): figure out a better testing shim.
123   virtual std::unique_ptr<FtraceInstanceState> CreateSecondaryInstance(
124       const std::string& instance_name);
125 
126   virtual uint64_t NowMs() const;
127 
atrace_wrapper()128   AtraceWrapper* atrace_wrapper() const { return atrace_wrapper_.get(); }
129 
130  private:
131   friend class TestFtraceController;
132   enum class PollSupport { kUntested, kSupported, kUnsupported };
133 
134   FtraceController(const FtraceController&) = delete;
135   FtraceController& operator=(const FtraceController&) = delete;
136 
137   // Periodic task that reads all per-cpu ftrace buffers. Global across tracefs
138   // instances.
139   void ReadTick(int generation);
140   bool ReadPassForInstance(FtraceInstanceState* instance);
141   uint32_t GetTickPeriodMs();
142   // Optional: additional reads based on buffer capacity. Per tracefs instance.
143   void UpdateBufferWatermarkWatches(FtraceInstanceState* instance,
144                                     const std::string& instance_name);
145   void OnBufferPastWatermark(std::string instance_name,
146                              size_t cpu,
147                              bool repoll_watermark);
148   void RemoveBufferWatermarkWatches(FtraceInstanceState* instance);
149   PollSupport VerifyKernelSupportForBufferWatermark();
150 
151   void FlushForInstance(FtraceInstanceState* instance);
152 
153   void StartIfNeeded(FtraceInstanceState* instance,
154                      const std::string& instance_name);
155   void StopIfNeeded(FtraceInstanceState* instance);
156 
157   FtraceInstanceState* GetOrCreateInstance(const std::string& instance_name);
158   void DestroyIfUnusedSeconaryInstance(FtraceInstanceState* instance);
159 
160   size_t GetStartedDataSourcesCount();
161   void MaybeSnapshotFtraceClock();  // valid only for primary_ tracefs instance
162 
163   template <typename F /* void(FtraceInstanceState*) */>
164   void ForEachInstance(F fn);
165 
166   base::TaskRunner* const task_runner_;
167   Observer* const observer_;
168   CpuReader::ParsingBuffers parsing_mem_;
169   LazyKernelSymbolizer symbolizer_;
170   FtraceConfigId next_cfg_id_ = 1;
171   int tick_generation_ = 0;
172   bool retain_ksyms_on_stop_ = false;
173   PollSupport buffer_watermark_support_ = PollSupport::kUntested;
174   std::set<FtraceDataSource*> data_sources_;
175   std::unique_ptr<AtraceWrapper> atrace_wrapper_;
176   // Default tracefs instance (normally /sys/kernel/tracing) is valid for as
177   // long as the controller is valid.
178   // Secondary instances (i.e. /sys/kernel/tracing/instances/...) are created
179   // and destroyed as necessary between AddDataSource and RemoveDataSource:
180   FtraceInstanceState primary_;
181   std::map<std::string, std::unique_ptr<FtraceInstanceState>>
182       secondary_instances_;
183 
184   // Additional state for snapshotting non-boot ftrace clock, specific to the
185   // primary_ instance:
186   base::ScopedFile cpu_zero_stats_fd_;
187   FtraceClockSnapshot ftrace_clock_snapshot_;
188 
189   base::WeakPtrFactory<FtraceController> weak_factory_;  // Keep last.
190 };
191 
192 bool DumpKprobeStats(const std::string& text, FtraceStats* ftrace_stats);
193 
194 }  // namespace perfetto
195 
196 #endif  // SRC_TRACED_PROBES_FTRACE_FTRACE_CONTROLLER_H_
197