Adding upstream version 6.12.33.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
89eabb05c2
commit
79d69e5050
86698 changed files with 39662057 additions and 0 deletions
116
tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py
Normal file
116
tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py
Normal file
|
@ -0,0 +1,116 @@
|
|||
# Core.py - Python extension for perf script, core functions
|
||||
#
|
||||
# Copyright (C) 2010 by Tom Zanussi <tzanussi@gmail.com>
|
||||
#
|
||||
# This software may be distributed under the terms of the GNU General
|
||||
# Public License ("GPL") version 2 as published by the Free Software
|
||||
# Foundation.
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
def autodict():
|
||||
return defaultdict(autodict)
|
||||
|
||||
flag_fields = autodict()
|
||||
symbolic_fields = autodict()
|
||||
|
||||
def define_flag_field(event_name, field_name, delim):
|
||||
flag_fields[event_name][field_name]['delim'] = delim
|
||||
|
||||
def define_flag_value(event_name, field_name, value, field_str):
|
||||
flag_fields[event_name][field_name]['values'][value] = field_str
|
||||
|
||||
def define_symbolic_field(event_name, field_name):
|
||||
# nothing to do, really
|
||||
pass
|
||||
|
||||
def define_symbolic_value(event_name, field_name, value, field_str):
|
||||
symbolic_fields[event_name][field_name]['values'][value] = field_str
|
||||
|
||||
def flag_str(event_name, field_name, value):
|
||||
string = ""
|
||||
|
||||
if flag_fields[event_name][field_name]:
|
||||
print_delim = 0
|
||||
for idx in sorted(flag_fields[event_name][field_name]['values']):
|
||||
if not value and not idx:
|
||||
string += flag_fields[event_name][field_name]['values'][idx]
|
||||
break
|
||||
if idx and (value & idx) == idx:
|
||||
if print_delim and flag_fields[event_name][field_name]['delim']:
|
||||
string += " " + flag_fields[event_name][field_name]['delim'] + " "
|
||||
string += flag_fields[event_name][field_name]['values'][idx]
|
||||
print_delim = 1
|
||||
value &= ~idx
|
||||
|
||||
return string
|
||||
|
||||
def symbol_str(event_name, field_name, value):
|
||||
string = ""
|
||||
|
||||
if symbolic_fields[event_name][field_name]:
|
||||
for idx in sorted(symbolic_fields[event_name][field_name]['values']):
|
||||
if not value and not idx:
|
||||
string = symbolic_fields[event_name][field_name]['values'][idx]
|
||||
break
|
||||
if (value == idx):
|
||||
string = symbolic_fields[event_name][field_name]['values'][idx]
|
||||
break
|
||||
|
||||
return string
|
||||
|
||||
trace_flags = { 0x00: "NONE", \
|
||||
0x01: "IRQS_OFF", \
|
||||
0x02: "IRQS_NOSUPPORT", \
|
||||
0x04: "NEED_RESCHED", \
|
||||
0x08: "HARDIRQ", \
|
||||
0x10: "SOFTIRQ" }
|
||||
|
||||
def trace_flag_str(value):
|
||||
string = ""
|
||||
print_delim = 0
|
||||
|
||||
for idx in trace_flags:
|
||||
if not value and not idx:
|
||||
string += "NONE"
|
||||
break
|
||||
|
||||
if idx and (value & idx) == idx:
|
||||
if print_delim:
|
||||
string += " | ";
|
||||
string += trace_flags[idx]
|
||||
print_delim = 1
|
||||
value &= ~idx
|
||||
|
||||
return string
|
||||
|
||||
|
||||
def taskState(state):
|
||||
states = {
|
||||
0 : "R",
|
||||
1 : "S",
|
||||
2 : "D",
|
||||
64: "DEAD"
|
||||
}
|
||||
|
||||
if state not in states:
|
||||
return "Unknown"
|
||||
|
||||
return states[state]
|
||||
|
||||
|
||||
class EventHeaders:
|
||||
def __init__(self, common_cpu, common_secs, common_nsecs,
|
||||
common_pid, common_comm, common_callchain):
|
||||
self.cpu = common_cpu
|
||||
self.secs = common_secs
|
||||
self.nsecs = common_nsecs
|
||||
self.pid = common_pid
|
||||
self.comm = common_comm
|
||||
self.callchain = common_callchain
|
||||
|
||||
def ts(self):
|
||||
return (self.secs * (10 ** 9)) + self.nsecs
|
||||
|
||||
def ts_format(self):
|
||||
return "%d.%d" % (self.secs, int(self.nsecs / 1000))
|
97
tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
Executable file
97
tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
Executable file
|
@ -0,0 +1,97 @@
|
|||
# EventClass.py
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# This is a library defining some events types classes, which could
|
||||
# be used by other scripts to analyzing the perf samples.
|
||||
#
|
||||
# Currently there are just a few classes defined for examples,
|
||||
# PerfEvent is the base class for all perf event sample, PebsEvent
|
||||
# is a HW base Intel x86 PEBS event, and user could add more SW/HW
|
||||
# event classes based on requirements.
|
||||
from __future__ import print_function
|
||||
|
||||
import struct
|
||||
|
||||
# Event types, user could add more here
|
||||
EVTYPE_GENERIC = 0
|
||||
EVTYPE_PEBS = 1 # Basic PEBS event
|
||||
EVTYPE_PEBS_LL = 2 # PEBS event with load latency info
|
||||
EVTYPE_IBS = 3
|
||||
|
||||
#
|
||||
# Currently we don't have good way to tell the event type, but by
|
||||
# the size of raw buffer, raw PEBS event with load latency data's
|
||||
# size is 176 bytes, while the pure PEBS event's size is 144 bytes.
|
||||
#
|
||||
def create_event(name, comm, dso, symbol, raw_buf):
|
||||
if (len(raw_buf) == 144):
|
||||
event = PebsEvent(name, comm, dso, symbol, raw_buf)
|
||||
elif (len(raw_buf) == 176):
|
||||
event = PebsNHM(name, comm, dso, symbol, raw_buf)
|
||||
else:
|
||||
event = PerfEvent(name, comm, dso, symbol, raw_buf)
|
||||
|
||||
return event
|
||||
|
||||
class PerfEvent(object):
|
||||
event_num = 0
|
||||
def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_GENERIC):
|
||||
self.name = name
|
||||
self.comm = comm
|
||||
self.dso = dso
|
||||
self.symbol = symbol
|
||||
self.raw_buf = raw_buf
|
||||
self.ev_type = ev_type
|
||||
PerfEvent.event_num += 1
|
||||
|
||||
def show(self):
|
||||
print("PMU event: name=%12s, symbol=%24s, comm=%8s, dso=%12s" %
|
||||
(self.name, self.symbol, self.comm, self.dso))
|
||||
|
||||
#
|
||||
# Basic Intel PEBS (Precise Event-based Sampling) event, whose raw buffer
|
||||
# contains the context info when that event happened: the EFLAGS and
|
||||
# linear IP info, as well as all the registers.
|
||||
#
|
||||
class PebsEvent(PerfEvent):
|
||||
pebs_num = 0
|
||||
def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS):
|
||||
tmp_buf=raw_buf[0:80]
|
||||
flags, ip, ax, bx, cx, dx, si, di, bp, sp = struct.unpack('QQQQQQQQQQ', tmp_buf)
|
||||
self.flags = flags
|
||||
self.ip = ip
|
||||
self.ax = ax
|
||||
self.bx = bx
|
||||
self.cx = cx
|
||||
self.dx = dx
|
||||
self.si = si
|
||||
self.di = di
|
||||
self.bp = bp
|
||||
self.sp = sp
|
||||
|
||||
PerfEvent.__init__(self, name, comm, dso, symbol, raw_buf, ev_type)
|
||||
PebsEvent.pebs_num += 1
|
||||
del tmp_buf
|
||||
|
||||
#
|
||||
# Intel Nehalem and Westmere support PEBS plus Load Latency info which lie
|
||||
# in the four 64 bit words write after the PEBS data:
|
||||
# Status: records the IA32_PERF_GLOBAL_STATUS register value
|
||||
# DLA: Data Linear Address (EIP)
|
||||
# DSE: Data Source Encoding, where the latency happens, hit or miss
|
||||
# in L1/L2/L3 or IO operations
|
||||
# LAT: the actual latency in cycles
|
||||
#
|
||||
class PebsNHM(PebsEvent):
|
||||
pebs_nhm_num = 0
|
||||
def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS_LL):
|
||||
tmp_buf=raw_buf[144:176]
|
||||
status, dla, dse, lat = struct.unpack('QQQQ', tmp_buf)
|
||||
self.status = status
|
||||
self.dla = dla
|
||||
self.dse = dse
|
||||
self.lat = lat
|
||||
|
||||
PebsEvent.__init__(self, name, comm, dso, symbol, raw_buf, ev_type)
|
||||
PebsNHM.pebs_nhm_num += 1
|
||||
del tmp_buf
|
|
@ -0,0 +1,184 @@
|
|||
# SchedGui.py - Python extension for perf script, basic GUI code for
|
||||
# traces drawing and overview.
|
||||
#
|
||||
# Copyright (C) 2010 by Frederic Weisbecker <fweisbec@gmail.com>
|
||||
#
|
||||
# This software is distributed under the terms of the GNU General
|
||||
# Public License ("GPL") version 2 as published by the Free Software
|
||||
# Foundation.
|
||||
|
||||
|
||||
try:
|
||||
import wx
|
||||
except ImportError:
|
||||
raise ImportError("You need to install the wxpython lib for this script")
|
||||
|
||||
|
||||
class RootFrame(wx.Frame):
|
||||
Y_OFFSET = 100
|
||||
RECT_HEIGHT = 100
|
||||
RECT_SPACE = 50
|
||||
EVENT_MARKING_WIDTH = 5
|
||||
|
||||
def __init__(self, sched_tracer, title, parent = None, id = -1):
|
||||
wx.Frame.__init__(self, parent, id, title)
|
||||
|
||||
(self.screen_width, self.screen_height) = wx.GetDisplaySize()
|
||||
self.screen_width -= 10
|
||||
self.screen_height -= 10
|
||||
self.zoom = 0.5
|
||||
self.scroll_scale = 20
|
||||
self.sched_tracer = sched_tracer
|
||||
self.sched_tracer.set_root_win(self)
|
||||
(self.ts_start, self.ts_end) = sched_tracer.interval()
|
||||
self.update_width_virtual()
|
||||
self.nr_rects = sched_tracer.nr_rectangles() + 1
|
||||
self.height_virtual = RootFrame.Y_OFFSET + (self.nr_rects * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
|
||||
|
||||
# whole window panel
|
||||
self.panel = wx.Panel(self, size=(self.screen_width, self.screen_height))
|
||||
|
||||
# scrollable container
|
||||
self.scroll = wx.ScrolledWindow(self.panel)
|
||||
self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale)
|
||||
self.scroll.EnableScrolling(True, True)
|
||||
self.scroll.SetFocus()
|
||||
|
||||
# scrollable drawing area
|
||||
self.scroll_panel = wx.Panel(self.scroll, size=(self.screen_width - 15, self.screen_height / 2))
|
||||
self.scroll_panel.Bind(wx.EVT_PAINT, self.on_paint)
|
||||
self.scroll_panel.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
|
||||
self.scroll_panel.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
|
||||
self.scroll.Bind(wx.EVT_PAINT, self.on_paint)
|
||||
self.scroll.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
|
||||
self.scroll.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
|
||||
|
||||
self.scroll.Fit()
|
||||
self.Fit()
|
||||
|
||||
self.scroll_panel.SetDimensions(-1, -1, self.width_virtual, self.height_virtual, wx.SIZE_USE_EXISTING)
|
||||
|
||||
self.txt = None
|
||||
|
||||
self.Show(True)
|
||||
|
||||
def us_to_px(self, val):
|
||||
return val / (10 ** 3) * self.zoom
|
||||
|
||||
def px_to_us(self, val):
|
||||
return (val / self.zoom) * (10 ** 3)
|
||||
|
||||
def scroll_start(self):
|
||||
(x, y) = self.scroll.GetViewStart()
|
||||
return (x * self.scroll_scale, y * self.scroll_scale)
|
||||
|
||||
def scroll_start_us(self):
|
||||
(x, y) = self.scroll_start()
|
||||
return self.px_to_us(x)
|
||||
|
||||
def paint_rectangle_zone(self, nr, color, top_color, start, end):
|
||||
offset_px = self.us_to_px(start - self.ts_start)
|
||||
width_px = self.us_to_px(end - self.ts_start)
|
||||
|
||||
offset_py = RootFrame.Y_OFFSET + (nr * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
|
||||
width_py = RootFrame.RECT_HEIGHT
|
||||
|
||||
dc = self.dc
|
||||
|
||||
if top_color is not None:
|
||||
(r, g, b) = top_color
|
||||
top_color = wx.Colour(r, g, b)
|
||||
brush = wx.Brush(top_color, wx.SOLID)
|
||||
dc.SetBrush(brush)
|
||||
dc.DrawRectangle(offset_px, offset_py, width_px, RootFrame.EVENT_MARKING_WIDTH)
|
||||
width_py -= RootFrame.EVENT_MARKING_WIDTH
|
||||
offset_py += RootFrame.EVENT_MARKING_WIDTH
|
||||
|
||||
(r ,g, b) = color
|
||||
color = wx.Colour(r, g, b)
|
||||
brush = wx.Brush(color, wx.SOLID)
|
||||
dc.SetBrush(brush)
|
||||
dc.DrawRectangle(offset_px, offset_py, width_px, width_py)
|
||||
|
||||
def update_rectangles(self, dc, start, end):
|
||||
start += self.ts_start
|
||||
end += self.ts_start
|
||||
self.sched_tracer.fill_zone(start, end)
|
||||
|
||||
def on_paint(self, event):
|
||||
dc = wx.PaintDC(self.scroll_panel)
|
||||
self.dc = dc
|
||||
|
||||
width = min(self.width_virtual, self.screen_width)
|
||||
(x, y) = self.scroll_start()
|
||||
start = self.px_to_us(x)
|
||||
end = self.px_to_us(x + width)
|
||||
self.update_rectangles(dc, start, end)
|
||||
|
||||
def rect_from_ypixel(self, y):
|
||||
y -= RootFrame.Y_OFFSET
|
||||
rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
|
||||
height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
|
||||
|
||||
if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT:
|
||||
return -1
|
||||
|
||||
return rect
|
||||
|
||||
def update_summary(self, txt):
|
||||
if self.txt:
|
||||
self.txt.Destroy()
|
||||
self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50))
|
||||
|
||||
|
||||
def on_mouse_down(self, event):
|
||||
(x, y) = event.GetPositionTuple()
|
||||
rect = self.rect_from_ypixel(y)
|
||||
if rect == -1:
|
||||
return
|
||||
|
||||
t = self.px_to_us(x) + self.ts_start
|
||||
|
||||
self.sched_tracer.mouse_down(rect, t)
|
||||
|
||||
|
||||
def update_width_virtual(self):
|
||||
self.width_virtual = self.us_to_px(self.ts_end - self.ts_start)
|
||||
|
||||
def __zoom(self, x):
|
||||
self.update_width_virtual()
|
||||
(xpos, ypos) = self.scroll.GetViewStart()
|
||||
xpos = self.us_to_px(x) / self.scroll_scale
|
||||
self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale, xpos, ypos)
|
||||
self.Refresh()
|
||||
|
||||
def zoom_in(self):
|
||||
x = self.scroll_start_us()
|
||||
self.zoom *= 2
|
||||
self.__zoom(x)
|
||||
|
||||
def zoom_out(self):
|
||||
x = self.scroll_start_us()
|
||||
self.zoom /= 2
|
||||
self.__zoom(x)
|
||||
|
||||
|
||||
def on_key_press(self, event):
|
||||
key = event.GetRawKeyCode()
|
||||
if key == ord("+"):
|
||||
self.zoom_in()
|
||||
return
|
||||
if key == ord("-"):
|
||||
self.zoom_out()
|
||||
return
|
||||
|
||||
key = event.GetKeyCode()
|
||||
(x, y) = self.scroll.GetViewStart()
|
||||
if key == wx.WXK_RIGHT:
|
||||
self.scroll.Scroll(x + 1, y)
|
||||
elif key == wx.WXK_LEFT:
|
||||
self.scroll.Scroll(x - 1, y)
|
||||
elif key == wx.WXK_DOWN:
|
||||
self.scroll.Scroll(x, y + 1)
|
||||
elif key == wx.WXK_UP:
|
||||
self.scroll.Scroll(x, y - 1)
|
|
@ -0,0 +1,92 @@
|
|||
# Util.py - Python extension for perf script, miscellaneous utility code
|
||||
#
|
||||
# Copyright (C) 2010 by Tom Zanussi <tzanussi@gmail.com>
|
||||
#
|
||||
# This software may be distributed under the terms of the GNU General
|
||||
# Public License ("GPL") version 2 as published by the Free Software
|
||||
# Foundation.
|
||||
from __future__ import print_function
|
||||
|
||||
import errno, os
|
||||
|
||||
FUTEX_WAIT = 0
|
||||
FUTEX_WAKE = 1
|
||||
FUTEX_PRIVATE_FLAG = 128
|
||||
FUTEX_CLOCK_REALTIME = 256
|
||||
FUTEX_CMD_MASK = ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
|
||||
|
||||
NSECS_PER_SEC = 1000000000
|
||||
|
||||
def avg(total, n):
|
||||
return total / n
|
||||
|
||||
def nsecs(secs, nsecs):
|
||||
return secs * NSECS_PER_SEC + nsecs
|
||||
|
||||
def nsecs_secs(nsecs):
|
||||
return nsecs / NSECS_PER_SEC
|
||||
|
||||
def nsecs_nsecs(nsecs):
|
||||
return nsecs % NSECS_PER_SEC
|
||||
|
||||
def nsecs_str(nsecs):
|
||||
str = "%5u.%09u" % (nsecs_secs(nsecs), nsecs_nsecs(nsecs)),
|
||||
return str
|
||||
|
||||
def add_stats(dict, key, value):
|
||||
if key not in dict:
|
||||
dict[key] = (value, value, value, 1)
|
||||
else:
|
||||
min, max, avg, count = dict[key]
|
||||
if value < min:
|
||||
min = value
|
||||
if value > max:
|
||||
max = value
|
||||
avg = (avg + value) / 2
|
||||
dict[key] = (min, max, avg, count + 1)
|
||||
|
||||
def clear_term():
|
||||
print("\x1b[H\x1b[2J")
|
||||
|
||||
audit_package_warned = False
|
||||
|
||||
try:
|
||||
import audit
|
||||
machine_to_id = {
|
||||
'x86_64': audit.MACH_86_64,
|
||||
'aarch64': audit.MACH_AARCH64,
|
||||
'alpha' : audit.MACH_ALPHA,
|
||||
'ia64' : audit.MACH_IA64,
|
||||
'ppc' : audit.MACH_PPC,
|
||||
'ppc64' : audit.MACH_PPC64,
|
||||
'ppc64le' : audit.MACH_PPC64LE,
|
||||
's390' : audit.MACH_S390,
|
||||
's390x' : audit.MACH_S390X,
|
||||
'i386' : audit.MACH_X86,
|
||||
'i586' : audit.MACH_X86,
|
||||
'i686' : audit.MACH_X86,
|
||||
}
|
||||
try:
|
||||
machine_to_id['armeb'] = audit.MACH_ARMEB
|
||||
except:
|
||||
pass
|
||||
machine_id = machine_to_id[os.uname()[4]]
|
||||
except:
|
||||
if not audit_package_warned:
|
||||
audit_package_warned = True
|
||||
print("Install the python-audit package to get syscall names.\n"
|
||||
"For example:\n # apt-get install python3-audit (Ubuntu)"
|
||||
"\n # yum install python3-audit (Fedora)"
|
||||
"\n etc.\n")
|
||||
|
||||
def syscall_name(id):
|
||||
try:
|
||||
return audit.audit_syscall_to_name(id, machine_id)
|
||||
except:
|
||||
return str(id)
|
||||
|
||||
def strerror(nr):
|
||||
try:
|
||||
return errno.errorcode[abs(nr)]
|
||||
except:
|
||||
return "Unknown %d errno" % nr
|
Loading…
Add table
Add a link
Reference in a new issue