[PATCH 2/6] kvm_stat: implement tracepoint stats provider

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Avi Kivity <avi@xxxxxxxxxx>
---
 kvm/kvm_stat |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 100 insertions(+), 1 deletions(-)

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)
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux