mirror of https://github.com/xemu-project/xemu.git
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:
parent
d895493b7c
commit
068294a1ca
|
@ -213,63 +213,73 @@ 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():
|
||||||
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
|
|
||||||
|
|
||||||
IOCTL_NUMBERS['ENABLE'] = 0x20002400
|
|
||||||
IOCTL_NUMBERS['DISABLE'] = 0x20002401
|
|
||||||
IOCTL_NUMBERS['SET_FILTER'] = 0x80002406 | (ctypes.sizeof(ctypes.c_char_p)
|
|
||||||
<< 16)
|
|
||||||
|
|
||||||
def aarch64_init():
|
|
||||||
global SC_PERF_EVT_OPEN
|
|
||||||
global EXIT_REASONS
|
|
||||||
|
|
||||||
SC_PERF_EVT_OPEN = 241
|
|
||||||
EXIT_REASONS = AARCH64_EXIT_REASONS
|
|
||||||
|
|
||||||
def detect_platform():
|
|
||||||
machine = os.uname()[4]
|
machine = os.uname()[4]
|
||||||
|
|
||||||
if machine.startswith('ppc'):
|
if machine.startswith('ppc'):
|
||||||
ppc_init()
|
return ArchPPC()
|
||||||
elif machine.startswith('aarch64'):
|
elif machine.startswith('aarch64'):
|
||||||
aarch64_init()
|
return ArchA64()
|
||||||
elif machine.startswith('s390'):
|
elif machine.startswith('s390'):
|
||||||
s390_init()
|
return ArchS390()
|
||||||
else:
|
else:
|
||||||
for line in file('/proc/cpuinfo').readlines():
|
# X86_64
|
||||||
if line.startswith('flags'):
|
for line in open('/proc/cpuinfo'):
|
||||||
for flag in line.split():
|
if not line.startswith('flags'):
|
||||||
if flag in X86_EXIT_REASONS:
|
continue
|
||||||
x86_init(flag)
|
|
||||||
|
flags = line.split()
|
||||||
|
if 'vmx' in flags:
|
||||||
|
return ArchX86(VMX_EXIT_REASONS)
|
||||||
|
if 'svm' in flags:
|
||||||
|
return ArchX86(SVM_EXIT_REASONS)
|
||||||
return
|
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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
class ArchA64(Arch):
|
||||||
|
def __init__(self):
|
||||||
|
self.sc_perf_evt_open = 241
|
||||||
|
self.ioctl_numbers = IOCTL_NUMBERS
|
||||||
|
self.exit_reasons = AARCH64_EXIT_REASONS
|
||||||
|
|
||||||
|
class ArchS390(Arch):
|
||||||
|
def __init__(self):
|
||||||
|
self.sc_perf_evt_open = 331
|
||||||
|
self.ioctl_numbers = IOCTL_NUMBERS
|
||||||
|
self.exit_reasons = None
|
||||||
|
|
||||||
|
ARCH = Arch.get_arch()
|
||||||
|
|
||||||
|
|
||||||
def walkdir(path):
|
def walkdir(path):
|
||||||
"""Returns os.walk() data for specified directory.
|
"""Returns os.walk() data for specified directory.
|
||||||
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue