[PATCH] fix compilation error of perf/core

2012-09-25 Thread Dong Hao
From: Dong Hao haod...@linux.vnet.ibm.com

The newest branch of perf/core should have compilation error!
Error log includes:

builtin-test.c: In function ‘perf_evsel__test_field’:
builtin-test.c:1216:6: error:
 variable ‘ret’ set but not used [-Werror=unused-but-set-variable]
builtin-test.c: In function ‘perf_evsel__tp_sched_test’:
builtin-test.c:1242:6: error:
 variable ‘ret’ set but not used [-Werror=unused-but-set-variable]
cc1: all warnings being treated as errors
make: *** [builtin-test.o] Error 1
-
Fix it by replacing return value from 0 to ret.
Then this branch can be compiled successfully.

Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 tools/perf/builtin-test.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 32caf13..78b47a7 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -1233,7 +1233,7 @@ static int perf_evsel__test_field(struct perf_evsel 
*evsel, const char *name,
ret = -1;
}
 
-   return 0;
+   return ret;
 }
 
 static int perf_evsel__tp_sched_test(void)
@@ -1286,7 +1286,7 @@ static int perf_evsel__tp_sched_test(void)
if (perf_evsel__test_field(evsel, target_cpu, 4, true))
ret = -1;
 
-   return 0;
+   return ret;
 }
 
 static struct test {
-- 
1.7.2.5

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


[PATCH v8 0/3] KVM: perf: kvm events analysis tool

2012-09-17 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Changelog:
the changes from Avi's comments:
- move the definition of x86 fault vector to asm/kvm.h
- drop the second patch which introduced new tracpoints

the changes from David's comments:
- use scnprintf instead of snprintf
- drop exclusive check for '-a' and '-p', after this, we should
  append -a to track all guest, -p to track the specified guest
- improve the help usage
- fix a possible memory leak
- some cleanups

the changes from Andrew Jones's comments:
- move stat related code to util/stat.c

Thank you very much for your patience!

This patchset introduces a perf-based tool (perf kvm stat record/report)
which can analyze kvm events more smartly. Below is the presentation slice
on 2012 Japan LinuxCon:
http://events.linuxfoundation.org/images/stories/pdf/lcjp2012_guangrong.pdf
You can get more details from it. If any questions/comments, please feel free
to let us know.

This patchset is based on Arnaldo's git tree perf/core branch.

Usage:
- kvm stat
  run a command and gather performance counter statistics, it is the alias of
  perf stat

- trace kvm events:
  perf kvm stat record, or, if other tracepoints are interesting as well, we
  can append the events like this:
  perf kvm stat record -e timer:* -a

  If many guests are running, we can track the specified guest by using -p or
  --pid. -a is used to track events generated by all guests.

- show the result:
  perf kvm stat report

The output example is following:
# pgrep qemu
13005
13059

total 2 guests are running on the host

Then, track the guest whose pid is 13059:
# ./perf kvm stat record -p 13059
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.253 MB perf.data.guest (~11065 samples) ]

See the vmexit events:
# ./perf kvm stat report --event=vmexit


Analyze events for all VCPUs:

 VM-EXITSamples  Samples% Time% Avg time

 APIC_ACCESS46070.55% 0.01% 22.44us ( +-   1.75% )
 HLT 9314.26%99.98% 832077.26us ( +-  10.42% )
  EXTERNAL_INTERRUPT 64 9.82% 0.00% 35.35us ( +-  14.21% )
   PENDING_INTERRUPT 24 3.68% 0.00%  9.29us ( +-  31.39% )
   CR_ACCESS  7 1.07% 0.00%  8.12us ( +-   5.76% )
  IO_INSTRUCTION  3 0.46% 0.00% 18.00us ( +-  11.79% )
   EXCEPTION_NMI  1 0.15% 0.00%  5.83us ( +-   -nan% )

Total Samples:652, Total events handled time:77396109.80us.

See the mmio events:
# ./perf kvm stat report --event=mmio


Analyze events for all VCPUs:

 MMIO AccessSamples  Samples% Time% Avg time

0xfee00380:W38784.31%79.28%  8.29us ( +-   3.32% )
0xfee00300:W 24 5.23% 9.96% 16.79us ( +-   1.97% )
0xfee00300:R 24 5.23% 7.83% 13.20us ( +-   3.00% )
0xfee00310:W 24 5.23% 2.93%  4.94us ( +-   3.84% )

Total Samples:459, Total events handled time:4044.59us.

See the ioport event:
# ./perf kvm stat report --event=ioport


Analyze events for all VCPUs:

  IO Port AccessSamples  Samples% Time% Avg time

 0xc050:POUT  3   100.00%   100.00% 13.75us ( +-  10.83% )

Total Samples:3, Total events handled time:41.26us.

And, --vcpu is used to track the specified vcpu and --key is used to sort the
result:
# ./perf kvm stat report --event=vmexit --vcpu=0 --key=time


Analyze events for VCPU 0:

 VM-EXITSamples  Samples% Time% Avg time

 HLT 2713.85%99.97% 405790.24us ( +-  12.70% )
  EXTERNAL_INTERRUPT 13 6.67% 0.00% 27.94us ( +-  22.26% )
 APIC_ACCESS14674.87% 0.03% 21.69us ( +-   2.91% )
  IO_INSTRUCTION  2 1.03% 0.00% 17.77us ( +-  20.56% )
   CR_ACCESS  2 1.03% 0.00%  8.55us ( +-   6.47% )
   PENDING_INTERRUPT  5 2.56% 0.00%  6.27us ( +-   3.94% )

Total Samples:195, Total events handled time:10959950.90us.


Dong Hao (3):
  KVM: x86: export svm/vmx exit code and vector code to userspace
  perf: move stat related code to util/stat.c
  KVM: perf: kvm events analysis tool

 arch/x86/include/asm/kvm.h|   16 +
 arch/x86/include/asm/kvm_host.h   |   16 -
 arch/x86/include/asm/svm.h|  205 +---
 arch/x86/include/asm/vmx.h|  127 --
 arch/x86/kvm/trace.h  |   89 
 tools/perf/Documentation/perf-kvm.txt |   30 ++-
 tools/perf/MANIFEST   |3 +
 tools/perf/Makefile   |1 +
 tools/perf/builtin-kvm.c  |  840 -
 tools/perf/builtin-stat.c |   56 +---
 tools/perf/util/header.c  |   59 +++-
 tools/perf/util/header.h  |1 +
 tools/perf/util/stat.c

[PATCH v8 1/3] KVM: x86: export svm/vmx exit code and vector code to userspace

2012-09-17 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Exporting KVM exit information to userspace to be consumed by perf.

[ Dong Hao haod...@linux.vnet.ibm.com: rebase it on acme's git tree ]
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
---
 arch/x86/include/asm/kvm.h  |   16 +++
 arch/x86/include/asm/kvm_host.h |   16 ---
 arch/x86/include/asm/svm.h  |  205 +--
 arch/x86/include/asm/vmx.h  |  127 
 arch/x86/kvm/trace.h|   89 -
 5 files changed, 230 insertions(+), 223 deletions(-)

diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index 246617e..41e08cb 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -9,6 +9,22 @@
 #include linux/types.h
 #include linux/ioctl.h
 
+#define DE_VECTOR 0
+#define DB_VECTOR 1
+#define BP_VECTOR 3
+#define OF_VECTOR 4
+#define BR_VECTOR 5
+#define UD_VECTOR 6
+#define NM_VECTOR 7
+#define DF_VECTOR 8
+#define TS_VECTOR 10
+#define NP_VECTOR 11
+#define SS_VECTOR 12
+#define GP_VECTOR 13
+#define PF_VECTOR 14
+#define MF_VECTOR 16
+#define MC_VECTOR 18
+
 /* Select x86 specific features in linux/kvm.h */
 #define __KVM_HAVE_PIT
 #define __KVM_HAVE_IOAPIC
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 09155d6..1eaa6b0 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -75,22 +75,6 @@
 #define KVM_HPAGE_MASK(x)  (~(KVM_HPAGE_SIZE(x) - 1))
 #define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
 
-#define DE_VECTOR 0
-#define DB_VECTOR 1
-#define BP_VECTOR 3
-#define OF_VECTOR 4
-#define BR_VECTOR 5
-#define UD_VECTOR 6
-#define NM_VECTOR 7
-#define DF_VECTOR 8
-#define TS_VECTOR 10
-#define NP_VECTOR 11
-#define SS_VECTOR 12
-#define GP_VECTOR 13
-#define PF_VECTOR 14
-#define MF_VECTOR 16
-#define MC_VECTOR 18
-
 #define SELECTOR_TI_MASK (1  2)
 #define SELECTOR_RPL_MASK 0x03
 
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index f2b83bc..cdf5674 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -1,6 +1,135 @@
 #ifndef __SVM_H
 #define __SVM_H
 
+#define SVM_EXIT_READ_CR0  0x000
+#define SVM_EXIT_READ_CR3  0x003
+#define SVM_EXIT_READ_CR4  0x004
+#define SVM_EXIT_READ_CR8  0x008
+#define SVM_EXIT_WRITE_CR0 0x010
+#define SVM_EXIT_WRITE_CR3 0x013
+#define SVM_EXIT_WRITE_CR4 0x014
+#define SVM_EXIT_WRITE_CR8 0x018
+#define SVM_EXIT_READ_DR0  0x020
+#define SVM_EXIT_READ_DR1  0x021
+#define SVM_EXIT_READ_DR2  0x022
+#define SVM_EXIT_READ_DR3  0x023
+#define SVM_EXIT_READ_DR4  0x024
+#define SVM_EXIT_READ_DR5  0x025
+#define SVM_EXIT_READ_DR6  0x026
+#define SVM_EXIT_READ_DR7  0x027
+#define SVM_EXIT_WRITE_DR0 0x030
+#define SVM_EXIT_WRITE_DR1 0x031
+#define SVM_EXIT_WRITE_DR2 0x032
+#define SVM_EXIT_WRITE_DR3 0x033
+#define SVM_EXIT_WRITE_DR4 0x034
+#define SVM_EXIT_WRITE_DR5 0x035
+#define SVM_EXIT_WRITE_DR6 0x036
+#define SVM_EXIT_WRITE_DR7 0x037
+#define SVM_EXIT_EXCP_BASE 0x040
+#define SVM_EXIT_INTR  0x060
+#define SVM_EXIT_NMI   0x061
+#define SVM_EXIT_SMI   0x062
+#define SVM_EXIT_INIT  0x063
+#define SVM_EXIT_VINTR 0x064
+#define SVM_EXIT_CR0_SEL_WRITE 0x065
+#define SVM_EXIT_IDTR_READ 0x066
+#define SVM_EXIT_GDTR_READ 0x067
+#define SVM_EXIT_LDTR_READ 0x068
+#define SVM_EXIT_TR_READ   0x069
+#define SVM_EXIT_IDTR_WRITE0x06a
+#define SVM_EXIT_GDTR_WRITE0x06b
+#define SVM_EXIT_LDTR_WRITE0x06c
+#define SVM_EXIT_TR_WRITE  0x06d
+#define SVM_EXIT_RDTSC 0x06e
+#define SVM_EXIT_RDPMC 0x06f
+#define SVM_EXIT_PUSHF 0x070
+#define SVM_EXIT_POPF  0x071
+#define SVM_EXIT_CPUID 0x072
+#define SVM_EXIT_RSM   0x073
+#define SVM_EXIT_IRET  0x074
+#define SVM_EXIT_SWINT 0x075
+#define SVM_EXIT_INVD  0x076
+#define SVM_EXIT_PAUSE 0x077
+#define SVM_EXIT_HLT   0x078
+#define SVM_EXIT_INVLPG0x079
+#define SVM_EXIT_INVLPGA   0x07a
+#define SVM_EXIT_IOIO  0x07b
+#define SVM_EXIT_MSR   0x07c
+#define SVM_EXIT_TASK_SWITCH   0x07d
+#define SVM_EXIT_FERR_FREEZE   0x07e
+#define SVM_EXIT_SHUTDOWN  0x07f
+#define SVM_EXIT_VMRUN 0x080
+#define SVM_EXIT_VMMCALL   0x081
+#define SVM_EXIT_VMLOAD0x082
+#define SVM_EXIT_VMSAVE0x083
+#define SVM_EXIT_STGI  0x084
+#define SVM_EXIT_CLGI  0x085
+#define SVM_EXIT_SKINIT0x086
+#define SVM_EXIT_RDTSCP0x087
+#define SVM_EXIT_ICEBP 0x088
+#define SVM_EXIT_WBINVD0x089
+#define SVM_EXIT_MONITOR   0x08a
+#define SVM_EXIT_MWAIT 0x08b
+#define SVM_EXIT_MWAIT_COND0x08c
+#define SVM_EXIT_XSETBV0x08d
+#define SVM_EXIT_NPF   0x400

[PATCH v8 3/3] KVM: perf: kvm events analysis tool

2012-09-17 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Add 'perf kvm stat' support to analyze kvm vmexit/mmio/ioport smartly

Usage:
- kvm stat
  run a command and gather performance counter statistics, it is the alias of
  perf stat

- trace kvm events:
  perf kvm stat record, or, if other tracepoints are interesting as well, we
  can append the events like this:
  perf kvm stat record -e timer:* -a

  If many guests are running, we can track the specified guest by using -p or
  --pid, -a is used to track events generated by all guests.

- show the result:
  perf kvm stat report

The output example is following:
# pgrep qemu
13005
13059

total 2 guests are running on the host

Then, track the guest whose pid is 13059:
# ./perf kvm stat record -p 13059
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.253 MB perf.data.guest (~11065 samples) ]

See the vmexit events:
# ./perf kvm stat report --event=vmexit


Analyze events for all VCPUs:

 VM-EXITSamples  Samples% Time% Avg time

 APIC_ACCESS46070.55% 0.01% 22.44us ( +-   1.75% )
 HLT 9314.26%99.98% 832077.26us ( +-  10.42% )
  EXTERNAL_INTERRUPT 64 9.82% 0.00% 35.35us ( +-  14.21% )
   PENDING_INTERRUPT 24 3.68% 0.00%  9.29us ( +-  31.39% )
   CR_ACCESS  7 1.07% 0.00%  8.12us ( +-   5.76% )
  IO_INSTRUCTION  3 0.46% 0.00% 18.00us ( +-  11.79% )
   EXCEPTION_NMI  1 0.15% 0.00%  5.83us ( +-   -nan% )

Total Samples:652, Total events handled time:77396109.80us.

See the mmio events:
# ./perf kvm stat report --event=mmio


Analyze events for all VCPUs:

 MMIO AccessSamples  Samples% Time% Avg time

0xfee00380:W38784.31%79.28%  8.29us ( +-   3.32% )
0xfee00300:W 24 5.23% 9.96% 16.79us ( +-   1.97% )
0xfee00300:R 24 5.23% 7.83% 13.20us ( +-   3.00% )
0xfee00310:W 24 5.23% 2.93%  4.94us ( +-   3.84% )

Total Samples:459, Total events handled time:4044.59us.

See the ioport event:
# ./perf kvm stat report --event=ioport


Analyze events for all VCPUs:

  IO Port AccessSamples  Samples% Time% Avg time

 0xc050:POUT  3   100.00%   100.00% 13.75us ( +-  10.83% )

Total Samples:3, Total events handled time:41.26us.

And, --vcpu is used to track the specified vcpu and --key is used to sort the
result:
# ./perf kvm stat report --event=vmexit --vcpu=0 --key=time


Analyze events for VCPU 0:

 VM-EXITSamples  Samples% Time% Avg time

 HLT 2713.85%99.97% 405790.24us ( +-  12.70% )
  EXTERNAL_INTERRUPT 13 6.67% 0.00% 27.94us ( +-  22.26% )
 APIC_ACCESS14674.87% 0.03% 21.69us ( +-   2.91% )
  IO_INSTRUCTION  2 1.03% 0.00% 17.77us ( +-  20.56% )
   CR_ACCESS  2 1.03% 0.00%  8.55us ( +-   6.47% )
   PENDING_INTERRUPT  5 2.56% 0.00%  6.27us ( +-   3.94% )

Total Samples:195, Total events handled time:10959950.90us.

[ Dong Hao haod...@linux.vnet.ibm.com
  Runzhen Wang runz...@linux.vnet.ibm.com:

 - rebase it on current acme's tree

 - fix the compiling-error on i386

]

Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
Signed-off-by: Runzhen Wang runz...@linux.vnet.ibm.com
---
 tools/perf/Documentation/perf-kvm.txt |   30 ++-
 tools/perf/MANIFEST   |3 +
 tools/perf/builtin-kvm.c  |  840 -
 tools/perf/util/header.c  |   59 +++-
 tools/perf/util/header.h  |1 +
 tools/perf/util/thread.h  |2 +
 6 files changed, 929 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/perf-kvm.txt 
b/tools/perf/Documentation/perf-kvm.txt
index dd84cb2..326f2cb 100644
--- a/tools/perf/Documentation/perf-kvm.txt
+++ b/tools/perf/Documentation/perf-kvm.txt
@@ -12,7 +12,7 @@ SYNOPSIS
[--guestkallsyms=path --guestmodules=path | --guestvmlinux=path]]
{top|record|report|diff|buildid-list}
 'perf kvm' [--host] [--guest] [--guestkallsyms=path --guestmodules=path
-   | --guestvmlinux=path] {top|record|report|diff|buildid-list}
+   | --guestvmlinux=path] {top|record|report|diff|buildid-list|stat}
 
 DESCRIPTION
 ---
@@ -38,6 +38,18 @@ There are a couple of variants of perf kvm:
   so that other tools can be used to fetch packages with matching symbol tables
   for use by perf report.
 
+  'perf kvm stat command' to run a command and gather performance counter
+  statistics.
+  Especially, perf 'kvm stat record/report' generates a statistical analysis
+  of KVM events. Currently, vmexit, mmio

[PATCH v8 2/3] perf: move stat related code to util/stat.c

2012-09-17 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Then, the code can be shared between kvm events and perf stat

[ Dong Hao haod...@linux.vnet.ibm.com: rebase it on acme's git tree ]
Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 tools/perf/Makefile   |1 +
 tools/perf/builtin-stat.c |   56 +--
 tools/perf/util/stat.c|   57 +
 tools/perf/util/stat.h|   16 
 4 files changed, 76 insertions(+), 54 deletions(-)
 create mode 100644 tools/perf/util/stat.c
 create mode 100644 tools/perf/util/stat.h

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 209774b..5077f8e 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -406,6 +406,7 @@ LIB_OBJS += $(OUTPUT)util/target.o
 LIB_OBJS += $(OUTPUT)util/rblist.o
 LIB_OBJS += $(OUTPUT)util/intlist.o
 LIB_OBJS += $(OUTPUT)util/vdso.o
+LIB_OBJS += $(OUTPUT)util/stat.o
 
 LIB_OBJS += $(OUTPUT)ui/helpline.o
 LIB_OBJS += $(OUTPUT)ui/hist.o
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index dab347d..3c43a35 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -51,13 +51,13 @@
 #include util/evsel.h
 #include util/debug.h
 #include util/color.h
+#include util/stat.h
 #include util/header.h
 #include util/cpumap.h
 #include util/thread.h
 #include util/thread_map.h
 
 #include sys/prctl.h
-#include math.h
 #include locale.h
 
 #define DEFAULT_SEPARATOR   
@@ -199,11 +199,6 @@ static int output_fd;
 
 static volatile int done = 0;
 
-struct stats
-{
-   double n, mean, M2;
-};
-
 struct perf_stat {
struct stats  res_stats[3];
 };
@@ -220,50 +215,6 @@ static void perf_evsel__free_stat_priv(struct perf_evsel 
*evsel)
evsel-priv = NULL;
 }
 
-static void update_stats(struct stats *stats, u64 val)
-{
-   double delta;
-
-   stats-n++;
-   delta = val - stats-mean;
-   stats-mean += delta / stats-n;
-   stats-M2 += delta*(val - stats-mean);
-}
-
-static double avg_stats(struct stats *stats)
-{
-   return stats-mean;
-}
-
-/*
- * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
- *
- *   (\Sum n_i^2) - ((\Sum n_i)^2)/n
- * s^2 = ---
- *  n - 1
- *
- * http://en.wikipedia.org/wiki/Stddev
- *
- * The std dev of the mean is related to the std dev by:
- *
- * s
- * s_mean = ---
- *  sqrt(n)
- *
- */
-static double stddev_stats(struct stats *stats)
-{
-   double variance, variance_mean;
-
-   if (!stats-n)
-   return 0.0;
-
-   variance = stats-M2 / (stats-n - 1);
-   variance_mean = variance / stats-n;
-
-   return sqrt(variance_mean);
-}
-
 static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
 static struct stats runtime_cycles_stats[MAX_NR_CPUS];
 static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS];
@@ -559,10 +510,7 @@ static int run_perf_stat(int argc __maybe_unused, const 
char **argv)
 
 static void print_noise_pct(double total, double avg)
 {
-   double pct = 0.0;
-
-   if (avg)
-   pct = 100.0*total/avg;
+   double pct = rel_stddev_stats(total, avg);
 
if (csv_output)
fprintf(output, %s%.2f%%, csv_sep, pct);
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
new file mode 100644
index 000..2374212
--- /dev/null
+++ b/tools/perf/util/stat.c
@@ -0,0 +1,57 @@
+#include math.h
+
+#include stat.h
+
+void update_stats(struct stats *stats, u64 val)
+{
+   double delta;
+
+   stats-n++;
+   delta = val - stats-mean;
+   stats-mean += delta / stats-n;
+   stats-M2 += delta*(val - stats-mean);
+}
+
+double avg_stats(struct stats *stats)
+{
+   return stats-mean;
+}
+
+/*
+ * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
+ *
+ *   (\Sum n_i^2) - ((\Sum n_i)^2)/n
+ * s^2 = ---
+ *  n - 1
+ *
+ * http://en.wikipedia.org/wiki/Stddev
+ *
+ * The std dev of the mean is related to the std dev by:
+ *
+ * s
+ * s_mean = ---
+ *  sqrt(n)
+ *
+ */
+double stddev_stats(struct stats *stats)
+{
+   double variance, variance_mean;
+
+   if (!stats-n)
+   return 0.0;
+
+   variance = stats-M2 / (stats-n - 1);
+   variance_mean = variance / stats-n;
+
+   return sqrt(variance_mean);
+}
+
+double rel_stddev_stats(double stddev, double avg)
+{
+   double pct = 0.0;
+
+   if (avg)
+   pct = 100.0 * stddev/avg;
+
+   return pct;
+}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
new file mode 100644
index 000..588367c
--- /dev/null
+++ b/tools/perf/util/stat.h
@@ -0,0 +1,16 @@
+#ifndef __PERF_STATS_H
+#define __PERF_STATS_H
+
+#include types.h
+
+struct stats
+{
+   double n, mean, M2;
+};
+
+void update_stats

[PATCH v7 0/3] KVM: perf: kvm events analysis tool

2012-08-27 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Changelog:
- rebased it on Arnaldo's newest git tree perf/core branch

the change from Arnaldo's comments:
- directly get event from evsel-tp_format
- remove die() and return the proper error code
- rename thread-private to thread-priv

the change from David's comments:
- use is_valid_tracepoint instead of kvm_events_exist 

This patchset introduces a perf-based tool (perf kvm stat record/report)
which can analyze kvm events more smartly. Below is the presentation slice
on 2012 Japan LinuxCon:
http://events.linuxfoundation.org/images/stories/pdf/lcjp2012_guangrong.pdf
You can get more details from it. If any questions/comments, please feel free
to let us know.

This patchset is based on Arnaldo's git tree perf/core branch, and patch 2
is just doing the improvement work, which can be picked up independently.


Usage:
- kvm stat
  run a command and gather performance counter statistics, it is the alias of
  perf stat

- trace kvm events:
  perf kvm stat record, or, if other tracepoints are interesting as well, we
  can append the events like this:
  perf kvm stat record -e kvm:*
  If many guests are running, we can track the specified guest by using -p or
  --pid

- show the result:
  perf kvm stat report

The output example is following:
# pgrep qemu-kvm
26071
32253
32564

total 3 guests are running on the host

Then, track the guest whose pid is 26071:
# ./perf kvm stat record -p 26071
^C[ perf record: Woken up 9 times to write data ]
[ perf record: Captured and wrote 24.903 MB perf.data.guest (~1088034 samples) ]

See the vmexit events:
# ./perf kvm stat report --event=vmexit

Analyze events for all VCPUs:

 VM-EXITSamples  Samples% Time% Avg time

 APIC_ACCESS  6538166.58% 5.95% 37.72us ( +-   6.54% )
  EXTERNAL_INTERRUPT  1603116.32% 3.06% 79.11us ( +-   7.34% )
   CPUID   5360 5.46% 0.06%  4.50us ( +-  35.07% )
 HLT   4496 4.58%90.75%   8360.34us ( +-   5.22% )
   EPT_VIOLATION   2667 2.72% 0.04%  5.49us ( +-   5.05% )
   PENDING_INTERRUPT   2242 2.28% 0.03%  5.25us ( +-   2.96% )
   EXCEPTION_NMI   1332 1.36% 0.02%  6.53us ( +-   6.51% )
  IO_INSTRUCTION383 0.39% 0.09% 93.39us ( +-  40.92% )
   CR_ACCESS310 0.32% 0.00%  6.10us ( +-   3.95% )

Total Samples:98202, Total events handled time:41419293.63us.

See the mmio events:
# ./perf kvm stat report --event=mmio

Analyze events for all VCPUs:

 MMIO AccessSamples  Samples% Time% Avg time

0xfee00380:W  5868690.21%15.67%  4.95us ( +-   2.96% )
0xfee00300:R   2124 3.26% 1.48% 12.93us ( +-  14.75% )
0xfee00310:W   2124 3.26% 0.34%  3.00us ( +-   1.33% )
0xfee00300:W   2123 3.26%82.50%720.68us ( +-  10.24% )

Total Samples:65057, Total events handled time:1854470.45us.

See the ioport event:
# ./perf kvm stat report --event=ioport

Analyze events for all VCPUs:

  IO Port AccessSamples  Samples% Time% Avg time

 0xc090:POUT383   100.00%   100.00% 89.00us ( +-  42.94% )

Total Samples:383, Total events handled time:34085.56us.

And, --vcpu is used to track the specified vcpu and --key is used to sort the
result:
# ./perf kvm stat report --event=vmexit --vcpu=0 --key=time

Analyze events for VCPU 0:

 VM-EXITSamples  Samples% Time% Avg time

 HLT551 5.05%94.81%   9501.72us ( +-  12.52% )
  EXTERNAL_INTERRUPT   139012.74% 2.39% 94.80us ( +-  20.92% )
 APIC_ACCESS   618656.68% 2.62% 23.41us ( +-  23.62% )
  IO_INSTRUCTION 17 0.16% 0.01% 20.39us ( +-  22.33% )
   EXCEPTION_NMI 94 0.86% 0.01%  6.07us ( +-   7.13% )
   PENDING_INTERRUPT199 1.82% 0.02%  5.48us ( +-   4.36% )
   CR_ACCESS 52 0.48% 0.00%  4.89us ( +-   4.09% )
   EPT_VIOLATION   205718.85% 0.12%  3.15us ( +-   1.33% )
   CPUID368 3.37% 0.02%  2.82us ( +-   2.79% )

Total Samples:10914, Total events handled time:5521782.02us.


Dong Hao (3):
  KVM: x86: export svm/vmx exit code and vector code to userspace
  KVM: x86: trace mmio begin and complete
  KVM: perf: kvm events analysis tool

 arch/x86/include/asm/kvm_host.h   |   36 +-
 arch/x86/include/asm/svm.h|  205 +---
 arch/x86/include/asm/vmx.h|  126 +++--
 arch/x86/kvm/trace.h  |   89 
 arch/x86/kvm/x86.c|   32 +-
 include/trace/events/kvm.h|   37 ++
 tools/perf/Documentation/perf-kvm.txt |   30 +-
 tools/perf/MANIFEST   |3 +
 tools/perf/builtin-kvm.c

[PATCH v7 1/3] KVM: x86: export svm/vmx exit code and vector code to userspace

2012-08-27 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Exporting KVM exit information to userspace to be consumed by perf.

[ Dong Hao haod...@linux.vnet.ibm.com: rebase it on acme's git tree ]
Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 arch/x86/include/asm/kvm_host.h |   36 ---
 arch/x86/include/asm/svm.h  |  205 +--
 arch/x86/include/asm/vmx.h  |  126 
 arch/x86/kvm/trace.h|   89 -
 4 files changed, 234 insertions(+), 222 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 09155d6..ad2d229 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -11,6 +11,24 @@
 #ifndef _ASM_X86_KVM_HOST_H
 #define _ASM_X86_KVM_HOST_H
 
+#define DE_VECTOR 0
+#define DB_VECTOR 1
+#define BP_VECTOR 3
+#define OF_VECTOR 4
+#define BR_VECTOR 5
+#define UD_VECTOR 6
+#define NM_VECTOR 7
+#define DF_VECTOR 8
+#define TS_VECTOR 10
+#define NP_VECTOR 11
+#define SS_VECTOR 12
+#define GP_VECTOR 13
+#define PF_VECTOR 14
+#define MF_VECTOR 16
+#define MC_VECTOR 18
+
+#ifdef __KERNEL__
+
 #include linux/types.h
 #include linux/mm.h
 #include linux/mmu_notifier.h
@@ -75,22 +93,6 @@
 #define KVM_HPAGE_MASK(x)  (~(KVM_HPAGE_SIZE(x) - 1))
 #define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
 
-#define DE_VECTOR 0
-#define DB_VECTOR 1
-#define BP_VECTOR 3
-#define OF_VECTOR 4
-#define BR_VECTOR 5
-#define UD_VECTOR 6
-#define NM_VECTOR 7
-#define DF_VECTOR 8
-#define TS_VECTOR 10
-#define NP_VECTOR 11
-#define SS_VECTOR 12
-#define GP_VECTOR 13
-#define PF_VECTOR 14
-#define MF_VECTOR 16
-#define MC_VECTOR 18
-
 #define SELECTOR_TI_MASK (1  2)
 #define SELECTOR_RPL_MASK 0x03
 
@@ -994,4 +996,6 @@ int kvm_pmu_read_pmc(struct kvm_vcpu *vcpu, unsigned pmc, 
u64 *data);
 void kvm_handle_pmu_event(struct kvm_vcpu *vcpu);
 void kvm_deliver_pmi(struct kvm_vcpu *vcpu);
 
+#endif
+
 #endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index f2b83bc..cdf5674 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -1,6 +1,135 @@
 #ifndef __SVM_H
 #define __SVM_H
 
+#define SVM_EXIT_READ_CR0  0x000
+#define SVM_EXIT_READ_CR3  0x003
+#define SVM_EXIT_READ_CR4  0x004
+#define SVM_EXIT_READ_CR8  0x008
+#define SVM_EXIT_WRITE_CR0 0x010
+#define SVM_EXIT_WRITE_CR3 0x013
+#define SVM_EXIT_WRITE_CR4 0x014
+#define SVM_EXIT_WRITE_CR8 0x018
+#define SVM_EXIT_READ_DR0  0x020
+#define SVM_EXIT_READ_DR1  0x021
+#define SVM_EXIT_READ_DR2  0x022
+#define SVM_EXIT_READ_DR3  0x023
+#define SVM_EXIT_READ_DR4  0x024
+#define SVM_EXIT_READ_DR5  0x025
+#define SVM_EXIT_READ_DR6  0x026
+#define SVM_EXIT_READ_DR7  0x027
+#define SVM_EXIT_WRITE_DR0 0x030
+#define SVM_EXIT_WRITE_DR1 0x031
+#define SVM_EXIT_WRITE_DR2 0x032
+#define SVM_EXIT_WRITE_DR3 0x033
+#define SVM_EXIT_WRITE_DR4 0x034
+#define SVM_EXIT_WRITE_DR5 0x035
+#define SVM_EXIT_WRITE_DR6 0x036
+#define SVM_EXIT_WRITE_DR7 0x037
+#define SVM_EXIT_EXCP_BASE 0x040
+#define SVM_EXIT_INTR  0x060
+#define SVM_EXIT_NMI   0x061
+#define SVM_EXIT_SMI   0x062
+#define SVM_EXIT_INIT  0x063
+#define SVM_EXIT_VINTR 0x064
+#define SVM_EXIT_CR0_SEL_WRITE 0x065
+#define SVM_EXIT_IDTR_READ 0x066
+#define SVM_EXIT_GDTR_READ 0x067
+#define SVM_EXIT_LDTR_READ 0x068
+#define SVM_EXIT_TR_READ   0x069
+#define SVM_EXIT_IDTR_WRITE0x06a
+#define SVM_EXIT_GDTR_WRITE0x06b
+#define SVM_EXIT_LDTR_WRITE0x06c
+#define SVM_EXIT_TR_WRITE  0x06d
+#define SVM_EXIT_RDTSC 0x06e
+#define SVM_EXIT_RDPMC 0x06f
+#define SVM_EXIT_PUSHF 0x070
+#define SVM_EXIT_POPF  0x071
+#define SVM_EXIT_CPUID 0x072
+#define SVM_EXIT_RSM   0x073
+#define SVM_EXIT_IRET  0x074
+#define SVM_EXIT_SWINT 0x075
+#define SVM_EXIT_INVD  0x076
+#define SVM_EXIT_PAUSE 0x077
+#define SVM_EXIT_HLT   0x078
+#define SVM_EXIT_INVLPG0x079
+#define SVM_EXIT_INVLPGA   0x07a
+#define SVM_EXIT_IOIO  0x07b
+#define SVM_EXIT_MSR   0x07c
+#define SVM_EXIT_TASK_SWITCH   0x07d
+#define SVM_EXIT_FERR_FREEZE   0x07e
+#define SVM_EXIT_SHUTDOWN  0x07f
+#define SVM_EXIT_VMRUN 0x080
+#define SVM_EXIT_VMMCALL   0x081
+#define SVM_EXIT_VMLOAD0x082
+#define SVM_EXIT_VMSAVE0x083
+#define SVM_EXIT_STGI  0x084
+#define SVM_EXIT_CLGI  0x085
+#define SVM_EXIT_SKINIT0x086
+#define SVM_EXIT_RDTSCP0x087
+#define SVM_EXIT_ICEBP 0x088
+#define SVM_EXIT_WBINVD0x089
+#define SVM_EXIT_MONITOR   0x08a
+#define SVM_EXIT_MWAIT 0x08b
+#define SVM_EXIT_MWAIT_COND0x08c
+#define SVM_EXIT_XSETBV0x08d
+#define

[PATCH v7 2/3] KVM: x86: trace mmio begin and complete

2012-08-27 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

'perf kvm stat record/report' will use kvm_exit and kvm_mmio(read...) to
calculate mmio read emulated time for the old kernel, in order to trace
mmio read event more exactly, we add kvm_mmio_begin to trace the time when
mmio read begins, also, add kvm_io_done to trace the time when mmio/pio is
completed

[ Dong Hao haod...@linux.vnet.ibm.com: rebase it on current kvm tree ]
Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 arch/x86/kvm/x86.c |   32 
 include/trace/events/kvm.h |   37 +
 2 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 42bce48..b90394d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3828,9 +3828,12 @@ mmio:
/*
 * Is this MMIO handled locally?
 */
+   trace_kvm_mmio_begin(vcpu-vcpu_id, write, gpa);
handled = ops-read_write_mmio(vcpu, gpa, bytes, val);
-   if (handled == bytes)
+   if (handled == bytes) {
+   trace_kvm_io_done(vcpu-vcpu_id);
return X86EMUL_CONTINUE;
+   }
 
gpa += handled;
bytes -= handled;
@@ -4025,6 +4028,7 @@ static int emulator_pio_in_out(struct kvm_vcpu *vcpu, int 
size,
vcpu-arch.pio.size = size;
 
if (!kernel_pio(vcpu, vcpu-arch.pio_data)) {
+   trace_kvm_io_done(vcpu-vcpu_id);
vcpu-arch.pio.count = 0;
return 1;
}
@@ -4625,9 +4629,7 @@ restart:
inject_emulated_exception(vcpu);
r = EMULATE_DONE;
} else if (vcpu-arch.pio.count) {
-   if (!vcpu-arch.pio.in)
-   vcpu-arch.pio.count = 0;
-   else
+   if (vcpu-arch.pio.in)
writeback = false;
r = EMULATE_DO_MMIO;
} else if (vcpu-mmio_needed) {
@@ -4658,8 +4660,6 @@ int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, 
unsigned short port)
unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX);
int ret = emulator_pio_out_emulated(vcpu-arch.emulate_ctxt,
size, port, val, 1);
-   /* do not return to emulator after return from userspace */
-   vcpu-arch.pio.count = 0;
return ret;
 }
 EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
@@ -5509,11 +5509,16 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
 {
struct kvm_run *run = vcpu-run;
struct kvm_mmio_fragment *frag;
-   int r;
+   int r = 1;
 
if (!(vcpu-arch.pio.count || vcpu-mmio_needed))
return 1;
 
+   if (vcpu-arch.pio.count  !vcpu-arch.pio.in) {
+   vcpu-arch.pio.count = 0;
+   goto exit;
+   }
+
if (vcpu-mmio_needed) {
/* Complete previous fragment */
frag = vcpu-mmio_fragments[vcpu-mmio_cur_fragment++];
@@ -5521,8 +5526,10 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
memcpy(frag-data, run-mmio.data, frag-len);
if (vcpu-mmio_cur_fragment == vcpu-mmio_nr_fragments) {
vcpu-mmio_needed = 0;
+
if (vcpu-mmio_is_write)
-   return 1;
+   goto exit;
+
vcpu-mmio_read_completed = 1;
goto done;
}
@@ -5539,11 +5546,12 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
}
 done:
vcpu-srcu_idx = srcu_read_lock(vcpu-kvm-srcu);
-   r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
+   r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE) == EMULATE_DONE;
srcu_read_unlock(vcpu-kvm-srcu, vcpu-srcu_idx);
-   if (r != EMULATE_DONE)
-   return 0;
-   return 1;
+
+exit:
+   trace_kvm_io_done(vcpu-vcpu_id);
+   return r;
 }
 
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index 7ef9e75..d4182fa 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h
@@ -177,6 +177,43 @@ TRACE_EVENT(kvm_mmio,
  __entry-len, __entry-gpa, __entry-val)
 );
 
