public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi@redhat.com>
To: Marcelo Tosatti <mtosatti@redhat.com>, kvm@vger.kernel.org
Subject: [PATCH 2/6] kvm_stat: implement tracepoint stats provider
Date: Tue, 31 Aug 2010 16:25:28 +0300	[thread overview]
Message-ID: <1283261132-5904-4-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1283261132-5904-1-git-send-email-avi@redhat.com>

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 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


  parent reply	other threads:[~2010-08-31 13:25 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-31 13:25 [PATCH 0/6] kvm_stat tracepoint support Avi Kivity
2010-08-31 13:25 ` [PATCH 0/6] *** SUBJECT HERE *** Avi Kivity
2010-08-31 13:30   ` Avi Kivity
2010-08-31 14:43     ` Gerd Hoffmann
2010-08-31 16:10       ` Avi Kivity
2010-08-31 16:13         ` Anthony Liguori
2010-08-31 16:24           ` Avi Kivity
2010-09-01  7:32           ` Gerd Hoffmann
2010-08-31 13:25 ` [PATCH 1/6] kvm_stat: refactor to separate stats provider from difference engine Avi Kivity
2010-08-31 13:25 ` Avi Kivity [this message]
2010-08-31 13:25 ` [PATCH 3/6] kvm_stat: provide detailed kvm_exit:exit_reason display Avi Kivity
2010-08-31 13:25 ` [PATCH 4/6] kvm_stat: sort tui output according to highest occurence Avi Kivity
2010-08-31 13:25 ` [PATCH 5/6] kvm_stat: increase label width Avi Kivity
2010-08-31 13:25 ` [PATCH 6/6] kvm_stat: be slower Avi Kivity

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1283261132-5904-4-git-send-email-avi@redhat.com \
    --to=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mtosatti@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox