diff options
-rwxr-xr-x | tools/kvm/kvm_stat/kvm_stat | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat index 6207843b9199..5c4f24879dc4 100755 --- a/tools/kvm/kvm_stat/kvm_stat +++ b/tools/kvm/kvm_stat/kvm_stat @@ -224,6 +224,7 @@ IOCTL_NUMBERS = { 'RESET': 0x00002403, } + class Arch(object): """Encapsulates global architecture specific data. @@ -254,12 +255,14 @@ class Arch(object): 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 @@ -274,12 +277,14 @@ class ArchPPC(Arch): self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16 self.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 + class ArchS390(Arch): def __init__(self): self.sc_perf_evt_open = 331 @@ -341,6 +346,7 @@ def get_filters(): libc = ctypes.CDLL('libc.so.6', use_errno=True) syscall = libc.syscall + class perf_event_attr(ctypes.Structure): """Struct that holds the necessary data to set up a trace event. @@ -369,6 +375,7 @@ class perf_event_attr(ctypes.Structure): self.size = ctypes.sizeof(self) self.read_format = PERF_FORMAT_GROUP + def perf_event_open(attr, pid, cpu, group_fd, flags): """Wrapper for the sys_perf_evt_open() syscall. @@ -394,6 +401,7 @@ PERF_FORMAT_GROUP = 1 << 3 PATH_DEBUGFS_TRACING = '/sys/kernel/debug/tracing' PATH_DEBUGFS_KVM = '/sys/kernel/debug/kvm' + class Group(object): """Represents a perf event group.""" @@ -426,6 +434,7 @@ class Group(object): struct.unpack(read_format, os.read(self.events[0].fd, length)))) + class Event(object): """Represents a performance event and manages its life cycle.""" def __init__(self, name, group, trace_cpu, trace_pid, trace_point, @@ -509,6 +518,7 @@ class Event(object): """Resets the count of the trace event in the kernel.""" fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0) + class TracepointProvider(object): """Data provider for the stats class. @@ -650,6 +660,7 @@ class TracepointProvider(object): ret[name] += val return ret + class DebugfsProvider(object): """Provides data from the files that KVM creates in the kvm debugfs folder.""" @@ -719,6 +730,7 @@ class DebugfsProvider(object): except IOError: return 0 + class Stats(object): """Manages the data providers and the data they provide. @@ -790,6 +802,7 @@ class Stats(object): LABEL_WIDTH = 40 NUMBER_WIDTH = 10 + class Tui(object): """Instruments curses to draw a nice text ui.""" def __init__(self, stats): @@ -859,6 +872,7 @@ class Tui(object): len('Current'), 'Current') row = 3 stats = self.stats.get() + def sortkey(x): if stats[x][1]: return (-stats[x][1], -stats[x][0]) @@ -966,6 +980,7 @@ class Tui(object): except curses.error: continue + def batch(stats): """Prints statistics in a key, value format.""" try: @@ -978,13 +993,16 @@ def batch(stats): except KeyboardInterrupt: pass + def log(stats): """Prints statistics as reiterating key block, multiple value blocks.""" keys = sorted(stats.get().iterkeys()) + def banner(): for k in keys: print '%s' % k, print + def statline(): s = stats.get() for k in keys: @@ -1002,6 +1020,7 @@ def log(stats): except KeyboardInterrupt: break + def get_options(): """Returns processed program arguments.""" description_text = """ @@ -1072,6 +1091,7 @@ Requirements: (options, _) = optparser.parse_args(sys.argv) return options + def get_providers(options): """Returns a list of data providers depending on the passed options.""" providers = [] @@ -1085,6 +1105,7 @@ def get_providers(options): return providers + def check_access(options): """Exits if the current user can't access all needed directories.""" if not os.path.exists('/sys/kernel/debug'): @@ -1114,6 +1135,7 @@ def check_access(options): return options + def main(): options = get_options() options = check_access(options) |