Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tools/perf/scripts: Fixed Python pylint warnings #7

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 126 additions & 58 deletions tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# EventClass.py
# EventClass.py - Python extension for perf script, used for
# performance event analysis

# SPDX-License-Identifier: GPL-2.0
#
# This is a library defining some events types classes, which could
Expand All @@ -13,65 +15,115 @@
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
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.
#

# Function to create an event instance based on raw buffer size
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))
"""
Create an event instance based on raw buffer size.

Args:
name (str): Event name.
comm (str): Command name.
dso (str): Dynamic shared object.
symbol (str): Symbol name.
raw_buf (bytes): Raw buffer containing event data.

Returns:
PerfEvent: An instance of the appropriate event class.
"""
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():
"""
Base class for all perf event samples.
"""
event_num = 0

def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_GENERIC):
"""
Initialize PerfEvent instance.

Args:
name (str): Event name.
comm (str): Command name.
dso (str): Dynamic shared object.
symbol (str): Symbol name.
raw_buf (bytes): Raw buffer containing event data.
ev_type (int): Event type identifier.
"""
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 event information.
"""
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
"""
Class for basic Intel PEBS events.
"""
pebs_num = 0

def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS):
"""
Initialize PebsEvent instance.

Args:
name (str): Event name.
comm (str): Command name.
dso (str): Dynamic shared object.
symbol (str): Symbol name.
raw_buf (bytes): Raw buffer containing event data.
ev_type (int): Event type identifier.
"""
tmp_buf = raw_buf[0:80]
flags, ipa, reg_ax, reg_bx, reg_cx, reg_dx, reg_si, reg_di, reg_bp, reg_sp = struct.unpack(
'QQQQQQQQQQ', tmp_buf)
self.flags = flags
self.ipa = ipa
self.reg_ax = reg_ax
self.reg_bx = reg_bx
self.reg_cx = reg_cx
self.reg_dx = reg_dx
self.reg_si = reg_si
self.reg_di = reg_di
self.reg_bp = reg_bp
self.reg_sp = reg_sp

PerfEvent.__init__(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
Expand All @@ -82,16 +134,32 @@ def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS):
# 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
"""
Class for Intel Nehalem and Westmere PEBS events with load latency info.
"""
pebs_nhm_num = 0

def __init__(self, name, comm, dso, symbol, raw_buf, ev_type=EVTYPE_PEBS_LL):
"""
Initialize PebsNHM instance.

Args:
name (str): Event name.
comm (str): Command name.
dso (str): Dynamic shared object.
symbol (str): Symbol name.
raw_buf (bytes): Raw buffer containing event data.
ev_type (int): Event type identifier.
"""
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__(name, comm, dso, symbol, raw_buf, ev_type)
PebsNHM.pebs_nhm_num += 1
del tmp_buf
161 changes: 91 additions & 70 deletions tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py
Original file line number Diff line number Diff line change
@@ -1,91 +1,112 @@
# Util.py - Python extension for perf script, miscellaneous utility code
#
# Copyright (C) 2010 by Tom Zanussi <[email protected]>
#
# This software may be distributed under the terms of the GNU General
# Public License ("GPL") version 2 as published by the Free Software
# Foundation.
"""
Util.py - Python extension for perf script, miscellaneous utility code

Copyright (C) 2010 by Tom Zanussi <[email protected]>

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
import errno
import 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
NSECS_PER_SEC = 1000000000


def avg(total, num_elements):
"""Calculate the average of a total sum."""
return total / num_elements


def nsecs(secs, nanosecs):
"""Convert seconds and nanoseconds to total nanoseconds."""
return secs * NSECS_PER_SEC + nanosecs


def avg(total, n):
return total / n
def nsecs_secs(nanosecs):
"""Extract seconds from total nanoseconds."""
return nanosecs // NSECS_PER_SEC

def nsecs(secs, nsecs):
return secs * NSECS_PER_SEC + nsecs

def nsecs_secs(nsecs):
return nsecs / NSECS_PER_SEC
def nsecs_nsecs(nanosecs):
"""Extract nanoseconds from total nanoseconds."""
return nanosecs % 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 nsecs_str(nanosecs):
"""Convert total nanoseconds to a formatted string."""
return "{:5d}.{:09d}".format(nsecs_secs(nanosecs), nsecs_nsecs(nanosecs))


def add_stats(stats_dict, key, value):
"""Add statistics to a dictionary."""
if key not in stats_dict:
stats_dict[key] = (value, value, value, 1)
else:
min_value, max_value, avg_value, count = stats_dict[key]
if value < min_value:
min_value = value
if value > max_value:
max_value = value
avg_value = (avg_value + value) / 2
stats_dict[key] = (min_value, max_value, avg_value, count + 1)

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():
"""Clear the terminal screen."""
print("\x1b[H\x1b[2J")

audit_package_warned = False

AUDIT_PACKAGE_WARNED = False

try:
import audit
machine_to_id = {
'x86_64': audit.MACH_86_64,
'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 audit-libs-python package to get syscall names.\n"
"For example:\n # apt-get install python-audit (Ubuntu)"
"\n # yum install audit-libs-python (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
import audit
MACHINE_TO_ID = {
'x86_64': audit.MACH_86_64,
'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 AttributeError:
pass
MACHINE_ID = MACHINE_TO_ID[os.uname()[4]]
except ImportError:
if not AUDIT_PACKAGE_WARNED:
AUDIT_PACKAGE_WARNED = True
print("Install the audit-libs-python package to get syscall names.\n"
"For example:\n # apt-get install python-audit (Ubuntu)"
"\n # yum install audit-libs-python (Fedora)"
"\n etc.\n")


def syscall_name(syscall_id):
"""Get the name of a syscall using its ID."""
try:
return audit.audit_syscall_to_name(syscall_id, MACHINE_ID)
except AttributeError:
return str(syscall_id)


def strerror(errno_value):
"""Convert an errno value to a human-readable string."""
try:
return errno.errorcode[abs(errno_value)]
except KeyError:
return "Unknown {} errno".format(errno_value)