scripts/kvm/kvm_stat: Group arch specific data

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>
This commit is contained in:
Janosch Frank 2016-01-11 16:17:55 +01:00 committed by Paolo Bonzini
parent d895493b7c
commit 068294a1ca
1 changed files with 63 additions and 54 deletions

View File

@ -213,62 +213,72 @@ X86_EXIT_REASONS = {
'svm': SVM_EXIT_REASONS, 'svm': SVM_EXIT_REASONS,
} }
SC_PERF_EVT_OPEN = None
EXIT_REASONS = None
IOCTL_NUMBERS = { IOCTL_NUMBERS = {
'SET_FILTER' : 0x40082406, 'SET_FILTER': 0x40082406,
'ENABLE' : 0x00002400, 'ENABLE': 0x00002400,
'DISABLE' : 0x00002401, 'DISABLE': 0x00002401,
'RESET' : 0x00002403, 'RESET': 0x00002403,
} }
def x86_init(flag): class Arch(object):
global SC_PERF_EVT_OPEN """Class that encapsulates global architecture specific data like
global EXIT_REASONS syscall and ioctl numbers.
SC_PERF_EVT_OPEN = 298 """
EXIT_REASONS = X86_EXIT_REASONS[flag] @staticmethod
def get_arch():
machine = os.uname()[4]
def s390_init(): if machine.startswith('ppc'):
global SC_PERF_EVT_OPEN 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
SC_PERF_EVT_OPEN = 331 flags = line.split()
if 'vmx' in flags:
return ArchX86(VMX_EXIT_REASONS)
if 'svm' in flags:
return ArchX86(SVM_EXIT_REASONS)
return
def ppc_init(): class ArchX86(Arch):
global SC_PERF_EVT_OPEN def __init__(self, exit_reasons):
global IOCTL_NUMBERS self.sc_perf_evt_open = 298
self.ioctl_numbers = IOCTL_NUMBERS
self.exit_reasons = exit_reasons
SC_PERF_EVT_OPEN = 319 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
IOCTL_NUMBERS['ENABLE'] = 0x20002400 # PPC comes in 32 and 64 bit and some generated ioctl
IOCTL_NUMBERS['DISABLE'] = 0x20002401 # numbers depend on the wordsize.
IOCTL_NUMBERS['SET_FILTER'] = 0x80002406 | (ctypes.sizeof(ctypes.c_char_p) char_ptr_size = ctypes.sizeof(ctypes.c_char_p)
<< 16) self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16
def aarch64_init(): class ArchA64(Arch):
global SC_PERF_EVT_OPEN def __init__(self):
global EXIT_REASONS self.sc_perf_evt_open = 241
self.ioctl_numbers = IOCTL_NUMBERS
self.exit_reasons = AARCH64_EXIT_REASONS
SC_PERF_EVT_OPEN = 241 class ArchS390(Arch):
EXIT_REASONS = AARCH64_EXIT_REASONS def __init__(self):
self.sc_perf_evt_open = 331
self.ioctl_numbers = IOCTL_NUMBERS
self.exit_reasons = None
def detect_platform(): ARCH = Arch.get_arch()
machine = os.uname()[4]
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
def walkdir(path): def walkdir(path):
@ -304,11 +314,10 @@ def get_online_cpus():
def get_filters(): def get_filters():
detect_platform()
filters = {} filters = {}
filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS) filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS)
if EXIT_REASONS: if ARCH.exit_reasons:
filters['kvm_exit'] = ('exit_reason', EXIT_REASONS) filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
return filters return filters
libc = ctypes.CDLL('libc.so.6', use_errno=True) libc = ctypes.CDLL('libc.so.6', use_errno=True)
@ -328,9 +337,9 @@ class perf_event_attr(ctypes.Structure):
('bp_len', ctypes.c_uint64), ('bp_len', ctypes.c_uint64),
] ]
def perf_event_open(attr, pid, cpu, group_fd, flags): def perf_event_open(attr, pid, cpu, group_fd, flags):
return syscall(SC_PERF_EVT_OPEN, ctypes.pointer(attr), ctypes.c_int(pid), return syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr),
ctypes.c_int(cpu), ctypes.c_int(group_fd), ctypes.c_int(pid), ctypes.c_int(cpu),
ctypes.c_long(flags)) ctypes.c_int(group_fd), ctypes.c_long(flags))
PERF_TYPE_TRACEPOINT = 2 PERF_TYPE_TRACEPOINT = 2
PERF_FORMAT_GROUP = 1 << 3 PERF_FORMAT_GROUP = 1 << 3
@ -388,19 +397,19 @@ class Event(object):
'while calling sys_perf_event_open().') 'while calling sys_perf_event_open().')
if trace_filter: if trace_filter:
fcntl.ioctl(fd, IOCTL_NUMBERS['SET_FILTER'], fcntl.ioctl(fd, ARCH.ioctl_numbers['SET_FILTER'],
trace_filter) trace_filter)
self.fd = fd self.fd = fd
def enable(self): def enable(self):
fcntl.ioctl(self.fd, IOCTL_NUMBERS['ENABLE'], 0) fcntl.ioctl(self.fd, ARCH.ioctl_numbers['ENABLE'], 0)
def disable(self): def disable(self):
fcntl.ioctl(self.fd, IOCTL_NUMBERS['DISABLE'], 0) fcntl.ioctl(self.fd, ARCH.ioctl_numbers['DISABLE'], 0)
def reset(self): def reset(self):
fcntl.ioctl(self.fd, IOCTL_NUMBERS['RESET'], 0) fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0)
class TracepointProvider(object): class TracepointProvider(object):
def __init__(self): def __init__(self):