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