From: Avi Kivity <[email protected]>
Signed-off-by: Avi Kivity <[email protected]>
diff --git a/kvm/kvm_stat b/kvm/kvm_stat
index 75424fc..9b0392b 100755
--- a/kvm/kvm_stat
+++ b/kvm/kvm_stat
@@ -16,6 +16,100 @@ class DebugfsProvider(object):
return int(file(self.base + '/' + key).read())
return dict([(key, val(key)) for key in self._fields])
+import ctypes, struct, array
+
+libc = ctypes.CDLL('libc.so.6')
+syscall = libc.syscall
+class perf_event_attr(ctypes.Structure):
+ _fields_ = [('type', ctypes.c_uint32),
+ ('size', ctypes.c_uint32),
+ ('config', ctypes.c_uint64),
+ ('sample_freq', ctypes.c_uint64),
+ ('sample_type', ctypes.c_uint64),
+ ('read_format', ctypes.c_uint64),
+ ('flags', ctypes.c_uint64),
+ ('wakeup_events', ctypes.c_uint32),
+ ('bp_type', ctypes.c_uint32),
+ ('bp_addr', ctypes.c_uint64),
+ ('bp_len', ctypes.c_uint64),
+ ]
+def _perf_event_open(attr, pid, cpu, group_fd, flags):
+ return syscall(298, ctypes.pointer(attr), ctypes.c_int(pid),
+ ctypes.c_int(cpu), ctypes.c_int(group_fd),
+ ctypes.c_long(flags))
+
+PERF_TYPE_HARDWARE = 0
+PERF_TYPE_SOFTWARE = 1
+PERF_TYPE_TRACEPOINT = 2
+PERF_TYPE_HW_CACHE = 3
+PERF_TYPE_RAW = 4
+PERF_TYPE_BREAKPOINT = 5
+
+PERF_SAMPLE_IP = 1 << 0
+PERF_SAMPLE_TID = 1 << 1
+PERF_SAMPLE_TIME = 1 << 2
+PERF_SAMPLE_ADDR = 1 << 3
+PERF_SAMPLE_READ = 1 << 4
+PERF_SAMPLE_CALLCHAIN = 1 << 5
+PERF_SAMPLE_ID = 1 << 6
+PERF_SAMPLE_CPU = 1 << 7
+PERF_SAMPLE_PERIOD = 1 << 8
+PERF_SAMPLE_STREAM_ID = 1 << 9
+PERF_SAMPLE_RAW = 1 << 10
+
+PERF_FORMAT_TOTAL_TIME_ENABLED = 1 << 0
+PERF_FORMAT_TOTAL_TIME_RUNNING = 1 << 1
+PERF_FORMAT_ID = 1 << 2
+PERF_FORMAT_GROUP = 1 << 3
+
+
+class TracepointProvider(object):
+ def __init__(self):
+ self.base = '/sys/kernel/debug/tracing/events/kvm/'
+ fields = [f
+ for f in os.listdir(self.base)
+ if os.path.isdir(self.base + '/' + f)]
+ self.select(fields)
+ def fields(self):
+ return self._fields
+ def select(self, _fields):
+ self._fields = _fields
+ self.cpus = [0, 1]
+ fds = []
+ self.group_leaders = []
+ for cpu in self.cpus:
+ group_leader = -1
+ for f in _fields:
+ attr = perf_event_attr()
+ attr.type = PERF_TYPE_TRACEPOINT
+ attr.size = ctypes.sizeof(attr)
+ id = int(file(self.base + f + '/id').read())
+ attr.config = id
+ attr.sample_type = (PERF_SAMPLE_RAW
+ | PERF_SAMPLE_TIME
+ | PERF_SAMPLE_CPU)
+ attr.sample_period = 1
+ attr.read_format = PERF_FORMAT_GROUP
+ fd = _perf_event_open(attr, -1, cpu, group_leader, 0)
+ if fd == -1:
+ raise Exception('perf_event_open failed')
+ if group_leader == -1:
+ group_leader = fd
+ fds.append(fd)
+ self.group_leaders.append(group_leader)
+ self.fds = fds
+ self.files = [os.fdopen(group_leader)
+ for group_leader in self.group_leaders]
+ def read(self):
+ ret = dict([(f, 0) for f in self._fields])
+ bytes = 8 * (1 + len(self._fields))
+ fmt = 'xxxxxxxx' + 'q' * len(self._fields)
+ for file in self.files:
+ a = struct.unpack(fmt, file.read(bytes))
+ for field, val in zip(self._fields, a):
+ ret[field] += val
+ return ret
+
class Stats:
def __init__(self, provider, fields = None):
def wanted(key):
@@ -133,7 +227,12 @@ options.add_option('-f', '--fields',
)
(options, args) = options.parse_args(sys.argv)
-stats = Stats(provider = DebugfsProvider(), fields = options.fields)
+try:
+ provider = TracepointProvider()
+except:
+ provider = DebugfsProvider()
+
+stats = Stats(provider, fields = options.fields)
if options.log:
log(stats)
--
To unsubscribe from this list: send the line "unsubscribe kvm-commits" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html