Commit | Line | Data |
---|---|---|
02f1c33f | 1 | # EventClass.py |
b2441318 | 2 | # SPDX-License-Identifier: GPL-2.0 |
02f1c33f | 3 | # |
87b6a3ad | 4 | # This is a library defining some events types classes, which could |
02f1c33f FT |
5 | # be used by other scripts to analyzing the perf samples. |
6 | # | |
7 | # Currently there are just a few classes defined for examples, | |
8 | # PerfEvent is the base class for all perf event sample, PebsEvent | |
9 | # is a HW base Intel x86 PEBS event, and user could add more SW/HW | |
87b6a3ad | 10 | # event classes based on requirements. |
02f1c33f FT |
11 | |
12 | import struct | |
13 | ||
14 | # Event types, user could add more here | |
15 | EVTYPE_GENERIC = 0 | |
16 | EVTYPE_PEBS = 1 # Basic PEBS event | |
17 | EVTYPE_PEBS_LL = 2 # PEBS event with load latency info | |
18 | EVTYPE_IBS = 3 | |
19 | ||
20 | # | |
21 | # Currently we don't have good way to tell the event type, but by | |
22 | # the size of raw buffer, raw PEBS event with load latency data's | |
23 | # size is 176 bytes, while the pure PEBS event's size is 144 bytes. | |
24 | # | |
25 | def create_event(name, comm, dso, symbol, raw_buf): | |
26 | if (len(raw_buf) == 144): | |
27 | event = PebsEvent(name, comm, dso, symbol, raw_buf) | |
28 | elif (len(raw_buf) == 176): | |
29 | event = PebsNHM(name, comm, dso, symbol, raw_buf) | |
30 | else: | |
31 | event = PerfEvent(name, comm, dso, symbol, raw_buf) | |
32 | ||
33 | return event | |
34 | ||
35 | class PerfEvent(object): | |
36 | event_num = 0 | |
37 | def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_GENERIC): | |
38 | self.name = name | |
39 | self.comm = comm | |
40 | self.dso = dso | |
41 | self.symbol = symbol | |
42 | self.raw_buf = raw_buf | |
43 | self.ev_type = ev_type | |
44 | PerfEvent.event_num += 1 | |
45 | ||
46 | def show(self): | |
47 | print "PMU event: name=%12s, symbol=%24s, comm=%8s, dso=%12s" % (self.name, self.symbol, self.comm, self.dso) | |
48 | ||
49 | # | |
50 | # Basic Intel PEBS (Precise Event-based Sampling) event, whose raw buffer | |
51 | # contains the context info when that event happened: the EFLAGS and | |
52 | # linear IP info, as well as all the registers. | |
53 | # | |
54 | class PebsEvent(PerfEvent): | |
55 | pebs_num = 0 | |
56 | def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS): | |
57 | tmp_buf=raw_buf[0:80] | |
58 | flags, ip, ax, bx, cx, dx, si, di, bp, sp = struct.unpack('QQQQQQQQQQ', tmp_buf) | |
59 | self.flags = flags | |
60 | self.ip = ip | |
61 | self.ax = ax | |
62 | self.bx = bx | |
63 | self.cx = cx | |
64 | self.dx = dx | |
65 | self.si = si | |
66 | self.di = di | |
67 | self.bp = bp | |
68 | self.sp = sp | |
69 | ||
70 | PerfEvent.__init__(self, name, comm, dso, symbol, raw_buf, ev_type) | |
71 | PebsEvent.pebs_num += 1 | |
72 | del tmp_buf | |
73 | ||
74 | # | |
75 | # Intel Nehalem and Westmere support PEBS plus Load Latency info which lie | |
76 | # in the four 64 bit words write after the PEBS data: | |
77 | # Status: records the IA32_PERF_GLOBAL_STATUS register value | |
78 | # DLA: Data Linear Address (EIP) | |
79 | # DSE: Data Source Encoding, where the latency happens, hit or miss | |
80 | # in L1/L2/L3 or IO operations | |
81 | # LAT: the actual latency in cycles | |
82 | # | |
83 | class PebsNHM(PebsEvent): | |
84 | pebs_nhm_num = 0 | |
85 | def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS_LL): | |
86 | tmp_buf=raw_buf[144:176] | |
87 | status, dla, dse, lat = struct.unpack('QQQQ', tmp_buf) | |
88 | self.status = status | |
89 | self.dla = dla | |
90 | self.dse = dse | |
91 | self.lat = lat | |
92 | ||
93 | PebsEvent.__init__(self, name, comm, dso, symbol, raw_buf, ev_type) | |
94 | PebsNHM.pebs_nhm_num += 1 | |
95 | del tmp_buf |