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 3/6] kvm_stat: provide detailed kvm_exit:exit_reason display
Date: Tue, 31 Aug 2010 16:25:29 +0300	[thread overview]
Message-ID: <1283261132-5904-5-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1283261132-5904-1-git-send-email-avi@redhat.com>

In addition to displaying kvm_exit as an aggregate counter, use perf_event's
filter capability to count individual exit reasons.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 kvm/kvm_stat |  156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 155 insertions(+), 1 deletions(-)

diff --git a/kvm/kvm_stat b/kvm/kvm_stat
index 9b0392b..677683a 100755
--- a/kvm/kvm_stat
+++ b/kvm/kvm_stat
@@ -16,6 +16,143 @@ class DebugfsProvider(object):
             return int(file(self.base + '/' + key).read())
         return dict([(key, val(key)) for key in self._fields])
 
+vmx_exit_reasons = {
+    0: 'EXCEPTION_NMI',
+    1: 'EXTERNAL_INTERRUPT',
+    2: 'TRIPLE_FAULT',
+    7: 'PENDING_INTERRUPT',
+    8: 'NMI_WINDOW',
+    9: 'TASK_SWITCH',
+    10: 'CPUID',
+    12: 'HLT',
+    14: 'INVLPG',
+    15: 'RDPMC',
+    16: 'RDTSC',
+    18: 'VMCALL',
+    19: 'VMCLEAR',
+    20: 'VMLAUNCH',
+    21: 'VMPTRLD',
+    22: 'VMPTRST',
+    23: 'VMREAD',
+    24: 'VMRESUME',
+    25: 'VMWRITE',
+    26: 'VMOFF',
+    27: 'VMON',
+    28: 'CR_ACCESS',
+    29: 'DR_ACCESS',
+    30: 'IO_INSTRUCTION',
+    31: 'MSR_READ',
+    32: 'MSR_WRITE',
+    33: 'INVALID_STATE',
+    36: 'MWAIT_INSTRUCTION',
+    39: 'MONITOR_INSTRUCTION',
+    40: 'PAUSE_INSTRUCTION',
+    41: 'MCE_DURING_VMENTRY',
+    43: 'TPR_BELOW_THRESHOLD',
+    44: 'APIC_ACCESS',
+    48: 'EPT_VIOLATION',
+    49: 'EPT_MISCONFIG',
+    54: 'WBINVD',
+    55: 'XSETBV',
+}
+
+svm_exit_reasons = {
+    0x000: 'READ_CR0',
+    0x003: 'READ_CR3',
+    0x004: 'READ_CR4',
+    0x008: 'READ_CR8',
+    0x010: 'WRITE_CR0',
+    0x013: 'WRITE_CR3',
+    0x014: 'WRITE_CR4',
+    0x018: 'WRITE_CR8',
+    0x020: 'READ_DR0',
+    0x021: 'READ_DR1',
+    0x022: 'READ_DR2',
+    0x023: 'READ_DR3',
+    0x024: 'READ_DR4',
+    0x025: 'READ_DR5',
+    0x026: 'READ_DR6',
+    0x027: 'READ_DR7',
+    0x030: 'WRITE_DR0',
+    0x031: 'WRITE_DR1',
+    0x032: 'WRITE_DR2',
+    0x033: 'WRITE_DR3',
+    0x034: 'WRITE_DR4',
+    0x035: 'WRITE_DR5',
+    0x036: 'WRITE_DR6',
+    0x037: 'WRITE_DR7',
+    0x040: 'EXCP_BASE',
+    0x060: 'INTR',
+    0x061: 'NMI',
+    0x062: 'SMI',
+    0x063: 'INIT',
+    0x064: 'VINTR',
+    0x065: 'CR0_SEL_WRITE',
+    0x066: 'IDTR_READ',
+    0x067: 'GDTR_READ',
+    0x068: 'LDTR_READ',
+    0x069: 'TR_READ',
+    0x06a: 'IDTR_WRITE',
+    0x06b: 'GDTR_WRITE',
+    0x06c: 'LDTR_WRITE',
+    0x06d: 'TR_WRITE',
+    0x06e: 'RDTSC',
+    0x06f: 'RDPMC',
+    0x070: 'PUSHF',
+    0x071: 'POPF',
+    0x072: 'CPUID',
+    0x073: 'RSM',
+    0x074: 'IRET',
+    0x075: 'SWINT',
+    0x076: 'INVD',
+    0x077: 'PAUSE',
+    0x078: 'HLT',
+    0x079: 'INVLPG',
+    0x07a: 'INVLPGA',
+    0x07b: 'IOIO',
+    0x07c: 'MSR',
+    0x07d: 'TASK_SWITCH',
+    0x07e: 'FERR_FREEZE',
+    0x07f: 'SHUTDOWN',
+    0x080: 'VMRUN',
+    0x081: 'VMMCALL',
+    0x082: 'VMLOAD',
+    0x083: 'VMSAVE',
+    0x084: 'STGI',
+    0x085: 'CLGI',
+    0x086: 'SKINIT',
+    0x087: 'RDTSCP',
+    0x088: 'ICEBP',
+    0x089: 'WBINVD',
+    0x08a: 'MONITOR',
+    0x08b: 'MWAIT',
+    0x08c: 'MWAIT_COND',
+    0x400: 'NPF',
+}
+
+vendor_exit_reasons = {
+    'vmx': vmx_exit_reasons,
+    'svm': svm_exit_reasons,
+}
+
+exit_reasons = None
+
+for line in file('/proc/cpuinfo').readlines():
+    if line.startswith('flags'):
+        for flag in line.split():
+            if flag in vendor_exit_reasons:
+                exit_reasons = vendor_exit_reasons[flag]
+
+filters = {
+    'kvm_exit': ('exit_reason', exit_reasons)
+}
+
+def invert(d):
+    return dict((x[1], x[0]) for x in d.iteritems())
+
+for f in filters:
+    filters[f] = (filters[f][0], invert(filters[f][1]))
+
 import ctypes, struct, array
 
 libc = ctypes.CDLL('libc.so.6')
