1 /* 2 * Copyright (C) 2020 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_UNWINDING_H_ 18 #define SRC_PROFILING_PERF_UNWINDING_H_ 19 20 #include <stdint.h> 21 #include <condition_variable> 22 #include <map> 23 #include <optional> 24 #include <thread> 25 26 #include <linux/perf_event.h> 27 #include <unwindstack/Error.h> 28 29 #include "perfetto/base/flat_set.h" 30 #include "perfetto/base/logging.h" 31 #include "perfetto/ext/base/thread_checker.h" 32 #include "perfetto/ext/base/unix_task_runner.h" 33 #include "perfetto/ext/tracing/core/basic_types.h" 34 #include "src/kallsyms/kernel_symbol_map.h" 35 #include "src/kallsyms/lazy_kernel_symbolizer.h" 36 #include "src/profiling/common/unwind_support.h" 37 #include "src/profiling/perf/common_types.h" 38 #include "src/profiling/perf/unwind_queue.h" 39 40 namespace perfetto { 41 namespace profiling { 42 43 constexpr static uint32_t kUnwindQueueCapacity = 1024; 44 45 // Unwinds and symbolises callstacks. For userspace this uses the sampled stack 46 // and register state (see |ParsedSample|). For kernelspace, the kernel itself 47 // unwinds the stack (recording a list of instruction pointers), so only 48 // symbolisation using /proc/kallsyms is necessary. Has a single unwinding ring 49 // queue, shared across all data sources. 50 // 51 // Userspace samples cannot be unwound without having /proc/<pid>/{maps,mem} 52 // file descriptors for that process. This lookup can be asynchronous (e.g. on 53 // Android), so the unwinder might have to wait before it can process (or 54 // discard) some of the enqueued samples. To avoid blocking the entire queue, 55 // the unwinder is allowed to process the entries out of order. 56 // 57 // Besides the queue, all interactions between the unwinder and the rest of the 58 // producer logic are through posted tasks. 59 // 60 // As unwinding times are long-tailed (example measurements: median <1ms, 61 // worst-case ~1000ms), the unwinder runs on a dedicated thread to avoid 62 // starving the rest of the producer's work (including IPC and consumption of 63 // records from the kernel ring buffers). 64 // 65 // This class should not be instantiated directly, use the |UnwinderHandle| 66 // below instead. 67 // 68 // TODO(rsavitski): while the inputs to the unwinder are batched as a result of 69 // the reader posting a wakeup only after consuming a batch of kernel samples, 70 // the Unwinder might be staggering wakeups for the producer thread by posting a 71 // task every time a sample has been unwound. Evaluate how bad these wakeups are 72 // in practice, and consider also implementing a batching strategy for the 73 // unwinder->serialization handoff (which isn't very latency-sensitive). 74 class Unwinder { 75 public: 76 friend class UnwinderHandle; 77 78 enum class UnwindMode { kUnwindStack, kFramePointer }; 79 80 // Callbacks from the unwinder to the primary producer thread. 81 class Delegate { 82 public: 83 virtual void PostEmitSample(DataSourceInstanceID ds_id, 84 CompletedSample sample) = 0; 85 virtual void PostEmitUnwinderSkippedSample(DataSourceInstanceID ds_id, 86 ParsedSample sample) = 0; 87 virtual void PostFinishDataSourceStop(DataSourceInstanceID ds_id) = 0; 88 89 virtual ~Delegate(); 90 }; 91 ~Unwinder()92 ~Unwinder() { PERFETTO_DCHECK_THREAD(thread_checker_); } 93 94 void PostStartDataSource(DataSourceInstanceID ds_id, 95 bool kernel_frames, 96 UnwindMode unwind_mode); 97 void PostAdoptProcDescriptors(DataSourceInstanceID ds_id, 98 pid_t pid, 99 base::ScopedFile maps_fd, 100 base::ScopedFile mem_fd); 101 void PostRecordTimedOutProcDescriptors(DataSourceInstanceID ds_id, pid_t pid); 102 void PostRecordNoUserspaceProcess(DataSourceInstanceID ds_id, pid_t pid); 103 void PostProcessQueue(); 104 void PostInitiateDataSourceStop(DataSourceInstanceID ds_id); 105 void PostPurgeDataSource(DataSourceInstanceID ds_id); 106 107 void PostClearCachedStatePeriodic(DataSourceInstanceID ds_id, 108 uint32_t period_ms); 109 unwind_queue()110 UnwindQueue<UnwindEntry, kUnwindQueueCapacity>& unwind_queue() { 111 return unwind_queue_; 112 } 113 GetEnqueuedFootprint()114 uint64_t GetEnqueuedFootprint() { 115 uint64_t freed = 116 footprint_tracker_.stack_bytes_freed.load(std::memory_order_acquire); 117 uint64_t allocated = footprint_tracker_.stack_bytes_allocated.load( 118 std::memory_order_relaxed); 119 120 // overflow not a concern in practice 121 PERFETTO_DCHECK(allocated >= freed); 122 return allocated - freed; 123 } 124 IncrementEnqueuedFootprint(uint64_t increment)125 void IncrementEnqueuedFootprint(uint64_t increment) { 126 footprint_tracker_.stack_bytes_allocated.fetch_add( 127 increment, std::memory_order_relaxed); 128 } 129 130 private: 131 struct ProcessState { 132 // kInitial: unwinder waiting for more info on the process (proc-fds, their 133 // lookup expiration, or that there is no need for them). 134 // kFdsResolved: proc-fds available, can unwind samples. 135 // kFdsTimedOut: proc-fd lookup timed out, will discard samples. Can still 136 // transition to kFdsResolved if the fds are received later. 137 // kNoUserspace: only handling kernel callchains (the sample might 138 // still be for a userspace process), can process samples. 139 enum class Status { kInitial, kFdsResolved, kFdsTimedOut, kNoUserspace }; 140 141 Status status = Status::kInitial; 142 // Present iff status == kFdsResolved. 143 std::optional<UnwindingMetadata> unwind_state; 144 // Used to distinguish first-time unwinding attempts for a process, for 145 // logging purposes. 146 bool attempted_unwinding = false; 147 }; 148 149 struct DataSourceState { 150 enum class Status { kActive, kShuttingDown }; DataSourceStateDataSourceState151 explicit DataSourceState(UnwindMode _unwind_mode) 152 : unwind_mode(_unwind_mode) {} 153 154 Status status = Status::kActive; 155 const UnwindMode unwind_mode; 156 std::map<pid_t, ProcessState> process_states; 157 }; 158 159 // Accounting for how much heap memory is attached to the enqueued samples at 160 // a given time. Read by the main thread, mutated by both threads. 161 // We track just the heap allocated for the sampled stacks, as it dominates 162 // the per-sample heap use. 163 struct QueueFootprintTracker { 164 std::atomic<uint64_t> stack_bytes_allocated; 165 std::atomic<uint64_t> stack_bytes_freed; 166 }; 167 168 // Must be instantiated via the |UnwinderHandle|. 169 Unwinder(Delegate* delegate, base::UnixTaskRunner* task_runner); 170 171 // Marks the data source as valid and active at the unwinding stage. 172 // Initializes kernel address symbolization if needed. 173 void StartDataSource(DataSourceInstanceID ds_id, 174 bool kernel_frames, 175 UnwindMode unwind_mode); 176 177 void AdoptProcDescriptors(DataSourceInstanceID ds_id, 178 pid_t pid, 179 base::ScopedFile maps_fd, 180 base::ScopedFile mem_fd); 181 void UpdateProcessStateStatus(DataSourceInstanceID ds_id, 182 pid_t pid, 183 ProcessState::Status new_status); 184 185 // Primary task. Processes the enqueued samples using 186 // |ConsumeAndUnwindReadySamples|, and re-evaluates data source state. 187 void ProcessQueue(); 188 189 // Processes the enqueued samples for which all unwinding inputs are ready. 190 // Returns the set of data source instances which still have samples pending 191 // (i.e. waiting on the proc-fds). 192 base::FlatSet<DataSourceInstanceID> ConsumeAndUnwindReadySamples(); 193 194 CompletedSample UnwindSample(const ParsedSample& sample, 195 UnwindingMetadata* opt_user_state, 196 bool pid_unwound_before, 197 UnwindMode unwind_mode); 198 199 // Returns a list of symbolized kernel frames in the sample (if any). 200 std::vector<unwindstack::FrameData> SymbolizeKernelCallchain( 201 const ParsedSample& sample); 202 203 // Marks the data source as shutting down at the unwinding stage. It is known 204 // that no new samples for this source will be pushed into the queue, but we 205 // need to delay the unwinder state teardown until all previously-enqueued 206 // samples for this source are processed. 207 void InitiateDataSourceStop(DataSourceInstanceID ds_id); 208 209 // Tears down unwinding state for the data source without any outstanding 210 // samples, and informs the service that it can continue the shutdown 211 // sequence. 212 void FinishDataSourceStop(DataSourceInstanceID ds_id); 213 214 // Immediately destroys the data source state, used for abrupt stops. 215 void PurgeDataSource(DataSourceInstanceID ds_id); 216 DecrementEnqueuedFootprint(uint64_t decrement)217 void DecrementEnqueuedFootprint(uint64_t decrement) { 218 footprint_tracker_.stack_bytes_freed.fetch_add(decrement, 219 std::memory_order_relaxed); 220 } 221 222 // Clears the parsed maps for all previously-sampled processes, and resets the 223 // libunwindstack cache. This has the effect of deallocating the cached Elf 224 // objects within libunwindstack, which take up non-trivial amounts of memory. 225 // 226 // There are two reasons for having this operation: 227 // * over a longer trace, it's desireable to drop heavy state for processes 228 // that haven't been sampled recently. 229 // * since libunwindstack's cache is not bounded, it'll tend towards having 230 // state for all processes that are targeted by the profiling config. 231 // Clearing the cache periodically helps keep its footprint closer to the 232 // actual working set (NB: which might still be arbitrarily big, depending 233 // on the profiling config). 234 // 235 // After this function completes, the next unwind for each process will 236 // therefore incur a guaranteed maps reparse. 237 // 238 // Unwinding for concurrent data sources will *not* be directly affected at 239 // the time of writing, as the non-cleared parsed maps will keep the cached 240 // Elf objects alive through shared_ptrs. 241 // 242 // Note that this operation is heavy in terms of cpu%, and should therefore 243 // be called only for profiling configs that require it. 244 // 245 // TODO(rsavitski): dropping the full parsed maps is somewhat excessive, could 246 // instead clear just the |MapInfo.elf| shared_ptr, but that's considered too 247 // brittle as it's an implementation detail of libunwindstack. 248 // TODO(rsavitski): improve libunwindstack cache's architecture (it is still 249 // worth having at the moment to speed up unwinds across map reparses). 250 void ClearCachedStatePeriodic(DataSourceInstanceID ds_id, uint32_t period_ms); 251 252 void ResetAndEnableUnwindstackCache(); 253 254 base::UnixTaskRunner* const task_runner_; 255 Delegate* const delegate_; 256 UnwindQueue<UnwindEntry, kUnwindQueueCapacity> unwind_queue_; 257 QueueFootprintTracker footprint_tracker_; 258 std::map<DataSourceInstanceID, DataSourceState> data_sources_; 259 LazyKernelSymbolizer kernel_symbolizer_; 260 261 PERFETTO_THREAD_CHECKER(thread_checker_) 262 }; 263 264 // Owning resource handle for an |Unwinder| with a dedicated task thread. 265 // Ensures that the |Unwinder| is constructed and destructed on the task thread. 266 // TODO(rsavitski): update base::ThreadTaskRunner to allow for this pattern of 267 // owned state, and consolidate. 268 class UnwinderHandle { 269 public: UnwinderHandle(Unwinder::Delegate * delegate)270 explicit UnwinderHandle(Unwinder::Delegate* delegate) { 271 std::mutex init_lock; 272 std::condition_variable init_cv; 273 274 std::function<void(base::UnixTaskRunner*, Unwinder*)> initializer = 275 [this, &init_lock, &init_cv](base::UnixTaskRunner* task_runner, 276 Unwinder* unwinder) { 277 std::lock_guard<std::mutex> lock(init_lock); 278 task_runner_ = task_runner; 279 unwinder_ = unwinder; 280 // Notify while still holding the lock, as init_cv ceases to exist as 281 // soon as the main thread observes a non-null task_runner_, and it 282 // can wake up spuriously (i.e. before the notify if we had unlocked 283 // before notifying). 284 init_cv.notify_one(); 285 }; 286 287 thread_ = std::thread(&UnwinderHandle::RunTaskThread, this, 288 std::move(initializer), delegate); 289 290 std::unique_lock<std::mutex> lock(init_lock); 291 init_cv.wait(lock, [this] { return !!task_runner_ && !!unwinder_; }); 292 } 293 ~UnwinderHandle()294 ~UnwinderHandle() { 295 if (task_runner_) { 296 PERFETTO_CHECK(!task_runner_->QuitCalled()); 297 task_runner_->Quit(); 298 299 PERFETTO_DCHECK(thread_.joinable()); 300 } 301 if (thread_.joinable()) 302 thread_.join(); 303 } 304 305 Unwinder* operator->() { return unwinder_; } 306 307 private: RunTaskThread(std::function<void (base::UnixTaskRunner *,Unwinder *)> initializer,Unwinder::Delegate * delegate)308 void RunTaskThread( 309 std::function<void(base::UnixTaskRunner*, Unwinder*)> initializer, 310 Unwinder::Delegate* delegate) { 311 base::UnixTaskRunner task_runner; 312 Unwinder unwinder(delegate, &task_runner); 313 task_runner.PostTask( 314 std::bind(std::move(initializer), &task_runner, &unwinder)); 315 task_runner.Run(); 316 } 317 318 std::thread thread_; 319 base::UnixTaskRunner* task_runner_ = nullptr; 320 Unwinder* unwinder_ = nullptr; 321 }; 322 323 } // namespace profiling 324 } // namespace perfetto 325 326 #endif // SRC_PROFILING_PERF_UNWINDING_H_ 327