+TRACE_EVENT(kvm_mmio_begin,
+   TP_PROTO(unsigned int vcpu_id, bool rw, u64 gpa),
+   TP_ARGS(vcpu_id, rw, gpa),
+
+   TP_STRUCT__entry(
+   __field(unsigned int, vcpu_id)
+   __field(int, type)
+   __field(u64, gpa)
+   ),
+
+   TP_fast_assign(
+   __entry-vcpu_id = vcpu_id;
+   __entry-type = rw ? KVM_TRACE_MMIO_WRITE :
+ KVM_TRACE_MMIO_READ;
+   __entry-gpa = gpa;
+   ),
+
+   TP_printk(vcpu %u mmio %s gpa 0x%llx, __entry-vcpu_id,
+ __print_symbolic(__entry

[PATCH v7 3/3] KVM: perf: kvm events analysis tool

2012-08-27 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Add 'perf kvm stat' support to analyze kvm vmexit/mmio/ioport smartly

Usage:
- kvm stat
  run a command and gather performance counter statistics, it is the alias of
  perf stat

- trace kvm events:
  perf kvm stat record, or, if other tracepoints are interesting as well, we
  can append the events like this:
  perf kvm stat record -e timer:*
  If many guests are running, we can track the specified guest by using -p or
  --pid

- show the result:
  perf kvm stat report

The output example is following:
# pgrep qemu-kvm
26071
32253
32564

total 3 guests are running on the host

Then, track the guest whose pid is 26071:
# ./perf kvm stat record -p 26071
^C[ perf record: Woken up 9 times to write data ]
[ perf record: Captured and wrote 24.903 MB perf.data.guest (~1088034 samples) ]

See the vmexit events:
# ./perf kvm stat report --event=vmexit

Analyze events for all VCPUs:

 VM-EXITSamples  Samples% Time% Avg time

 APIC_ACCESS  6538166.58% 5.95% 37.72us ( +-   6.54% )
  EXTERNAL_INTERRUPT  1603116.32% 3.06% 79.11us ( +-   7.34% )
   CPUID   5360 5.46% 0.06%  4.50us ( +-  35.07% )
 HLT   4496 4.58%90.75%   8360.34us ( +-   5.22% )
   EPT_VIOLATION   2667 2.72% 0.04%  5.49us ( +-   5.05% )
   PENDING_INTERRUPT   2242 2.28% 0.03%  5.25us ( +-   2.96% )
   EXCEPTION_NMI   1332 1.36% 0.02%  6.53us ( +-   6.51% )
  IO_INSTRUCTION383 0.39% 0.09% 93.39us ( +-  40.92% )
   CR_ACCESS310 0.32% 0.00%  6.10us ( +-   3.95% )

Total Samples:98202, Total events handled time:41419293.63us.

See the mmio events:
# ./perf kvm stat report --event=mmio

Analyze events for all VCPUs:

 MMIO AccessSamples  Samples% Time% Avg time

0xfee00380:W  5868690.21%15.67%  4.95us ( +-   2.96% )
0xfee00300:R   2124 3.26% 1.48% 12.93us ( +-  14.75% )
0xfee00310:W   2124 3.26% 0.34%  3.00us ( +-   1.33% )
0xfee00300:W   2123 3.26%82.50%720.68us ( +-  10.24% )

Total Samples:65057, Total events handled time:1854470.45us.

See the ioport event:
# ./perf kvm stat report --event=ioport

Analyze events for all VCPUs:

  IO Port AccessSamples  Samples% Time% Avg time

 0xc090:POUT383   100.00%   100.00% 89.00us ( +-  42.94% )

Total Samples:383, Total events handled time:34085.56us.

And, --vcpu is used to track the specified vcpu and --key is used to sort the
result:
# ./perf kvm stat report --event=vmexit --vcpu=0 --key=time

Analyze events for VCPU 0:

 VM-EXITSamples  Samples% Time% Avg time

 HLT551 5.05%94.81%   9501.72us ( +-  12.52% )
  EXTERNAL_INTERRUPT   139012.74% 2.39% 94.80us ( +-  20.92% )
 APIC_ACCESS   618656.68% 2.62% 23.41us ( +-  23.62% )
  IO_INSTRUCTION 17 0.16% 0.01% 20.39us ( +-  22.33% )
   EXCEPTION_NMI 94 0.86% 0.01%  6.07us ( +-   7.13% )
   PENDING_INTERRUPT199 1.82% 0.02%  5.48us ( +-   4.36% )
   CR_ACCESS 52 0.48% 0.00%  4.89us ( +-   4.09% )
   EPT_VIOLATION   205718.85% 0.12%  3.15us ( +-   1.33% )
   CPUID368 3.37% 0.02%  2.82us ( +-   2.79% )

Total Samples:10914, Total events handled time:5521782.02us.

[ Dong Hao haod...@linux.vnet.ibm.com:
 - rebase it on current acme's tree
 - fix the compiling-error on i386
]

Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 tools/perf/Documentation/perf-kvm.txt |   30 +-
 tools/perf/MANIFEST   |3 +
 tools/perf/builtin-kvm.c  |  889 -
 tools/perf/util/header.c  |   54 ++-
 tools/perf/util/header.h  |1 +
 tools/perf/util/thread.h  |2 +
 6 files changed, 973 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/perf-kvm.txt 
b/tools/perf/Documentation/perf-kvm.txt
index dd84cb2..326f2cb 100644
--- a/tools/perf/Documentation/perf-kvm.txt
+++ b/tools/perf/Documentation/perf-kvm.txt
@@ -12,7 +12,7 @@ SYNOPSIS
[--guestkallsyms=path --guestmodules=path | --guestvmlinux=path]]
{top|record|report|diff|buildid-list}
 'perf kvm' [--host] [--guest] [--guestkallsyms=path --guestmodules=path
-   | --guestvmlinux=path] {top|record|report|diff|buildid-list}
+   | --guestvmlinux=path] {top|record|report|diff|buildid-list|stat}
 
 DESCRIPTION
 ---
@@ -38,6 +38,18 @@ There are a couple of variants of perf kvm:
   so that other tools can be used to fetch packages with matching

[PATCH v7 0/3] KVM: perf: kvm events analysis tool

2012-08-23 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Changelog:
- rebased it on Arnaldo's git tree perf/core branch

the change from Arnaldo's comments:
- directly get event from evsel-tp_format
- remove die() and return the proper error code
- rename thread-private to thread-priv

the change from David's comments:
- use is_valid_tracepoint instead of kvm_events_exist 

This patchset introduces a perf-based tool (perf kvm stat record/report)
which can analyze kvm events more smartly. Below is the presentation slice
on 2012 Japan LinuxCon:
http://events.linuxfoundation.org/images/stories/pdf/lcjp2012_guangrong.pdf
You can get more details from it. If any questions/comments, please feel free
to let us know.

This patchset is based on Arnaldo's git tree perf/core branch, and patch 2
is just doing the improvement work, which can be picked up independently.


Usage:
- kvm stat
  run a command and gather performance counter statistics, it is the alias of
  perf stat

- trace kvm events:
  perf kvm stat record, or, if other tracepoints are interesting as well, we
  can append the events like this:
  perf kvm stat record -e kvm:*
  If many guests are running, we can track the specified guest by using -p or
  --pid

- show the result:
  perf kvm stat report

The output example is following:
# pgrep qemu-kvm
26071
32253
32564

total 3 guests are running on the host

Then, track the guest whose pid is 26071:
# ./perf kvm stat record -p 26071
^C[ perf record: Woken up 9 times to write data ]
[ perf record: Captured and wrote 24.903 MB perf.data.guest (~1088034 samples) ]

See the vmexit events:
# ./perf kvm stat report --event=vmexit

Analyze events for all VCPUs:

 VM-EXITSamples  Samples% Time% Avg time

 APIC_ACCESS  6538166.58% 5.95% 37.72us ( +-   6.54% )
  EXTERNAL_INTERRUPT  1603116.32% 3.06% 79.11us ( +-   7.34% )
   CPUID   5360 5.46% 0.06%  4.50us ( +-  35.07% )
 HLT   4496 4.58%90.75%   8360.34us ( +-   5.22% )
   EPT_VIOLATION   2667 2.72% 0.04%  5.49us ( +-   5.05% )
   PENDING_INTERRUPT   2242 2.28% 0.03%  5.25us ( +-   2.96% )
   EXCEPTION_NMI   1332 1.36% 0.02%  6.53us ( +-   6.51% )
  IO_INSTRUCTION383 0.39% 0.09% 93.39us ( +-  40.92% )
   CR_ACCESS310 0.32% 0.00%  6.10us ( +-   3.95% )

Total Samples:98202, Total events handled time:41419293.63us.

See the mmio events:
# ./perf kvm stat report --event=mmio

Analyze events for all VCPUs:

 MMIO AccessSamples  Samples% Time% Avg time

0xfee00380:W  5868690.21%15.67%  4.95us ( +-   2.96% )
0xfee00300:R   2124 3.26% 1.48% 12.93us ( +-  14.75% )
0xfee00310:W   2124 3.26% 0.34%  3.00us ( +-   1.33% )
0xfee00300:W   2123 3.26%82.50%720.68us ( +-  10.24% )

Total Samples:65057, Total events handled time:1854470.45us.

See the ioport event:
# ./perf kvm stat report --event=ioport

Analyze events for all VCPUs:

  IO Port AccessSamples  Samples% Time% Avg time

 0xc090:POUT383   100.00%   100.00% 89.00us ( +-  42.94% )

Total Samples:383, Total events handled time:34085.56us.

And, --vcpu is used to track the specified vcpu and --key is used to sort the
result:
# ./perf kvm stat report --event=vmexit --vcpu=0 --key=time

Analyze events for VCPU 0:

 VM-EXITSamples  Samples% Time% Avg time

 HLT551 5.05%94.81%   9501.72us ( +-  12.52% )
  EXTERNAL_INTERRUPT   139012.74% 2.39% 94.80us ( +-  20.92% )
 APIC_ACCESS   618656.68% 2.62% 23.41us ( +-  23.62% )
  IO_INSTRUCTION 17 0.16% 0.01% 20.39us ( +-  22.33% )
   EXCEPTION_NMI 94 0.86% 0.01%  6.07us ( +-   7.13% )
   PENDING_INTERRUPT199 1.82% 0.02%  5.48us ( +-   4.36% )
   CR_ACCESS 52 0.48% 0.00%  4.89us ( +-   4.09% )
   EPT_VIOLATION   205718.85% 0.12%  3.15us ( +-   1.33% )
   CPUID368 3.37% 0.02%  2.82us ( +-   2.79% )

Total Samples:10914, Total events handled time:5521782.02us.


Dong Hao (3):
  KVM: x86: export svm/vmx exit code and vector code to userspace
  KVM: x86: trace mmio begin and complete
  KVM: perf: kvm events analysis tool

 arch/x86/include/asm/kvm_host.h   |   36 +-
 arch/x86/include/asm/svm.h|  205 +---
 arch/x86/include/asm/vmx.h|  126 +++--
 arch/x86/kvm/trace.h  |   89 
 arch/x86/kvm/x86.c|   32 +-
 include/trace/events/kvm.h|   37 ++
 tools/perf/Documentation/perf-kvm.txt |   30 +-
 tools/perf/MANIFEST   |3 +
 tools/perf/builtin-kvm.c

[PATCH v7 2/3] KVM: x86: trace mmio begin and complete

2012-08-23 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

'perf kvm stat record/report' will use kvm_exit and kvm_mmio(read...) to
calculate mmio read emulated time for the old kernel, in order to trace
mmio read event more exactly, we add kvm_mmio_begin to trace the time when
mmio read begins, also, add kvm_io_done to trace the time when mmio/pio is
completed

[ Dong Hao haod...@linux.vnet.ibm.com: rebase it on current kvm tree ]
Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 arch/x86/kvm/x86.c |   32 
 include/trace/events/kvm.h |   37 +
 2 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 42bce48..b90394d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3828,9 +3828,12 @@ mmio:
/*
 * Is this MMIO handled locally?
 */
+   trace_kvm_mmio_begin(vcpu-vcpu_id, write, gpa);
handled = ops-read_write_mmio(vcpu, gpa, bytes, val);
-   if (handled == bytes)
+   if (handled == bytes) {
+   trace_kvm_io_done(vcpu-vcpu_id);
return X86EMUL_CONTINUE;
+   }
 
gpa += handled;
bytes -= handled;
@@ -4025,6 +4028,7 @@ static int emulator_pio_in_out(struct kvm_vcpu *vcpu, int 
size,
vcpu-arch.pio.size = size;
 
if (!kernel_pio(vcpu, vcpu-arch.pio_data)) {
+   trace_kvm_io_done(vcpu-vcpu_id);
vcpu-arch.pio.count = 0;
return 1;
}
@@ -4625,9 +4629,7 @@ restart:
inject_emulated_exception(vcpu);
r = EMULATE_DONE;
} else if (vcpu-arch.pio.count) {
-   if (!vcpu-arch.pio.in)
-   vcpu-arch.pio.count = 0;
-   else
+   if (vcpu-arch.pio.in)
writeback = false;
r = EMULATE_DO_MMIO;
} else if (vcpu-mmio_needed) {
@@ -4658,8 +4660,6 @@ int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, 
unsigned short port)
unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX);
int ret = emulator_pio_out_emulated(vcpu-arch.emulate_ctxt,
size, port, val, 1);
-   /* do not return to emulator after return from userspace */
-   vcpu-arch.pio.count = 0;
return ret;
 }
 EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
@@ -5509,11 +5509,16 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
 {
struct kvm_run *run = vcpu-run;
struct kvm_mmio_fragment *frag;
-   int r;
+   int r = 1;
 
if (!(vcpu-arch.pio.count || vcpu-mmio_needed))
return 1;
 
+   if (vcpu-arch.pio.count  !vcpu-arch.pio.in) {
+   vcpu-arch.pio.count = 0;
+   goto exit;
+   }
+
if (vcpu-mmio_needed) {
/* Complete previous fragment */
frag = vcpu-mmio_fragments[vcpu-mmio_cur_fragment++];
@@ -5521,8 +5526,10 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
memcpy(frag-data, run-mmio.data, frag-len);
if (vcpu-mmio_cur_fragment == vcpu-mmio_nr_fragments) {
vcpu-mmio_needed = 0;
+
if (vcpu-mmio_is_write)
-   return 1;
+   goto exit;
+
vcpu-mmio_read_completed = 1;
goto done;
}
@@ -5539,11 +5546,12 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
}
 done:
vcpu-srcu_idx = srcu_read_lock(vcpu-kvm-srcu);
-   r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
+   r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE) == EMULATE_DONE;
srcu_read_unlock(vcpu-kvm-srcu, vcpu-srcu_idx);
-   if (r != EMULATE_DONE)
-   return 0;
-   return 1;
+
+exit:
+   trace_kvm_io_done(vcpu-vcpu_id);
+   return r;
 }
 
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index 7ef9e75..d4182fa 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h
@@ -177,6 +177,43 @@ TRACE_EVENT(kvm_mmio,
  __entry-len, __entry-gpa, __entry-val)
 );
 
+TRACE_EVENT(kvm_mmio_begin,
+   TP_PROTO(unsigned int vcpu_id, bool rw, u64 gpa),
+   TP_ARGS(vcpu_id, rw, gpa),
+
+   TP_STRUCT__entry(
+   __field(unsigned int, vcpu_id)
+   __field(int, type)
+   __field(u64, gpa)
+   ),
+
+   TP_fast_assign(
+   __entry-vcpu_id = vcpu_id;
+   __entry-type = rw ? KVM_TRACE_MMIO_WRITE :
+ KVM_TRACE_MMIO_READ;
+   __entry-gpa = gpa;
+   ),
+
+   TP_printk(vcpu %u mmio %s gpa 0x%llx, __entry-vcpu_id,
+ __print_symbolic(__entry

[PATCH v7 3/3] KVM: perf: kvm events analysis tool

2012-08-23 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Add 'perf kvm stat' support to analyze kvm vmexit/mmio/ioport smartly

Usage:
- kvm stat
  run a command and gather performance counter statistics, it is the alias of
  perf stat

- trace kvm events:
  perf kvm stat record, or, if other tracepoints are interesting as well, we
  can append the events like this:
  perf kvm stat record -e timer:*
  If many guests are running, we can track the specified guest by using -p or
  --pid

- show the result:
  perf kvm stat report

The output example is following:
# pgrep qemu-kvm
26071
32253
32564

total 3 guests are running on the host

Then, track the guest whose pid is 26071:
# ./perf kvm stat record -p 26071
^C[ perf record: Woken up 9 times to write data ]
[ perf record: Captured and wrote 24.903 MB perf.data.guest (~1088034 samples) ]

See the vmexit events:
# ./perf kvm stat report --event=vmexit

Analyze events for all VCPUs:

 VM-EXITSamples  Samples% Time% Avg time

 APIC_ACCESS  6538166.58% 5.95% 37.72us ( +-   6.54% )
  EXTERNAL_INTERRUPT  1603116.32% 3.06% 79.11us ( +-   7.34% )
   CPUID   5360 5.46% 0.06%  4.50us ( +-  35.07% )
 HLT   4496 4.58%90.75%   8360.34us ( +-   5.22% )
   EPT_VIOLATION   2667 2.72% 0.04%  5.49us ( +-   5.05% )
   PENDING_INTERRUPT   2242 2.28% 0.03%  5.25us ( +-   2.96% )
   EXCEPTION_NMI   1332 1.36% 0.02%  6.53us ( +-   6.51% )
  IO_INSTRUCTION383 0.39% 0.09% 93.39us ( +-  40.92% )
   CR_ACCESS310 0.32% 0.00%  6.10us ( +-   3.95% )

Total Samples:98202, Total events handled time:41419293.63us.

See the mmio events:
# ./perf kvm stat report --event=mmio

Analyze events for all VCPUs:

 MMIO AccessSamples  Samples% Time% Avg time

0xfee00380:W  5868690.21%15.67%  4.95us ( +-   2.96% )
0xfee00300:R   2124 3.26% 1.48% 12.93us ( +-  14.75% )
0xfee00310:W   2124 3.26% 0.34%  3.00us ( +-   1.33% )
0xfee00300:W   2123 3.26%82.50%720.68us ( +-  10.24% )

Total Samples:65057, Total events handled time:1854470.45us.

See the ioport event:
# ./perf kvm stat report --event=ioport

Analyze events for all VCPUs:

  IO Port AccessSamples  Samples% Time% Avg time

 0xc090:POUT383   100.00%   100.00% 89.00us ( +-  42.94% )

Total Samples:383, Total events handled time:34085.56us.

And, --vcpu is used to track the specified vcpu and --key is used to sort the
result:
# ./perf kvm stat report --event=vmexit --vcpu=0 --key=time

Analyze events for VCPU 0:

 VM-EXITSamples  Samples% Time% Avg time

 HLT551 5.05%94.81%   9501.72us ( +-  12.52% )
  EXTERNAL_INTERRUPT   139012.74% 2.39% 94.80us ( +-  20.92% )
 APIC_ACCESS   618656.68% 2.62% 23.41us ( +-  23.62% )
  IO_INSTRUCTION 17 0.16% 0.01% 20.39us ( +-  22.33% )
   EXCEPTION_NMI 94 0.86% 0.01%  6.07us ( +-   7.13% )
   PENDING_INTERRUPT199 1.82% 0.02%  5.48us ( +-   4.36% )
   CR_ACCESS 52 0.48% 0.00%  4.89us ( +-   4.09% )
   EPT_VIOLATION   205718.85% 0.12%  3.15us ( +-   1.33% )
   CPUID368 3.37% 0.02%  2.82us ( +-   2.79% )

Total Samples:10914, Total events handled time:5521782.02us.

[ Dong Hao haod...@linux.vnet.ibm.com:
 - rebase it on current acme's tree
 - fix the compiling-error on i386
]

Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 tools/perf/Documentation/perf-kvm.txt |   30 +-
 tools/perf/MANIFEST   |3 +
 tools/perf/builtin-kvm.c  |  889 -
 tools/perf/util/header.c  |   54 ++-
 tools/perf/util/header.h  |1 +
 tools/perf/util/thread.h  |2 +
 6 files changed, 973 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/perf-kvm.txt 
b/tools/perf/Documentation/perf-kvm.txt
index dd84cb2..d52feef 100644
--- a/tools/perf/Documentation/perf-kvm.txt
+++ b/tools/perf/Documentation/perf-kvm.txt
@@ -12,7 +12,7 @@ SYNOPSIS
[--guestkallsyms=path --guestmodules=path | --guestvmlinux=path]]
{top|record|report|diff|buildid-list}
 'perf kvm' [--host] [--guest] [--guestkallsyms=path --guestmodules=path
-   | --guestvmlinux=path] {top|record|report|diff|buildid-list}
+   | --guestvmlinux=path] {top|record|report|diff|buildid-list|stat}
 
 DESCRIPTION
 ---
@@ -38,6 +38,18 @@ There are a couple of variants of perf kvm:
   so that other tools can be used to fetch packages with matching

[PATCH v7 1/3] KVM: x86: export svm/vmx exit code and vector code to userspace

2012-08-23 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Exporting KVM exit information to userspace to be consumed by perf.

[ Dong Hao haod...@linux.vnet.ibm.com: rebase it on acme's git tree ]
Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 arch/x86/include/asm/kvm_host.h |   36 ---
 arch/x86/include/asm/svm.h  |  205 +--
 arch/x86/include/asm/vmx.h  |  126 
 arch/x86/kvm/trace.h|   89 -
 4 files changed, 234 insertions(+), 222 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 09155d6..ad2d229 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -11,6 +11,24 @@
 #ifndef _ASM_X86_KVM_HOST_H
 #define _ASM_X86_KVM_HOST_H
 
+#define DE_VECTOR 0
+#define DB_VECTOR 1
+#define BP_VECTOR 3
+#define OF_VECTOR 4
+#define BR_VECTOR 5
+#define UD_VECTOR 6
+#define NM_VECTOR 7
+#define DF_VECTOR 8
+#define TS_VECTOR 10
+#define NP_VECTOR 11
+#define SS_VECTOR 12
+#define GP_VECTOR 13
+#define PF_VECTOR 14
+#define MF_VECTOR 16
+#define MC_VECTOR 18
+
+#ifdef __KERNEL__
+
 #include linux/types.h
 #include linux/mm.h
 #include linux/mmu_notifier.h
@@ -75,22 +93,6 @@
 #define KVM_HPAGE_MASK(x)  (~(KVM_HPAGE_SIZE(x) - 1))
 #define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
 
-#define DE_VECTOR 0
-#define DB_VECTOR 1
-#define BP_VECTOR 3
-#define OF_VECTOR 4
-#define BR_VECTOR 5
-#define UD_VECTOR 6
-#define NM_VECTOR 7
-#define DF_VECTOR 8
-#define TS_VECTOR 10
-#define NP_VECTOR 11
-#define SS_VECTOR 12
-#define GP_VECTOR 13
-#define PF_VECTOR 14
-#define MF_VECTOR 16
-#define MC_VECTOR 18
-
 #define SELECTOR_TI_MASK (1  2)
 #define SELECTOR_RPL_MASK 0x03
 
@@ -994,4 +996,6 @@ int kvm_pmu_read_pmc(struct kvm_vcpu *vcpu, unsigned pmc, 
u64 *data);
 void kvm_handle_pmu_event(struct kvm_vcpu *vcpu);
 void kvm_deliver_pmi(struct kvm_vcpu *vcpu);
 
+#endif
+
 #endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index f2b83bc..cdf5674 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -1,6 +1,135 @@
 #ifndef __SVM_H
 #define __SVM_H
 
+#define SVM_EXIT_READ_CR0  0x000
+#define SVM_EXIT_READ_CR3  0x003
+#define SVM_EXIT_READ_CR4  0x004
+#define SVM_EXIT_READ_CR8  0x008
+#define SVM_EXIT_WRITE_CR0 0x010
+#define SVM_EXIT_WRITE_CR3 0x013
+#define SVM_EXIT_WRITE_CR4 0x014
+#define SVM_EXIT_WRITE_CR8 0x018
+#define SVM_EXIT_READ_DR0  0x020
+#define SVM_EXIT_READ_DR1  0x021
+#define SVM_EXIT_READ_DR2  0x022
+#define SVM_EXIT_READ_DR3  0x023
+#define SVM_EXIT_READ_DR4  0x024
+#define SVM_EXIT_READ_DR5  0x025
+#define SVM_EXIT_READ_DR6  0x026
+#define SVM_EXIT_READ_DR7  0x027
+#define SVM_EXIT_WRITE_DR0 0x030
+#define SVM_EXIT_WRITE_DR1 0x031
+#define SVM_EXIT_WRITE_DR2 0x032
+#define SVM_EXIT_WRITE_DR3 0x033
+#define SVM_EXIT_WRITE_DR4 0x034
+#define SVM_EXIT_WRITE_DR5 0x035
+#define SVM_EXIT_WRITE_DR6 0x036
+#define SVM_EXIT_WRITE_DR7 0x037
+#define SVM_EXIT_EXCP_BASE 0x040
+#define SVM_EXIT_INTR  0x060
+#define SVM_EXIT_NMI   0x061
+#define SVM_EXIT_SMI   0x062
+#define SVM_EXIT_INIT  0x063
+#define SVM_EXIT_VINTR 0x064
+#define SVM_EXIT_CR0_SEL_WRITE 0x065
+#define SVM_EXIT_IDTR_READ 0x066
+#define SVM_EXIT_GDTR_READ 0x067
+#define SVM_EXIT_LDTR_READ 0x068
+#define SVM_EXIT_TR_READ   0x069
+#define SVM_EXIT_IDTR_WRITE0x06a
+#define SVM_EXIT_GDTR_WRITE0x06b
+#define SVM_EXIT_LDTR_WRITE0x06c
+#define SVM_EXIT_TR_WRITE  0x06d
+#define SVM_EXIT_RDTSC 0x06e
+#define SVM_EXIT_RDPMC 0x06f
+#define SVM_EXIT_PUSHF 0x070
+#define SVM_EXIT_POPF  0x071
+#define SVM_EXIT_CPUID 0x072
+#define SVM_EXIT_RSM   0x073
+#define SVM_EXIT_IRET  0x074
+#define SVM_EXIT_SWINT 0x075
+#define SVM_EXIT_INVD  0x076
+#define SVM_EXIT_PAUSE 0x077
+#define SVM_EXIT_HLT   0x078
+#define SVM_EXIT_INVLPG0x079
+#define SVM_EXIT_INVLPGA   0x07a
+#define SVM_EXIT_IOIO  0x07b
+#define SVM_EXIT_MSR   0x07c
+#define SVM_EXIT_TASK_SWITCH   0x07d
+#define SVM_EXIT_FERR_FREEZE   0x07e
+#define SVM_EXIT_SHUTDOWN  0x07f
+#define SVM_EXIT_VMRUN 0x080
+#define SVM_EXIT_VMMCALL   0x081
+#define SVM_EXIT_VMLOAD0x082
+#define SVM_EXIT_VMSAVE0x083
+#define SVM_EXIT_STGI  0x084
+#define SVM_EXIT_CLGI  0x085
+#define SVM_EXIT_SKINIT0x086
+#define SVM_EXIT_RDTSCP0x087
+#define SVM_EXIT_ICEBP 0x088
+#define SVM_EXIT_WBINVD0x089
+#define SVM_EXIT_MONITOR   0x08a
+#define SVM_EXIT_MWAIT 0x08b
+#define SVM_EXIT_MWAIT_COND0x08c
+#define SVM_EXIT_XSETBV0x08d
+#define

[PATCH v6 0/3] KVM: perf: kvm events analysis tool

2012-08-09 Thread Dong Hao
From: Xiao Guangrongxiaoguangr...@linux.vnet.ibm.com

This patchset introduces a perf-based tool (perf kvm stat record/report)
which can analysis kvm events more smartly. This is a presentation on
2012 Japan LinuxCon:
http://events.linuxfoundation.org/images/stories/pdf/lcjp2012_guangrong.pdf
You can get more detail from it. Any question/comment please feel free let
us know.

Patch 1 and patch 3 can be applied to either tip tree or kvm tree, but patch 2
can only be applied to kvm tree. Fortunately, patch 2 is just doing the
improvement work, and it can be picked up independently.

Usage:
- kvm stat
  run a command and gather performance counter statistics, it is the alias of
  perf stat

- trace kvm events:
  perf kvm stat record, or, if other tracepoints are interesting as well, we
  can append the events like this:
  perf kvm stat record -e timer:*
  If many guests are running, we can track the specified guest by using -p or
  --pid

- show the result:
  perf kvm stat report

The output example is following:
# pgrep qemu-kvm
27841
27888
27936

total 3 guests are running on the host

Then, track the guest whose pid is 27936:
# ./perf kvm stat record -p 27936
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.177 MB perf.data.guest (~7742 samples) ]

See the vmexit events:
# ./perf kvm stat report --event=vmexit


Analyze events for all VCPUs:

 VM-EXITSamples  Samples% Time% Avg time

 APIC_ACCESS23780.34% 0.01% 20.86us ( +-   8.03% )
 HLT 4515.25%99.98% 790874.75us ( +-  16.93% )
  EXTERNAL_INTERRUPT 11 3.73% 0.00% 47.70us ( +-  17.45% )
   EXCEPTION_NMI  1 0.34% 0.00%  5.11us ( +-   -nan% )
   CR_ACCESS  1 0.34% 0.00%  6.33us ( +-   -nan% )

Total Samples:295, Total events handled time:35594844.34us.

See the mmio events:
# ./perf kvm stat report --event=mmio


Analyze events for all VCPUs:

 MMIO AccessSamples  Samples% Time% Avg time

0xfee00380:W15182.07%76.19%  7.72us ( +-  11.96% )
0xfee00300:W 11 5.98%18.86% 26.23us ( +-  27.33% )
0xfee00300:R 11 5.98% 2.16%  3.00us ( +-   9.17% )
0xfee00310:W 11 5.98% 2.79%  3.88us ( +-   9.15% )

Total Samples:184, Total events handled time:1529.42us.

See the ioport event:
# ./perf kvm stat report --event=ioport


Analyze events for all VCPUs:

  IO Port AccessSamples  Samples% Time% Avg time

  0x5658:PIN   335755.22%92.13%162.31us ( +-   0.87% )
 0xc090:POUT   122120.09% 2.10% 10.18us ( +-   4.97% )
0x60:PIN74812.30% 3.18% 25.17us ( +-   5.01% )
0x64:PIN74812.30% 2.57% 20.35us ( +-  11.81% )
 0xc050:POUT  5 0.08% 0.01%  8.79us ( +-  12.88% )

Total Samples:6079, Total events handled time:591405.43us.

And, --vcpu is used to track the specified vcpu and --key is used to sort the
result:
# ./perf kvm stat report --event=ioport --vcpu=0 --key=time


Analyze events for VCPU 0:

  IO Port AccessSamples  Samples% Time% Avg time

  0x5658:PIN14594.77%99.67%133.00us ( +-   2.96% )
 0xc090:POUT  8 5.23% 0.33%  7.99us ( +-  16.85% )

Total Samples:153, Total events handled time:19348.87us.

Changelog:
- merge perf kvm-events into perf perf kvm stat as Ingo's suggestion
- track kvm events for the specified guest
- rename kvm_mmio_done to kvm_io_done
- fix compiling-error on i386


Dong Hao (3):
  KVM: x86: export svm/vmx exit code and vector code to userspace
  KVM: x86: tracemmio begin and complete
  KVM: perf kvm events analysis tool

 arch/x86/include/asm/kvm_host.h   |   36 +-
 arch/x86/include/asm/svm.h|  205 +---
 arch/x86/include/asm/vmx.h|  126 --
 arch/x86/kvm/trace.h  |   89 
 arch/x86/kvm/x86.c|   32 +-
 include/trace/events/kvm.h|   37 ++
 tools/perf/Documentation/perf-kvm.txt |   30 ++-
 tools/perf/MANIFEST   |3 +
 tools/perf/builtin-kvm.c  |  858 -
 tools/perf/util/header.c  |   55 ++-
 tools/perf/util/header.h  |1 +
 tools/perf/util/thread.h  |2 +
 12 files changed, 1234 insertions(+), 240 deletions(-)

-- 
1.7.2.5

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


[PATCH v6 2/3] KVM: x86: tracemmio begin and complete

2012-08-09 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

'perf kvm stat record/report' will use kvm_exit and kvm_mmio(read...) to
calculate mmio read emulated time for the old kernel, in order to trace
mmio read event more exactly, we add kvm_mmio_begin to trace the time when
mmio read begins, also, add kvm_io_done to trace the time when mmio/pio is
completed

[ Dong Hao haod...@linux.vnet.ibm.com: rebase it on current kvm tree ]
Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 arch/x86/kvm/x86.c |   32 
 include/trace/events/kvm.h |   37 +
 2 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 8ebf65c..164ed9d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3807,9 +3807,12 @@ mmio:
/*
 * Is this MMIO handled locally?
 */
+   trace_kvm_mmio_begin(vcpu-vcpu_id, write, gpa);
handled = ops-read_write_mmio(vcpu, gpa, bytes, val);
-   if (handled == bytes)
+   if (handled == bytes) {
+   trace_kvm_io_done(vcpu-vcpu_id);
return X86EMUL_CONTINUE;
+   }
 
gpa += handled;
bytes -= handled;
@@ -4002,6 +4005,7 @@ static int emulator_pio_in_out(struct kvm_vcpu *vcpu, int 
size,
vcpu-arch.pio.size = size;
 
if (!kernel_pio(vcpu, vcpu-arch.pio_data)) {
+   trace_kvm_io_done(vcpu-vcpu_id);
vcpu-arch.pio.count = 0;
return 1;
}
@@ -4602,9 +4606,7 @@ restart:
inject_emulated_exception(vcpu);
r = EMULATE_DONE;
} else if (vcpu-arch.pio.count) {
-   if (!vcpu-arch.pio.in)
-   vcpu-arch.pio.count = 0;
-   else
+   if (vcpu-arch.pio.in)
writeback = false;
r = EMULATE_DO_MMIO;
} else if (vcpu-mmio_needed) {
@@ -4635,8 +4637,6 @@ int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, 
unsigned short port)
unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX);
int ret = emulator_pio_out_emulated(vcpu-arch.emulate_ctxt,
size, port, val, 1);
-   /* do not return to emulator after return from userspace */
-   vcpu-arch.pio.count = 0;
return ret;
 }
 EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
