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