1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROMIUMOS_WIDE_PROFILING_PERF_SERIALIZER_H_ 6 #define CHROMIUMOS_WIDE_PROFILING_PERF_SERIALIZER_H_ 7 8 #include <stdint.h> 9 #include <sys/types.h> 10 11 #include <map> 12 #include <memory> 13 #include <vector> 14 15 #include "base/macros.h" 16 17 #include "compat/proto.h" 18 #include "compat/string.h" 19 #include "perf_data_utils.h" 20 21 struct perf_event_attr; 22 23 namespace quipper { 24 25 struct ParsedEvent; 26 struct PerfFileAttr; 27 struct PerfGroupDescMetadata; 28 struct PerfPMUMappingsMetadata; 29 struct PerfNodeTopologyMetadata; 30 struct PerfCPUTopologyMetadata; 31 struct PerfEventStats; 32 struct PerfParserOptions; 33 struct PerfUint32Metadata; 34 struct PerfUint64Metadata; 35 36 class SampleInfoReader; 37 38 class PerfSerializer { 39 public: 40 PerfSerializer(); 41 ~PerfSerializer(); 42 43 // The following functions convert between raw perf data structures and their 44 // equivalent PerfDataProto representations. 45 bool SerializePerfFileAttr( 46 const PerfFileAttr& perf_file_attr, 47 PerfDataProto_PerfFileAttr* perf_file_attr_proto) const; 48 bool DeserializePerfFileAttr( 49 const PerfDataProto_PerfFileAttr& perf_file_attr_proto, 50 PerfFileAttr* perf_file_attr) const; 51 52 bool SerializePerfEventAttr( 53 const perf_event_attr& perf_event_attr, 54 PerfDataProto_PerfEventAttr* perf_event_attr_proto) const; 55 bool DeserializePerfEventAttr( 56 const PerfDataProto_PerfEventAttr& perf_event_attr_proto, 57 perf_event_attr* perf_event_attr) const; 58 59 bool SerializePerfEventType( 60 const PerfFileAttr& event_attr, 61 PerfDataProto_PerfEventType* event_type_proto) const; 62 bool DeserializePerfEventType( 63 const PerfDataProto_PerfEventType& event_type_proto, 64 PerfFileAttr* event_attr) const; 65 66 bool SerializeEvent(const malloced_unique_ptr<event_t>& event_ptr, 67 PerfDataProto_PerfEvent* event_proto) const; 68 bool DeserializeEvent(const PerfDataProto_PerfEvent& event_proto, 69 malloced_unique_ptr<event_t>* event_ptr) const; 70 bool SerializeEventHeader(const perf_event_header& header, 71 PerfDataProto_EventHeader* header_proto) const; 72 bool DeserializeEventHeader(const PerfDataProto_EventHeader& header_proto, 73 perf_event_header* header) const; 74 75 bool SerializeSampleEvent(const event_t& event, 76 PerfDataProto_SampleEvent* sample) const; 77 bool DeserializeSampleEvent(const PerfDataProto_SampleEvent& sample, 78 event_t* event) const; 79 80 bool SerializeMMapEvent(const event_t& event, 81 PerfDataProto_MMapEvent* sample) const; 82 bool DeserializeMMapEvent(const PerfDataProto_MMapEvent& sample, 83 event_t* event) const; 84 85 bool SerializeMMap2Event(const event_t& event, 86 PerfDataProto_MMapEvent* sample) const; 87 bool DeserializeMMap2Event(const PerfDataProto_MMapEvent& sample, 88 event_t* event) const; 89 90 bool SerializeCommEvent(const event_t& event, 91 PerfDataProto_CommEvent* sample) const; 92 bool DeserializeCommEvent(const PerfDataProto_CommEvent& sample, 93 event_t* event) const; 94 95 // These handle both fork and exit events, which use the same protobuf 96 // message definition. 97 bool SerializeForkExitEvent(const event_t& event, 98 PerfDataProto_ForkEvent* sample) const; 99 bool DeserializeForkExitEvent(const PerfDataProto_ForkEvent& sample, 100 event_t* event) const; 101 102 bool SerializeLostEvent(const event_t& event, 103 PerfDataProto_LostEvent* sample) const; 104 bool DeserializeLostEvent(const PerfDataProto_LostEvent& sample, 105 event_t* event) const; 106 107 bool SerializeThrottleEvent(const event_t& event, 108 PerfDataProto_ThrottleEvent* sample) const; 109 bool DeserializeThrottleEvent(const PerfDataProto_ThrottleEvent& sample, 110 event_t* event) const; 111 112 bool SerializeReadEvent(const event_t& event, 113 PerfDataProto_ReadEvent* sample) const; 114 bool DeserializeReadEvent(const PerfDataProto_ReadEvent& sample, 115 event_t* event) const; 116 117 bool SerializeAuxEvent(const event_t& event, 118 PerfDataProto_AuxEvent* sample) const; 119 bool DeserializeAuxEvent(const PerfDataProto_AuxEvent& sample, 120 event_t* event) const; 121 122 bool SerializeSampleInfo(const event_t& event, 123 PerfDataProto_SampleInfo* sample_info) const; 124 bool DeserializeSampleInfo(const PerfDataProto_SampleInfo& info, 125 event_t* event) const; 126 127 bool SerializeTracingMetadata(const std::vector<char>& from, 128 PerfDataProto* to) const; 129 bool DeserializeTracingMetadata(const PerfDataProto& from, 130 std::vector<char>* to) const; 131 132 bool SerializeBuildIDEvent(const malloced_unique_ptr<build_id_event>& from, 133 PerfDataProto_PerfBuildID* to) const; 134 bool DeserializeBuildIDEvent(const PerfDataProto_PerfBuildID& from, 135 malloced_unique_ptr<build_id_event>* to) const; 136 137 bool SerializeAuxtraceEvent(const event_t& event, 138 PerfDataProto_AuxtraceEvent* sample) const; 139 bool SerializeAuxtraceEventTraceData(const std::vector<char>& from, 140 PerfDataProto_AuxtraceEvent* to) const; 141 bool DeserializeAuxtraceEvent(const PerfDataProto_AuxtraceEvent& sample, 142 event_t* event) const; 143 bool DeserializeAuxtraceEventTraceData( 144 const PerfDataProto_AuxtraceEvent& from, std::vector<char>* to) const; 145 146 bool SerializeSingleUint32Metadata( 147 const PerfUint32Metadata& metadata, 148 PerfDataProto_PerfUint32Metadata* proto_metadata) const; 149 bool DeserializeSingleUint32Metadata( 150 const PerfDataProto_PerfUint32Metadata& proto_metadata, 151 PerfUint32Metadata* metadata) const; 152 153 bool SerializeSingleUint64Metadata( 154 const PerfUint64Metadata& metadata, 155 PerfDataProto_PerfUint64Metadata* proto_metadata) const; 156 bool DeserializeSingleUint64Metadata( 157 const PerfDataProto_PerfUint64Metadata& proto_metadata, 158 PerfUint64Metadata* metadata) const; 159 160 bool SerializeCPUTopologyMetadata( 161 const PerfCPUTopologyMetadata& metadata, 162 PerfDataProto_PerfCPUTopologyMetadata* proto_metadata) const; 163 bool DeserializeCPUTopologyMetadata( 164 const PerfDataProto_PerfCPUTopologyMetadata& proto_metadata, 165 PerfCPUTopologyMetadata* metadata) const; 166 167 bool SerializeNodeTopologyMetadata( 168 const PerfNodeTopologyMetadata& metadata, 169 PerfDataProto_PerfNodeTopologyMetadata* proto_metadata) const; 170 bool DeserializeNodeTopologyMetadata( 171 const PerfDataProto_PerfNodeTopologyMetadata& proto_metadata, 172 PerfNodeTopologyMetadata* metadata) const; 173 174 bool SerializePMUMappingsMetadata( 175 const PerfPMUMappingsMetadata& metadata, 176 PerfDataProto_PerfPMUMappingsMetadata* proto_metadata) const; 177 bool DeserializePMUMappingsMetadata( 178 const PerfDataProto_PerfPMUMappingsMetadata& proto_metadata, 179 PerfPMUMappingsMetadata* metadata) const; 180 181 bool SerializeGroupDescMetadata( 182 const PerfGroupDescMetadata& metadata, 183 PerfDataProto_PerfGroupDescMetadata* proto_metadata) const; 184 bool DeserializeGroupDescMetadata( 185 const PerfDataProto_PerfGroupDescMetadata& proto_metadata, 186 PerfGroupDescMetadata* metadata) const; 187 188 static void SerializeParserStats(const PerfEventStats& stats, 189 PerfDataProto* perf_data_proto); 190 static void DeserializeParserStats(const PerfDataProto& perf_data_proto, 191 PerfEventStats* stats); 192 193 // Instantiate a new PerfSampleReader with the given attr type. If an old one 194 // exists for that attr type, it is discarded. 195 void CreateSampleInfoReader(const PerfFileAttr& event_attr, 196 bool read_cross_endian); 197 198 bool SampleInfoReaderAvailable() const { 199 return !sample_info_reader_map_.empty(); 200 } 201 202 private: 203 // Special values for the event/other_event_id_pos_ fields. 204 enum EventIdPosition { 205 Uninitialized = -2, 206 NotPresent = -1, 207 }; 208 209 // Given a perf_event_attr, determines the offset of the ID field within an 210 // event, relative to the start of sample info within an event. All attrs must 211 // have the same ID field offset. 212 void UpdateEventIdPositions(const struct perf_event_attr& attr); 213 214 // Do non-SAMPLE events have a sample_id? Reflects the value of 215 // sample_id_all in the first attr, which should be consistent accross all 216 // attrs. 217 bool SampleIdAll() const; 218 219 // Find the event id in the event, and returns the corresponding 220 // SampleInfoReader. Returns nullptr if a SampleInfoReader could not be found. 221 const SampleInfoReader* GetSampleInfoReaderForEvent( 222 const event_t& event) const; 223 224 // Returns the SampleInfoReader associated with the given perf event ID, or 225 // nullptr if none exists. |id| == 0 means there is no attr ID for each event 226 // that associates it with a particular SampleInfoReader, in which case the 227 // first available SampleInfoReader is returned. 228 const SampleInfoReader* GetSampleInfoReaderForId(uint64_t id) const; 229 230 // Reads the sample info fields from |event| into |sample_info|. If more than 231 // one type of perf event attr is present, will pick the correct one. Also 232 // returns a bitfield of available sample info fields for the attr, in 233 // |sample_type|. 234 // Returns true if successfully read. 235 bool ReadPerfSampleInfoAndType(const event_t& event, perf_sample* sample_info, 236 uint64_t* sample_type) const; 237 238 bool SerializeKernelEvent(const event_t& event, 239 PerfDataProto_PerfEvent* event_proto) const; 240 bool SerializeUserEvent(const event_t& event, 241 PerfDataProto_PerfEvent* event_proto) const; 242 243 bool DeserializeKernelEvent(const PerfDataProto_PerfEvent& event_proto, 244 event_t* event) const; 245 bool DeserializeUserEvent(const PerfDataProto_PerfEvent& event_proto, 246 event_t* event) const; 247 248 // For SAMPLE events, the position of the sample id, 249 // Or EventIdPosition::NotPresent if neither PERF_SAMPLE_ID(ENTIFIER) are set. 250 // (Corresponds to evsel->id_pos in perf) 251 ssize_t sample_event_id_pos_ = EventIdPosition::Uninitialized; 252 // For non-SAMPLE events, the position of the sample id, counting backwards 253 // from the end of the event. 254 // Or EventIdPosition::NotPresent if neither PERF_SAMPLE_ID(ENTIFIER) are set. 255 // (Corresponds to evsel->is_pos in perf) 256 ssize_t other_event_id_pos_ = EventIdPosition::Uninitialized; 257 258 // For each perf event attr ID, there is a SampleInfoReader to read events of 259 // the associated perf attr type. 260 std::map<uint64_t, std::unique_ptr<SampleInfoReader>> sample_info_reader_map_; 261 262 DISALLOW_COPY_AND_ASSIGN(PerfSerializer); 263 }; 264 265 } // namespace quipper 266 267 #endif // CHROMIUMOS_WIDE_PROFILING_PERF_SERIALIZER_H_ 268