@@ -5487,11 +5487,16 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
 {
struct kvm_run *run = vcpu-run;
struct kvm_mmio_fragment *frag;
-   int r;
+   int r = 1;
 
if (!(vcpu-arch.pio.count || vcpu-mmio_needed))
return 1;
 
+   if (vcpu-arch.pio.count  !vcpu-arch.pio.in) {
+   vcpu-arch.pio.count = 0;
+   goto exit;
+   }
+
if (vcpu-mmio_needed) {
/* Complete previous fragment */
frag = vcpu-mmio_fragments[vcpu-mmio_cur_fragment++];
@@ -5499,8 +5504,10 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
memcpy(frag-data, run-mmio.data, frag-len);
if (vcpu-mmio_cur_fragment == vcpu-mmio_nr_fragments) {
vcpu-mmio_needed = 0;
+
if (vcpu-mmio_is_write)
-   return 1;
+   goto exit;
+
vcpu-mmio_read_completed = 1;
goto done;
}
@@ -5517,11 +5524,12 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
}
 done:
vcpu-srcu_idx = srcu_read_lock(vcpu-kvm-srcu);
-   r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
+   r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE) == EMULATE_DONE;
srcu_read_unlock(vcpu-kvm-srcu, vcpu-srcu_idx);
-   if (r != EMULATE_DONE)
-   return 0;
-   return 1;
+
+exit:
+   trace_kvm_io_done(vcpu-vcpu_id);
+   return r;
 }
 
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index 7ef9e75..5be5ad3 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h
@@ -177,6 +177,43 @@ TRACE_EVENT(kvm_mmio,
  __entry-len, __entry-gpa, __entry-val)
 );
 