@@ -62,6 +199,7 @@ PERF_FORMAT_TOTAL_TIME_RUNNING		= 1 << 1
 PERF_FORMAT_ID				= 1 << 2
 PERF_FORMAT_GROUP			= 1 << 3
 
+import re
 
 class TracepointProvider(object):
     def __init__(self):
@@ -69,6 +207,13 @@ class TracepointProvider(object):
         fields = [f
                   for f in os.listdir(self.base)
                   if os.path.isdir(self.base + '/' + f)]
+        extra = []
+        for f in fields:
+            if f in filters:
+                subfield, values = filters[f]
+                for name, number in values.iteritems():
+                    extra.append(f + '(' + name + ')')
+        fields += extra
         self.select(fields)
     def fields(self):
         return self._fields
@@ -80,10 +225,14 @@ class TracepointProvider(object):
         for cpu in self.cpus:
             group_leader = -1
             for f in _fields:
+                fbase, sub = f, None
+                m = re.match(r'(.*)\((.*)\)', f)
+                if m:
+                    fbase, sub = m.groups()
                 attr = perf_event_attr()
                 attr.type = PERF_TYPE_TRACEPOINT
                 attr.size = ctypes.sizeof(attr)
-                id = int(file(self.base + f + '/id').read())
+                id = int(file(self.base + fbase + '/id').read())
                 attr.config = id
                 attr.sample_type = (PERF_SAMPLE_RAW
                                     | PERF_SAMPLE_TIME
@@ -93,6 +242,11 @@ class TracepointProvider(object):
                 fd = _perf_event_open(attr, -1, cpu, group_leader, 0)
                 if fd == -1:
                     raise Exception('perf_event_open failed')
+                if sub:
+                    import fcntl
+                    filter = '%s==%d\0' % (filters[fbase][0],
+                                         filters[fbase][1][sub])
+                    fcntl.ioctl(fd, 0x40082406, filter)
                 if group_leader == -1:
                     group_leader = fd
                     fds.append(fd)
-- 
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 ` [PATCH 2/6] kvm_stat: implement tracepoint stats provider Avi Kivity
2010-08-31 13:25 ` Avi Kivity [this message]
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-5-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