[PATCH] fix compilation error of perf/core
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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