+TRACE_EVENT(kvm_mmio_begin,
+   TP_PROTO(unsigned int vcpu_id, bool rw, u64 gpa),
+   TP_ARGS(vcpu_id, rw, gpa),
+
+   TP_STRUCT__entry(
+   __field(unsigned int, vcpu_id)
+   __field(int, type)
+   __field(u64, gpa)
+   ),
+
+   TP_fast_assign(
+   __entry-vcpu_id = vcpu_id;
+   __entry-type = rw ? KVM_TRACE_MMIO_WRITE :
+   KVM_TRACE_MMIO_READ;
+   __entry-gpa = gpa;
+   ),
+
+   TP_printk(vcpu %u mmio %s gpa 0x%llx, __entry-vcpu_id,
+   __print_symbolic

[PATCH v6 1/3] KVM: x86: export svm/vmx exit code and vector code to userspace

2012-08-09 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

They will be needed by 'perf kvm stat'

[ Dong Hao haod...@linux.vnet.ibm.com: rebase it on current kvm/tip tree]
Signed-off-by: Xiao Guangrongxiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 arch/x86/include/asm/kvm_host.h |   36 ---
 arch/x86/include/asm/svm.h  |  205 +--
 arch/x86/include/asm/vmx.h  |  126 
 arch/x86/kvm/trace.h|   89 -
 4 files changed, 234 insertions(+), 222 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 1309e69..df23d75 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -11,6 +11,24 @@
 #ifndef _ASM_X86_KVM_HOST_H
 #define _ASM_X86_KVM_HOST_H
 
+#define DE_VECTOR 0
+#define DB_VECTOR 1
+#define BP_VECTOR 3
+#define OF_VECTOR 4
+#define BR_VECTOR 5
+#define UD_VECTOR 6
+#define NM_VECTOR 7
+#define DF_VECTOR 8
+#define TS_VECTOR 10
+#define NP_VECTOR 11
+#define SS_VECTOR 12
+#define GP_VECTOR 13
+#define PF_VECTOR 14
+#define MF_VECTOR 16
+#define MC_VECTOR 18
+
+#ifdef __KERNEL__
+
 #include linux/types.h
 #include linux/mm.h
 #include linux/mmu_notifier.h
@@ -75,22 +93,6 @@
 #define KVM_HPAGE_MASK(x)  (~(KVM_HPAGE_SIZE(x) - 1))
 #define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
 
-#define DE_VECTOR 0
-#define DB_VECTOR 1
-#define BP_VECTOR 3
-#define OF_VECTOR 4
-#define BR_VECTOR 5
-#define UD_VECTOR 6
-#define NM_VECTOR 7
-#define DF_VECTOR 8
-#define TS_VECTOR 10
-#define NP_VECTOR 11
-#define SS_VECTOR 12
-#define GP_VECTOR 13
-#define PF_VECTOR 14
-#define MF_VECTOR 16
-#define MC_VECTOR 18
-
 #define SELECTOR_TI_MASK (1  2)
 #define SELECTOR_RPL_MASK 0x03
 
@@ -995,4 +997,6 @@ int kvm_pmu_read_pmc(struct kvm_vcpu *vcpu, unsigned pmc, 
u64 *data);
 void kvm_handle_pmu_event(struct kvm_vcpu *vcpu);
 void kvm_deliver_pmi(struct kvm_vcpu *vcpu);
 
+#endif
+
 #endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index f2b83bc..cdf5674 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -1,6 +1,135 @@
 #ifndef __SVM_H
 #define __SVM_H
 
+#define SVM_EXIT_READ_CR0  0x000
+#define SVM_EXIT_READ_CR3  0x003
+#define SVM_EXIT_READ_CR4  0x004
+#define SVM_EXIT_READ_CR8  0x008
+#define SVM_EXIT_WRITE_CR0 0x010
+#define SVM_EXIT_WRITE_CR3 0x013
+#define SVM_EXIT_WRITE_CR4 0x014
+#define SVM_EXIT_WRITE_CR8 0x018
+#define SVM_EXIT_READ_DR0  0x020
+#define SVM_EXIT_READ_DR1  0x021
+#define SVM_EXIT_READ_DR2  0x022
+#define SVM_EXIT_READ_DR3  0x023
+#define SVM_EXIT_READ_DR4  0x024
+#define SVM_EXIT_READ_DR5  0x025
+#define SVM_EXIT_READ_DR6  0x026
+#define SVM_EXIT_READ_DR7  0x027
+#define SVM_EXIT_WRITE_DR0 0x030
+#define SVM_EXIT_WRITE_DR1 0x031
+#define SVM_EXIT_WRITE_DR2 0x032
+#define SVM_EXIT_WRITE_DR3 0x033
+#define SVM_EXIT_WRITE_DR4 0x034
+#define SVM_EXIT_WRITE_DR5 0x035
+#define SVM_EXIT_WRITE_DR6 0x036
+#define SVM_EXIT_WRITE_DR7 0x037
+#define SVM_EXIT_EXCP_BASE 0x040
+#define SVM_EXIT_INTR  0x060
+#define SVM_EXIT_NMI   0x061
+#define SVM_EXIT_SMI   0x062
+#define SVM_EXIT_INIT  0x063
+#define SVM_EXIT_VINTR 0x064
+#define SVM_EXIT_CR0_SEL_WRITE 0x065
+#define SVM_EXIT_IDTR_READ 0x066
+#define SVM_EXIT_GDTR_READ 0x067
+#define SVM_EXIT_LDTR_READ 0x068
+#define SVM_EXIT_TR_READ   0x069
+#define SVM_EXIT_IDTR_WRITE0x06a
+#define SVM_EXIT_GDTR_WRITE0x06b
+#define SVM_EXIT_LDTR_WRITE0x06c
+#define SVM_EXIT_TR_WRITE  0x06d
+#define SVM_EXIT_RDTSC 0x06e
+#define SVM_EXIT_RDPMC 0x06f
+#define SVM_EXIT_PUSHF 0x070
+#define SVM_EXIT_POPF  0x071
+#define SVM_EXIT_CPUID 0x072
+#define SVM_EXIT_RSM   0x073
+#define SVM_EXIT_IRET  0x074
+#define SVM_EXIT_SWINT 0x075
+#define SVM_EXIT_INVD  0x076
+#define SVM_EXIT_PAUSE 0x077
+#define SVM_EXIT_HLT   0x078
+#define SVM_EXIT_INVLPG0x079
+#define SVM_EXIT_INVLPGA   0x07a
+#define SVM_EXIT_IOIO  0x07b
+#define SVM_EXIT_MSR   0x07c
+#define SVM_EXIT_TASK_SWITCH   0x07d
+#define SVM_EXIT_FERR_FREEZE   0x07e
+#define SVM_EXIT_SHUTDOWN  0x07f
+#define SVM_EXIT_VMRUN 0x080
+#define SVM_EXIT_VMMCALL   0x081
+#define SVM_EXIT_VMLOAD0x082
+#define SVM_EXIT_VMSAVE0x083
+#define SVM_EXIT_STGI  0x084
+#define SVM_EXIT_CLGI  0x085
+#define SVM_EXIT_SKINIT0x086
+#define SVM_EXIT_RDTSCP0x087
+#define SVM_EXIT_ICEBP 0x088
+#define SVM_EXIT_WBINVD0x089
+#define SVM_EXIT_MONITOR   0x08a
+#define SVM_EXIT_MWAIT 0x08b
+#define SVM_EXIT_MWAIT_COND0x08c
+#define SVM_EXIT_XSETBV0x08d
+#define SVM_EXIT_NPF

[PATCH v6 3/3] KVM: perf kvm events analysis tool

2012-08-09 Thread Dong Hao
From: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com

Add 'perf kvm stat' support to analyze kvm vmexit/mmio/ioport smartly.

Usage:
- kvm stat
  run a command and gather performance counter statistics, it is the alias of
  perf stat

- trace kvm events:
  perf kvm stat record, or, if other tracepoints are interesting as well, we
  can append the events like this:
  perf kvm stat record -e timer:*
  If many guests are running, we can track the specified guest by using -p or
  --pid

- show the result:
  perf kvm stat report

The output example is following:
# pgrep qemu-kvm
27841
27888
27936

total 3 guests are running on the host

Then, track the guest whose pid is 27936:
# ./perf kvm stat record -p 27936
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.177 MB perf.data.guest (~7742 samples) ]

See the vmexit events:
# ./perf kvm stat report --event=vmexit


Analyze events for all VCPUs:

 VM-EXITSamples  Samples% Time% Avg time

 APIC_ACCESS23780.34% 0.01% 20.86us ( +-   8.03% )
 HLT 4515.25%99.98% 790874.75us ( +-  16.93% )
  EXTERNAL_INTERRUPT 11 3.73% 0.00% 47.70us ( +-  17.45% )
   EXCEPTION_NMI  1 0.34% 0.00%  5.11us ( +-   -nan% )
   CR_ACCESS  1 0.34% 0.00%  6.33us ( +-   -nan% )

Total Samples:295, Total events handled time:35594844.34us.

See the mmio events:
# ./perf kvm stat report --event=mmio


Analyze events for all VCPUs:

 MMIO AccessSamples  Samples% Time% Avg time

0xfee00380:W15182.07%76.19%  7.72us ( +-  11.96% )
0xfee00300:W 11 5.98%18.86% 26.23us ( +-  27.33% )
0xfee00300:R 11 5.98% 2.16%  3.00us ( +-   9.17% )
0xfee00310:W 11 5.98% 2.79%  3.88us ( +-   9.15% )

Total Samples:184, Total events handled time:1529.42us.

See the ioport event:
# ./perf kvm stat report --event=ioport


Analyze events for all VCPUs:

  IO Port AccessSamples  Samples% Time% Avg time

  0x5658:PIN   335755.22%92.13%162.31us ( +-   0.87% )
 0xc090:POUT   122120.09% 2.10% 10.18us ( +-   4.97% )
0x60:PIN74812.30% 3.18% 25.17us ( +-   5.01% )
0x64:PIN74812.30% 2.57% 20.35us ( +-  11.81% )
 0xc050:POUT  5 0.08% 0.01%  8.79us ( +-  12.88% )

Total Samples:6079, Total events handled time:591405.43us.

And, --vcpu is used to track the specified vcpu and --key is used to sort the
result:
# ./perf kvm stat report --event=ioport --vcpu=0 --key=time


Analyze events for VCPU 0:

  IO Port AccessSamples  Samples% Time% Avg time

  0x5658:PIN14594.77%99.67%133.00us ( +-   2.96% )
 0xc090:POUT  8 5.23% 0.33%  7.99us ( +-  16.85% )

Total Samples:153, Total events handled time:19348.87us.


[ Dong Hao haod...@linux.vnet.ibm.com:
 - rebase it on current tip tree
 - fix the compiling-error on i386
]
Signed-off-by: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com
---
 tools/perf/Documentation/perf-kvm.txt |   30 ++-
 tools/perf/MANIFEST   |3 +
 tools/perf/builtin-kvm.c  |  858 -
 tools/perf/util/header.c  |   55 ++-
 tools/perf/util/header.h  |1 +
 tools/perf/util/thread.h  |2 +
 6 files changed, 943 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/perf-kvm.txt 
b/tools/perf/Documentation/perf-kvm.txt
index dd84cb2..d52feef 100644
--- a/tools/perf/Documentation/perf-kvm.txt
+++ b/tools/perf/Documentation/perf-kvm.txt
@@ -12,7 +12,7 @@ SYNOPSIS
[--guestkallsyms=path --guestmodules=path | --guestvmlinux=path]]
{top|record|report|diff|buildid-list}
 'perf kvm' [--host] [--guest] [--guestkallsyms=path --guestmodules=path
-   | --guestvmlinux=path] {top|record|report|diff|buildid-list}
+   | --guestvmlinux=path] {top|record|report|diff|buildid-list|stat}
 
 DESCRIPTION
 ---
@@ -38,6 +38,18 @@ There are a couple of variants of perf kvm:
   so that other tools can be used to fetch packages with matching symbol tables
   for use by perf report.
 
+  'perf kvm stat command' to run a command and gather performance counter
+   statistics.
+  Especially, perf 'kvm stat record/report' generates a statistical analysis
+  of KVM events. Currently, vmexit, mmio and ioport events are supported.
+'perf kvm stat record command' records kvm events and the events between
+start and end command.
+And this command produces a file which contains tracing results of kvm
+events.
+
+'perf kvm stat report' reports statistical data which includes events