1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2015 The Qt Company Ltd 4 ** All rights reserved. 5 ** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us 6 ** 7 ** This file is part of the Qt Enterprise Perf Profiler Add-on. 8 ** 9 ** GNU General Public License Usage 10 ** This file may be used under the terms of the GNU General Public License 11 ** version 3 as published by the Free Software Foundation and appearing in 12 ** the file LICENSE.GPLv3 included in the packaging of this file. Please 13 ** review the following information to ensure the GNU General Public License 14 ** requirements will be met: https://www.gnu.org/licenses/gpl.html. 15 ** 16 ** If you have questions regarding the use of this file, please use 17 ** contact form at http://www.qt.io/contact-us 18 ** 19 ****************************************************************************/ 20 21 #pragma once 22 23 #include "perffilesection.h" 24 #include "perfheader.h" 25 26 #include <QDataStream> 27 #include <QHash> 28 #include <QIODevice> 29 30 class PerfEventAttributes { 31 public: 32 enum Sizes { 33 SIZE_VER0 = 64, /* sizeof first published struct */ 34 SIZE_VER1 = 72, /* add: config2 */ 35 SIZE_VER2 = 80, /* add: branch_sample_type */ 36 SIZE_VER3 = 96, /* add: sample_regs_user, sample_stack_user */ 37 SIZE_VER4 = 104, /* add: sample_regs_intr */ 38 SIZE_VER5 = 112, /* add: aux_watermark */ 39 }; 40 41 PerfEventAttributes(); 42 sampleIdAll()43 bool sampleIdAll() const { return m_sampleIdAll; } sampleType()44 quint64 sampleType() const { return m_sampleType; } readFormat()45 quint64 readFormat() const { return m_readFormat; } sampleRegsUser()46 quint64 sampleRegsUser() const { return m_sampleRegsUser; } size()47 quint32 size() const { return m_size; } type()48 quint32 type() const { return m_type; } config()49 quint64 config() const { return m_config; } 50 int sampleIdOffset() const; usesFrequency()51 bool usesFrequency() const { return m_freq; }; frequenyOrPeriod()52 quint64 frequenyOrPeriod() const { return m_sampleFreq; } 53 54 QByteArray name() const; 55 56 enum ReadFormat { 57 FORMAT_TOTAL_TIME_ENABLED = 1U << 0, 58 FORMAT_TOTAL_TIME_RUNNING = 1U << 1, 59 FORMAT_ID = 1U << 2, 60 FORMAT_GROUP = 1U << 3, 61 62 FORMAT_MAX = 1U << 4 63 }; 64 65 /* 66 * Bits that can be set in sampleType to request information 67 * in the overflow packets. 68 */ 69 enum SampleFormat { 70 SAMPLE_IP = 1U << 0, 71 SAMPLE_TID = 1U << 1, 72 SAMPLE_TIME = 1U << 2, 73 SAMPLE_ADDR = 1U << 3, 74 SAMPLE_READ = 1U << 4, 75 SAMPLE_CALLCHAIN = 1U << 5, 76 SAMPLE_ID = 1U << 6, 77 SAMPLE_CPU = 1U << 7, 78 SAMPLE_PERIOD = 1U << 8, 79 SAMPLE_STREAM_ID = 1U << 9, 80 SAMPLE_RAW = 1U << 10, 81 SAMPLE_BRANCH_STACK = 1U << 11, 82 SAMPLE_REGS_USER = 1U << 12, 83 SAMPLE_STACK_USER = 1U << 13, 84 SAMPLE_WEIGHT = 1U << 14, 85 SAMPLE_DATA_SRC = 1U << 15, 86 SAMPLE_IDENTIFIER = 1U << 16, 87 SAMPLE_TRANSACTION = 1U << 17, 88 89 SAMPLE_MAX = 1U << 18, 90 SAMPLE_ID_ALL = 1U << 31 // extra flag, to check if the sample has a sample ID at all 91 }; 92 93 /* 94 * attr.type() 95 */ 96 enum TypeId { 97 TYPE_HARDWARE = 0, 98 TYPE_SOFTWARE = 1, 99 TYPE_TRACEPOINT = 2, 100 TYPE_HARDWARE_CACHE = 3, 101 TYPE_RAW = 4, 102 TYPE_BREAKPOINT = 5, 103 TYPE_MAX, /* non-ABI */ 104 }; 105 106 /* 107 * Generalized performance event eventId types, used by the 108 * attr.event_id parameter of the sys_perf_event_open() 109 * syscall. 110 * 111 * Ends up in attr.config() if type() is TYPE_HARDWARE 112 */ 113 enum HardwareId { 114 /* 115 * Common hardware events, generalized by the kernel: 116 */ 117 HARDWARE_CPU_CYCLES = 0, 118 HARDWARE_INSTRUCTIONS = 1, 119 HARDWARE_CACHE_REFERENCES = 2, 120 HARDWARE_CACHE_MISSES = 3, 121 HARDWARE_BRANCH_INSTRUCTIONS = 4, 122 HARDWARE_BRANCH_MISSES = 5, 123 HARDWARE_BUS_CYCLES = 6, 124 HARDWARE_STALLED_CYCLES_FRONTEND = 7, 125 HARDWARE_STALLED_CYCLES_BACKEND = 8, 126 HARDWARE_REF_CPU_CYCLES = 9, 127 HARDWARE_MAX, /* non-ABI */ 128 }; 129 130 /* 131 * Generalized hardware cache events: 132 * 133 * attr.config() for type() == TYPE_HW_CACHE. 134 * 135 * Encoding is (cacheId | (cacheOpId << 8) | (cacheOpResultId << 16)) 136 * for example -e L1-dcache-store-misses results in config == 0x10100, or 137 * -e LLC-loads in config == 0x000002. 138 */ 139 enum HardwareCacheId { 140 HARDWARE_CACHE_L1D = 0, 141 HARDWARE_CACHE_L1I = 1, 142 HARDWARE_CACHE_LL = 2, 143 HARDWARE_CACHE_DTLB = 3, 144 HARDWARE_CACHE_ITLB = 4, 145 HARDWARE_CACHE_BPU = 5, 146 HARDWARE_CACHE_NODE = 6, 147 148 HARDWARE_CACHE_MAX, /* non-ABI */ 149 }; 150 151 enum HardwareCacheOperationId { 152 HARDWARE_CACHE_OPERATION_READ = 0, 153 HARDWARE_CACHE_OPERATION_WRITE = 1, 154 HARDWARE_CACHE_OPERATION_PREFETCH = 2, 155 HARDWARE_CACHE_OPERATION_MAX, /* non-ABI */ 156 }; 157 158 enum HardwareCacheOperationResultId { 159 HARDWARE_CACHE_RESULT_OPERATION_ACCESS = 0, 160 HARDWARE_CACHE_RESULT_OPERATION_MISS = 1, 161 HARDWARE_CACHE_RESULT_OPERATION_MAX, /* non-ABI */ 162 }; 163 164 /* 165 * Special "software" events provided by the kernel, even if the hardware 166 * does not support performance events. These events measure various 167 * physical and sw events of the kernel (and allow the profiling of them as 168 * well): 169 */ 170 enum SoftwareId { 171 SOFTWARE_CPU_CLOCK = 0, 172 SOFTWARE_TASK_CLOCK = 1, 173 SOFTWARE_PAGE_FAULTS = 2, 174 SOFTWARE_CONTEXT_SWITCHES = 3, 175 SOFTWARE_CPU_MIGRATIONS = 4, 176 SOFTWARE_PAGE_FAULTS_MIN = 5, 177 SOFTWARE_PAGE_FAULTS_MAJ = 6, 178 SOFTWARE_ALIGNMENT_FAULTS = 7, 179 SOFTWARE_EMULATION_FAULTS = 8, 180 SOFTWARE_DUMMY = 9, 181 SOFTWARE_MAX, /* non-ABI */ 182 }; 183 184 bool operator==(const PerfEventAttributes &rhs) const; 185 186 private: 187 188 /* 189 * Major type: hardware/software/tracepoint/etc. 190 */ 191 quint32 m_type; 192 193 /* 194 * Size of the attr structure, for fwd/bwd compat. 195 */ 196 quint32 m_size; 197 198 /* 199 * Type specific configuration information. 200 */ 201 quint64 m_config; 202 203 union { 204 quint64 m_samplePeriod; 205 quint64 m_sampleFreq; 206 }; 207 208 quint64 m_sampleType; 209 quint64 m_readFormat; 210 211 quint64 m_disabled : 1, /* off by default */ 212 m_inherit : 1, /* children inherit it */ 213 m_pinned : 1, /* must always be on PMU */ 214 m_exclusive : 1, /* only group on PMU */ 215 m_excludeUser : 1, /* don't count user */ 216 m_excludeKernel : 1, /* ditto kernel */ 217 m_excludeHv : 1, /* ditto hypervisor */ 218 m_excludeIdle : 1, /* don't count when idle */ 219 m_mmap : 1, /* include mmap data */ 220 m_comm : 1, /* include comm data */ 221 m_freq : 1, /* use freq, not period */ 222 m_inheritStat : 1, /* per task counts */ 223 m_enableOnExec : 1, /* next exec enables */ 224 m_task : 1, /* trace fork/exit */ 225 m_watermark : 1, /* wakeup_watermark */ 226 /* 227 * m_preciseIp: 228 * 229 * 0 - SAMPLE_IP can have arbitrary skid 230 * 1 - SAMPLE_IP must have constant skid 231 * 2 - SAMPLE_IP requested to have 0 skid 232 * 3 - SAMPLE_IP must have 0 skid 233 * 234 * See also PERF_RECORD_MISC_EXACT_IP 235 */ 236 m_preciseIp : 2, /* skid constraint */ 237 m_mmapData : 1, /* non-exec mmap data */ 238 m_sampleIdAll : 1, /* sample_type all events */ 239 240 m_excludeHost : 1, /* don't count in host */ 241 m_excludeGuest : 1, /* don't count in guest */ 242 243 /* m_excludeCallchainKernel */ : 1, /* exclude kernel callchains */ 244 /* m_excludeCallchainUser */ : 1, /* exclude user callchains */ 245 246 m_reserved1 : 41; 247 248 union { 249 quint32 m_wakeupEvents; /* wakeup every n events */ 250 quint32 m_wakeupWatermark; /* bytes before wakeup */ 251 }; 252 253 quint32 m_bpType; 254 union { 255 quint64 m_bpAddr; 256 quint64 m_config1; /* extension of config */ 257 }; 258 259 union { 260 quint64 m_bpLen; 261 quint64 m_config2; /* extension of config1 */ 262 }; 263 264 quint64 m_branchSampleType; /* enum perf_branch_sample_type */ 265 266 /* 267 * Defines set of user regs to dump on samples. 268 * See asm/perf_regs.h for details. 269 */ 270 quint64 m_sampleRegsUser; 271 272 /* 273 * Defines size of the user stack to dump on samples. 274 */ 275 quint32 m_sampleStackUser; 276 277 qint32 m_clockid; 278 279 /* 280 * Defines set of regs to dump for each sample 281 * state captured on: 282 * - precise = 0: PMU interrupt 283 * - precise > 0: sampled instruction 284 * 285 * See asm/perf_regs.h for details. 286 */ 287 quint64 m_sampleRegsIntr; 288 289 /* 290 * Wakeup watermark for AUX area 291 */ 292 quint32 m_auxWatermark; 293 quint16 m_sampleMaxStack; 294 295 /* Align to u64. */ 296 quint16 m_reserved2; 297 298 friend QDataStream &operator>>(QDataStream &stream, PerfEventAttributes &attrs); 299 }; 300 301 QDataStream &operator>>(QDataStream &stream, PerfEventAttributes &attrs); 302 303 class PerfAttributes { 304 public: 305 bool read(QIODevice *device, PerfHeader *header); 306 void addAttributes(quint64 id, const PerfEventAttributes &attributes); 307 void setGlobalAttributes(const PerfEventAttributes &attributes); 308 attributes()309 const QHash<quint64, PerfEventAttributes> &attributes() const { return m_attributes; } 310 const PerfEventAttributes &attributes(quint64 id) const; globalAttributes()311 const PerfEventAttributes &globalAttributes() const { return m_globalAttributes; } 312 313 private: 314 PerfEventAttributes m_globalAttributes; 315 QHash<quint64, PerfEventAttributes> m_attributes; 316 }; 317