1 /* 2 * Copyright (C) 2018 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_DATA_SOURCE_H_ 18 #define SRC_TRACED_PROBES_FTRACE_FTRACE_DATA_SOURCE_H_ 19 20 #include <functional> 21 #include <map> 22 #include <memory> 23 #include <utility> 24 25 #include "perfetto/base/flat_set.h" 26 #include "perfetto/ext/base/scoped_file.h" 27 #include "perfetto/ext/base/weak_ptr.h" 28 #include "perfetto/ext/tracing/core/basic_types.h" 29 #include "perfetto/ext/tracing/core/trace_writer.h" 30 #include "perfetto/protozero/message_handle.h" 31 #include "src/traced/probes/ftrace/ftrace_config_utils.h" 32 #include "src/traced/probes/ftrace/ftrace_metadata.h" 33 #include "src/traced/probes/ftrace/ftrace_stats.h" 34 #include "src/traced/probes/probes_data_source.h" 35 36 namespace perfetto { 37 38 class FtraceController; 39 class ProcessStatsDataSource; 40 class InodeFileDataSource; 41 struct FtraceDataSourceConfig; 42 43 namespace protos { 44 namespace pbzero { 45 class FtraceEventBundle; 46 enum FtraceParseStatus : int32_t; 47 } // namespace pbzero 48 } // namespace protos 49 50 // This class handles the state for one particular tracing session involving 51 // ftrace. There can be several concurrent tracing sessions involving ftrace 52 // and this class is essentially the building block used to multiplex them. 53 // This class is instantiated by ProbesProducer. ProbesProducer also owns the 54 // FtraceController. 55 class FtraceDataSource : public ProbesDataSource { 56 public: 57 static const ProbesDataSource::Descriptor descriptor; 58 59 FtraceDataSource(base::WeakPtr<FtraceController>, 60 TracingSessionID, 61 const FtraceConfig&, 62 std::unique_ptr<TraceWriter>); 63 ~FtraceDataSource() override; 64 65 // Hands out internal pointers to callbacks. 66 FtraceDataSource(const FtraceDataSource&) = delete; 67 FtraceDataSource& operator=(const FtraceDataSource&) = delete; 68 FtraceDataSource(FtraceDataSource&&) = delete; 69 FtraceDataSource& operator=(FtraceDataSource&&) = delete; 70 71 // Called by FtraceController soon after ProbesProducer creates the data 72 // source, to inject ftrace dependencies. 73 void Initialize(FtraceConfigId, const FtraceDataSourceConfig* parsing_config); 74 75 // ProbesDataSource implementation. 76 void Start() override; 77 78 // Flushes the ftrace buffers into the userspace trace buffers and writes 79 // also ftrace stats. 80 void Flush(FlushRequestID, std::function<void()> callback) override; 81 void OnFtraceFlushComplete(FlushRequestID); 82 config_id()83 FtraceConfigId config_id() const { return config_id_; } config()84 const FtraceConfig& config() const { return config_; } parsing_config()85 const FtraceDataSourceConfig* parsing_config() const { 86 return parsing_config_; 87 } 88 mutable_metadata()89 FtraceMetadata* mutable_metadata() { return &metadata_; } mutable_setup_errors()90 FtraceSetupErrors* mutable_setup_errors() { 91 return &stats_before_.setup_errors; 92 } mutable_parse_errors()93 base::FlatSet<protos::pbzero::FtraceParseStatus>* mutable_parse_errors() { 94 return &parse_errors_; 95 } trace_writer()96 TraceWriter* trace_writer() { return writer_.get(); } 97 mutable_bundle_end_timestamp(size_t cpu)98 uint64_t* mutable_bundle_end_timestamp(size_t cpu) { 99 if (cpu >= bundle_end_ts_by_cpu_.size()) 100 bundle_end_ts_by_cpu_.resize(cpu + 1); 101 return &bundle_end_ts_by_cpu_[cpu]; 102 } 103 104 private: 105 void WriteStats(); 106 107 const FtraceConfig config_; 108 FtraceMetadata metadata_; 109 // Stats as saved during data source setup, will be emitted with phase 110 // START_OF_TRACE on every flush: 111 FtraceStats stats_before_{}; 112 // Accumulates errors encountered while parsing the binary ftrace data (e.g. 113 // data disagreeing with our understanding of the ring buffer ABI): 114 base::FlatSet<protos::pbzero::FtraceParseStatus> parse_errors_; 115 std::map<FlushRequestID, std::function<void()>> pending_flushes_; 116 // Remembers, for each per-cpu buffer, the last written event's timestamp. 117 std::vector<uint64_t> bundle_end_ts_by_cpu_; 118 119 // -- Fields initialized by the Initialize() call: 120 FtraceConfigId config_id_ = 0; 121 std::unique_ptr<TraceWriter> writer_; 122 base::WeakPtr<FtraceController> controller_weak_; 123 // Muxer-held state for parsing ftrace according to this data source's 124 // configuration. Not the raw FtraceConfig proto (held by |config_|). 125 const FtraceDataSourceConfig* parsing_config_; 126 // -- End of fields set by Initialize(). 127 }; 128 129 } // namespace perfetto 130 131 #endif // SRC_TRACED_PROBES_FTRACE_FTRACE_DATA_SOURCE_H_ 132