Skip to content

Commit

Permalink
scripts/kvm/kvm_stat: Group arch specific data
Browse files Browse the repository at this point in the history
Using global variables and multiple initialization functions for arch
specific data makes the code hard to read. By grouping them in the
Arch classes we encapsulate and initialize them in one place.

Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Message-Id: <1452525484-32309-26-git-send-email-frankja@linux.vnet.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Janosch Frank authored and bonzini committed Jan 26, 2016
1 parent d895493 commit 068294a
Showing 1 changed file with 67 additions and 58 deletions.
125 changes: 67 additions & 58 deletions scripts/kvm/kvm_stat
Expand Up @@ -213,62 +213,72 @@ X86_EXIT_REASONS = {
'svm': SVM_EXIT_REASONS,
}

SC_PERF_EVT_OPEN = None
EXIT_REASONS = None

IOCTL_NUMBERS = {
'SET_FILTER' : 0x40082406,
'ENABLE' : 0x00002400,
'DISABLE' : 0x00002401,
'RESET' : 0x00002403,
'SET_FILTER': 0x40082406,
'ENABLE': 0x00002400,
'DISABLE': 0x00002401,
'RESET': 0x00002403,
}

def x86_init(flag):
global SC_PERF_EVT_OPEN
global EXIT_REASONS

SC_PERF_EVT_OPEN = 298
EXIT_REASONS = X86_EXIT_REASONS[flag]

def s390_init():
global SC_PERF_EVT_OPEN

SC_PERF_EVT_OPEN = 331

def ppc_init():
global SC_PERF_EVT_OPEN
global IOCTL_NUMBERS

SC_PERF_EVT_OPEN = 319
class Arch(object):
"""Class that encapsulates global architecture specific data like
syscall and ioctl numbers.
IOCTL_NUMBERS['ENABLE'] = 0x20002400
IOCTL_NUMBERS['DISABLE'] = 0x20002401
IOCTL_NUMBERS['SET_FILTER'] = 0x80002406 | (ctypes.sizeof(ctypes.c_char_p)
<< 16)
"""
@staticmethod
def get_arch():
machine = os.uname()[4]

if machine.startswith('ppc'):
return ArchPPC()
elif machine.startswith('aarch64'):
return ArchA64()
elif machine.startswith('s390'):
return ArchS390()
else:
# X86_64
for line in open('/proc/cpuinfo'):
if not line.startswith('flags'):
continue

flags = line.split()
if 'vmx' in flags:
return ArchX86(VMX_EXIT_REASONS)
if 'svm' in flags:
return ArchX86(SVM_EXIT_REASONS)
return

class ArchX86(Arch):
def __init__(self, exit_reasons):
self.sc_perf_evt_open = 298
self.ioctl_numbers = IOCTL_NUMBERS
self.exit_reasons = exit_reasons

class ArchPPC(Arch):
def __init__(self):
self.sc_perf_evt_open = 319
self.ioctl_numbers = IOCTL_NUMBERS
self.ioctl_numbers['ENABLE'] = 0x20002400
self.ioctl_numbers['DISABLE'] = 0x20002401

def aarch64_init():
global SC_PERF_EVT_OPEN
global EXIT_REASONS
# PPC comes in 32 and 64 bit and some generated ioctl
# numbers depend on the wordsize.
char_ptr_size = ctypes.sizeof(ctypes.c_char_p)
self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16

SC_PERF_EVT_OPEN = 241
EXIT_REASONS = AARCH64_EXIT_REASONS
class ArchA64(Arch):
def __init__(self):
self.sc_perf_evt_open = 241
self.ioctl_numbers = IOCTL_NUMBERS
self.exit_reasons = AARCH64_EXIT_REASONS

def detect_platform():
machine = os.uname()[4]
class ArchS390(Arch):
def __init__(self):
self.sc_perf_evt_open = 331
self.ioctl_numbers = IOCTL_NUMBERS
self.exit_reasons = None

if machine.startswith('ppc'):
ppc_init()
elif machine.startswith('aarch64'):
aarch64_init()
elif machine.startswith('s390'):
s390_init()
else:
for line in file('/proc/cpuinfo').readlines():
if line.startswith('flags'):
for flag in line.split():
if flag in X86_EXIT_REASONS:
x86_init(flag)
return
ARCH = Arch.get_arch()


def walkdir(path):
Expand Down Expand Up @@ -304,11 +314,10 @@ def get_online_cpus():


def get_filters():
detect_platform()
filters = {}
filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS)
if EXIT_REASONS:
filters['kvm_exit'] = ('exit_reason', EXIT_REASONS)
if ARCH.exit_reasons:
filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
return filters

libc = ctypes.CDLL('libc.so.6', use_errno=True)
Expand All @@ -328,9 +337,9 @@ class perf_event_attr(ctypes.Structure):
('bp_len', ctypes.c_uint64),
]
def perf_event_open(attr, pid, cpu, group_fd, flags):
return syscall(SC_PERF_EVT_OPEN, ctypes.pointer(attr), ctypes.c_int(pid),
ctypes.c_int(cpu), ctypes.c_int(group_fd),
ctypes.c_long(flags))
return syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr),
ctypes.c_int(pid), ctypes.c_int(cpu),
ctypes.c_int(group_fd), ctypes.c_long(flags))

PERF_TYPE_TRACEPOINT = 2
PERF_FORMAT_GROUP = 1 << 3
Expand Down Expand Up @@ -388,19 +397,19 @@ class Event(object):
'while calling sys_perf_event_open().')

if trace_filter:
fcntl.ioctl(fd, IOCTL_NUMBERS['SET_FILTER'],
fcntl.ioctl(fd, ARCH.ioctl_numbers['SET_FILTER'],
trace_filter)

self.fd = fd

def enable(self):
fcntl.ioctl(self.fd, IOCTL_NUMBERS['ENABLE'], 0)
fcntl.ioctl(self.fd, ARCH.ioctl_numbers['ENABLE'], 0)

def disable(self):
fcntl.ioctl(self.fd, IOCTL_NUMBERS['DISABLE'], 0)
fcntl.ioctl(self.fd, ARCH.ioctl_numbers['DISABLE'], 0)

def reset(self):
fcntl.ioctl(self.fd, IOCTL_NUMBERS['RESET'], 0)
fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0)

class TracepointProvider(object):
def __init__(self):
Expand Down

0 comments on commit 068294a

Please sign in to comment.