From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christian Ehrhardt Date: Tue, 11 Nov 2008 14:55:12 +0000 Subject: Re: [PATCH] kvm: powerpc: add exit timing statistics v3 Message-Id: <49199CD0.1030202@linux.vnet.ibm.com> List-Id: References: In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable To: kvm-ppc@vger.kernel.org And btw - the wiki page is updated with new versions of the exittimings=20 using all of our new memory management improvements. The page now also has some extended descriptions about the simple=20 workloads used, holds the current version of the postprocessing script etc. Christian Ehrhardt wrote: > From: Christian Ehrhardt > > *update to v3* > - ensure build time optimization when calling exit accouting functions us= ing > build time bug / constant check > - migrate most of the exit timing code from powerpc.c and > kvm_timing_stats.h to a separate exittiming.c file > - renamed a lot of constants used to better fit generic/core specific code > - added an accidenially removed optimization comment > - use pid of userspace process instead of an own atomic count to identify= a vm > - changed loop labels in tul/tbu loops (booke_interrupt.S) to anonymous 1= /1b > - removed the indirection of additional EMULATE_*_DONE types. Instead now > the exit timing supports "accounting" an exit which consists of set typ= e and > increase kvm_stat counters. But also provides both sub-tasks as separate > functions. Using that emulation now sets a default EMUL_INST type that = can > be overwritten by detailed subcategories (set_exit_type). Accouting for > kvm_stat is done with account_exit_stat for all emulinst exits together= on > top level (as it was before). > > *update to v2* > The update fixes accounting for sets to MSR[WE] which should not be accou= tned > as instruction emulation. While adding that and analyzing the data it bec= ame > obvious that several types of emulations hould be accounted separately. > I'm not yet really happy with adding all these EMULATE_*_DONE types but I= had > no better idea to not break flood the code with account calls and split > account/set_type. The issue is that emulation is also called e.g. for som= e mmio > paths and therefore the accouting should not be called inside emulation, = but on > the returning path that can now evaluate the different kind of emulations= done. > This is not yet finished, and posted as RFC only. > > Other existing kvm statistics are either just counters (kvm_stat) reporte= d for > kvm generally or trace based aproaches like kvm_trace. > For kvm on powerpc we had the need to track the timings of the different = exit > types. While this could be achieved parsing data created with a kvm_trace > extension this adds too muhc overhead (at least on embedded powerpc) slow= ing > down the workloads we wanted to measure. > > Therefore this patch adds a in kernel exit timing statistic to the powerp= c kvm > code. These statistic is available per vm&vcpu under the kvm debugfs dire= ctory. > As this statistic is low, but still some overhead it can be enabled via a > .config entry and should be off by default. > > Since this patch touched all powerpc kvm_stat code anyway this code is now > merged and simpliefied together with the exit timing statistic code (still > working with exit timing disabled in .config). > > * another update in v3* > An updated awk script printing the data in a more narrow layout can be fo= und > on our wiki pages about the exit timing topic. > (http://kvm.qumranet.com/kvmwiki/PowerPC_Exittimings) > Here is a sample output how the results look like. > processing file timing_boot.log > sum of time 8309940 > type count min max sum avg = stddev % > MMIO: 9402 44 1997 1697610 180.5584 = 155.768 20.43 > DCR: 680 41 99 32096 47.2000 = 7.008 0.39 > SIGNAL: 1 98 98 98 98.0000 = 0.000 0.00 > ITLBREAL: 926 8 14 7810 8.4341 = 0.658 0.09 > ITLBVIRT: 3595 18 202 76185 21.1919 = 4.954 0.92 > DTLBREAL: 950 8 16 8891 9.3589 = 1.427 0.11 > DTLBVIRT: 6695 18 282 156727 23.4096 = 13.781 1.89 > SYSCALL: 1801 6 59 11372 6.3143 = 2.575 0.14 > ISI: 116 6 8 764 6.5862 = 0.588 0.01 > DSI: 43 6 7 292 6.7907 = 0.407 0.00 > EMULINST: 65247 7 96 484081 7.4192 = 1.818 5.83 > EMUL_WAIT: 801 659 9200 3721789 4646.4282 = 1687.218 44.79 > EMUL_CORE: 66806 7 86 540053 8.0839 = 1.895 6.50 > EMUL_MTSPR: 13415 8 62 111358 8.3010 = 2.583 1.34 > EMUL_MFSPR: 7635 8 61 62772 8.2216 = 1.921 0.76 > EMUL_MTMSR: 5678 8 59 45704 8.0493 = 1.434 0.55 > EMUL_MFMSR: 32853 7 67 267603 8.1455 = 1.875 3.22 > EMUL_TLBSX: 354 9 60 3745 10.5791 = 3.919 0.05 > EMUL_TLBWE: 6403 9 112 99522 15.5430 = 7.668 1.20 > EMUL_RFI: 9515 7 57 71420 7.5060 = 2.108 0.86 > DEC: 290 49 161 15786 54.4345 = 9.708 0.19 > EXTINT: 7 74 75 522 74.5714 = 0.495 0.01 > TIMEINGUEST: 233213 0 3954 893740 3.8323 = 65.837 10.76 > > Signed-off-by: Christian Ehrhardt > --- > > [diffstat] > include/asm/kvm_host.h | 59 ++++++++++++++++++++++++ > include/asm/kvm_ppc.h | 8 +-- > include/asm/kvm_timing_stats.h | 100 ++++++++++++++++++++++++++++++++++= +++++++ > kernel/asm-offsets.c | 11 ++++ > kvm/44x_emulate.c | 10 +++- > kvm/44x_tlb.c | 3 + > kvm/Kconfig | 9 +++ > kvm/Makefile | 1 > kvm/booke.c | 36 +++++++++----- > kvm/booke.h | 5 +- > kvm/booke_interrupts.S | 24 +++++++++ > kvm/emulate.c | 4 + > kvm/powerpc.c | 11 +++- > 13 files changed, 259 insertions(+), 22 deletions(-) > > diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/a= sm/kvm_host.h > --- a/arch/powerpc/include/asm/kvm_host.h > +++ b/arch/powerpc/include/asm/kvm_host.h > @@ -71,7 +71,53 @@ struct kvmppc_44x_tlbe { > u32 word2; > }; > > +enum kvm_exit_types { > + MMIO_EXITS, > + DCR_EXITS, > + SIGNAL_EXITS, > + ITLB_REAL_MISS_EXITS, > + ITLB_VIRT_MISS_EXITS, > + DTLB_REAL_MISS_EXITS, > + DTLB_VIRT_MISS_EXITS, > + SYSCALL_EXITS, > + ISI_EXITS, > + DSI_EXITS, > + EMULATED_INST_EXITS, > + EMULATED_MTMSRWE_EXITS, > + EMULATED_COREOP_EXITS, > + EMULATED_MTSPR_EXITS, > + EMULATED_MFSPR_EXITS, > + EMULATED_MTMSR_EXITS, > + EMULATED_MFMSR_EXITS, > + EMULATED_TLBSX_EXITS, > + EMULATED_TLBWE_EXITS, > + EMULATED_RFI_EXITS, > + DEC_EXITS, > + EXT_INTR_EXITS, > + HALT_WAKEUP, > + USR_PR_INST, > + FP_UNAVAIL, > + DEBUG_EXITS, > + TIMEINGUEST, > + __NUMBER_OF_KVM_EXIT_TYPES > +}; > + > +#ifdef CONFIG_KVM_BOOKE_EXIT_TIMING > +/* allow access to big endian 32bit upper/lower parts and 64bit var */ > +struct exit_timing { > + union { > + u64 tv64; > + struct { > + u32 tbu, tbl; > + } tv32; > + }; > +}; > +#endif > + > struct kvm_arch { > +#ifdef CONFIG_KVM_BOOKE_EXIT_TIMING > + unsigned int vm_id; > +#endif > }; > > struct kvm_vcpu_arch { > @@ -130,6 +176,19 @@ struct kvm_vcpu_arch { > u32 dbcr0; > u32 dbcr1; > > +#ifdef CONFIG_KVM_BOOKE_EXIT_TIMING > + struct exit_timing timing_exit; > + struct exit_timing timing_last_enter; > + u32 last_exit_type; > + u32 timing_count_type[__NUMBER_OF_KVM_EXIT_TYPES]; > + u64 timing_sum_duration[__NUMBER_OF_KVM_EXIT_TYPES]; > + u64 timing_sum_quad_duration[__NUMBER_OF_KVM_EXIT_TYPES]; > + u64 timing_min_duration[__NUMBER_OF_KVM_EXIT_TYPES]; > + u64 timing_max_duration[__NUMBER_OF_KVM_EXIT_TYPES]; > + u64 timing_last_exit; > + struct dentry *debugfs_exit_timing; > +#endif > + > u32 last_inst; > ulong fault_dear; > ulong fault_esr; > diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/as= m/kvm_ppc.h > --- a/arch/powerpc/include/asm/kvm_ppc.h > +++ b/arch/powerpc/include/asm/kvm_ppc.h > @@ -30,10 +30,10 @@ > #include > > enum emulation_result { > - EMULATE_DONE, /* no further processing */ > - EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */ > - EMULATE_DO_DCR, /* kvm_run filled with DCR request */ > - EMULATE_FAIL, /* can't emulate this instruction */ > + EMULATE_DONE, /* no further processing */ > + EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */ > + EMULATE_DO_DCR, /* kvm_run filled with DCR request */ > + EMULATE_FAIL, /* can't emulate this instruction */ > }; > > extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *v= cpu); > diff --git a/arch/powerpc/include/asm/kvm_timing_stats.h b/arch/powerpc/i= nclude/asm/kvm_timing_stats.h > new file mode 100644 > --- /dev/null > +++ b/arch/powerpc/include/asm/kvm_timing_stats.h > @@ -0,0 +1,100 @@ > +/* > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License, version 2, as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, = USA. > + * > + * Copyright IBM Corp. 2008 > + * > + * Authors: Christian Ehrhardt > + */ > + > +#ifndef __POWERPC_KVM_EXITTIMING_H__ > +#define __POWERPC_KVM_EXITTIMING_H__ > + > +#include > +#include > + > +#ifdef CONFIG_KVM_BOOKE_EXIT_TIMING > +void init_timing_stats(struct kvm_vcpu *vcpu); > +void update_timing_stats(struct kvm_vcpu *vcpu); > +void kvmppc_create_vcpu_debugfs(struct kvm_vcpu *vcpu, unsigned int id); > +void kvmppc_remove_vcpu_debugfs(struct kvm_vcpu *vcpu); > + > +static inline void set_exit_type(struct kvm_vcpu *vcpu, int type) > +{ > + vcpu->arch.last_exit_type =3D type; > +} > + > +#else > +#define init_timing_stats(x) do { } while (0) > +#define update_timing_stats(x) do { } while (0) > +#define kvmppc_create_vcpu_debugfs(x, y) do { } while (0) > +#define kvmppc_remove_vcpu_debugfs(x) do { } while (0) > +#define set_exit_type(x, y) do { } while (0) > +#endif /* CONFIG_KVM_BOOKE_EXIT_TIMING */ > + > +/* account the exit in kvm_stats */ > +static inline void account_exit_stat(struct kvm_vcpu *vcpu, int type) > +{ > + /* type has to be known at build time for optimization */ > + BUILD_BUG_ON(__builtin_constant_p(type)); > + switch (type) { > + case EXT_INTR_EXITS: > + vcpu->stat.ext_intr_exits++; > + break; > + case DEC_EXITS: > + vcpu->stat.dec_exits++; > + break; > + case EMULATED_INST_EXITS: > + vcpu->stat.emulated_inst_exits++; > + break; > + case DCR_EXITS: > + vcpu->stat.dcr_exits++; > + break; > + case DSI_EXITS: > + vcpu->stat.dsi_exits++; > + break; > + case ISI_EXITS: > + vcpu->stat.isi_exits++; > + break; > + case SYSCALL_EXITS: > + vcpu->stat.syscall_exits++; > + break; > + case DTLB_REAL_MISS_EXITS: > + vcpu->stat.dtlb_real_miss_exits++; > + break; > + case DTLB_VIRT_MISS_EXITS: > + vcpu->stat.dtlb_virt_miss_exits++; > + break; > + case MMIO_EXITS: > + vcpu->stat.mmio_exits++; > + break; > + case ITLB_REAL_MISS_EXITS: > + vcpu->stat.itlb_real_miss_exits++; > + break; > + case ITLB_VIRT_MISS_EXITS: > + vcpu->stat.itlb_virt_miss_exits++; > + break; > + case SIGNAL_EXITS: > + vcpu->stat.signal_exits++; > + break; > + } > +} > + > +/* wrapper to set exit time and account for it in kvm_stats */ > +static inline void account_exit(struct kvm_vcpu *vcpu, int type) > +{ > + set_exit_type(vcpu, type); > + account_exit_stat(vcpu, type); > +} > + > +#endif /* __POWERPC_KVM_EXITTIMING_H__ */ > diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-= offsets.c > --- a/arch/powerpc/kernel/asm-offsets.c > +++ b/arch/powerpc/kernel/asm-offsets.c > @@ -381,5 +381,16 @@ int main(void) > DEFINE(PTE_SHIFT, PTE_SHIFT); > #endif > > +#ifdef CONFIG_KVM_BOOKE_EXIT_TIMING > + DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu, > + arch.timing_exit.tv32.tbu)); > + DEFINE(VCPU_TIMING_EXIT_TBL, offsetof(struct kvm_vcpu, > + arch.timing_exit.tv32.tbl)); > + DEFINE(VCPU_TIMING_LAST_ENTER_TBU, offsetof(struct kvm_vcpu, > + arch.timing_last_enter.tv32.tbu)); > + DEFINE(VCPU_TIMING_LAST_ENTER_TBL, offsetof(struct kvm_vcpu, > + arch.timing_last_enter.tv32.tbl)); > +#endif > + > return 0; > } > diff --git a/arch/powerpc/kvm/44x_emulate.c b/arch/powerpc/kvm/44x_emulat= e.c > --- a/arch/powerpc/kvm/44x_emulate.c > +++ b/arch/powerpc/kvm/44x_emulate.c > @@ -22,6 +22,7 @@ > #include > #include > #include > +#include > > #include "booke.h" > #include "44x_tlb.h" > @@ -57,12 +58,13 @@ int kvmppc_core_emulate_op(struct kvm_ru > int rt; > int ws; > > + set_exit_type(vcpu, EMULATED_COREOP_EXITS); > switch (get_op(inst)) { > - > case OP_RFI: > switch (get_xop(inst)) { > case XOP_RFI: > kvmppc_emul_rfi(vcpu); > + set_exit_type(vcpu, EMULATED_RFI_EXITS); > *advance =3D 0; > break; > > @@ -78,10 +80,12 @@ int kvmppc_core_emulate_op(struct kvm_ru > case XOP_MFMSR: > rt =3D get_rt(inst); > vcpu->arch.gpr[rt] =3D vcpu->arch.msr; > + set_exit_type(vcpu, EMULATED_MFMSR_EXITS); > break; > > case XOP_MTMSR: > rs =3D get_rs(inst); > + set_exit_type(vcpu, EMULATED_MTMSR_EXITS); > kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]); > break; > > @@ -127,6 +131,7 @@ int kvmppc_core_emulate_op(struct kvm_ru > run->dcr.is_write =3D 0; > vcpu->arch.io_gpr =3D rt; > vcpu->arch.dcr_needed =3D 1; > + account_exit(vcpu, DCR_EXITS); > emulated =3D EMULATE_DO_DCR; > } > > @@ -146,6 +151,7 @@ int kvmppc_core_emulate_op(struct kvm_ru > run->dcr.data =3D vcpu->arch.gpr[rs]; > run->dcr.is_write =3D 1; > vcpu->arch.dcr_needed =3D 1; > + account_exit(vcpu, DCR_EXITS); > emulated =3D EMULATE_DO_DCR; > } > > @@ -276,6 +282,7 @@ int kvmppc_core_emulate_mtspr(struct kvm > return EMULATE_FAIL; > } > > + set_exit_type(vcpu, EMULATED_MTSPR_EXITS); > return EMULATE_DONE; > } > > @@ -357,6 +364,7 @@ int kvmppc_core_emulate_mfspr(struct kvm > return EMULATE_FAIL; > } > > + set_exit_type(vcpu, EMULATED_MFSPR_EXITS); > return EMULATE_DONE; > } > > diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c > --- a/arch/powerpc/kvm/44x_tlb.c > +++ b/arch/powerpc/kvm/44x_tlb.c > @@ -27,6 +27,7 @@ > #include > #include > #include > +#include > > #include "44x_tlb.h" > > @@ -457,6 +458,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcp > KVMTRACE_5D(GTLB_WRITE, vcpu, gtlb_index, tlbe->tid, tlbe->word0, > tlbe->word1, tlbe->word2, handler); > > + set_exit_type(vcpu, EMULATED_TLBWE_EXITS); > return EMULATE_DONE; > } > > @@ -480,5 +482,6 @@ int kvmppc_44x_emul_tlbsx(struct kvm_vcp > } > vcpu->arch.gpr[rt] =3D gtlb_index; > > + set_exit_type(vcpu, EMULATED_TLBSX_EXITS); > return EMULATE_DONE; > } > diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig > --- a/arch/powerpc/kvm/Kconfig > +++ b/arch/powerpc/kvm/Kconfig > @@ -32,6 +32,15 @@ config KVM_440 > > If unsure, say N. > > +config KVM_BOOKE_EXIT_TIMING > + bool "Trace detailed exit Timing" > + depends on KVM && 44x > + ---help--- > + Inserts code to trace timestamps for every exit/enter cycle. A per vc= pu > + report is available in debugfs kvm/VM_###/VPCU_###_exit_timing. > + The overhead is relatively small, however it is not recommended for > + production environments. > + > config KVM_TRACE > bool "KVM trace support" > depends on KVM && MARKERS && SYSFS > diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile > --- a/arch/powerpc/kvm/Makefile > +++ b/arch/powerpc/kvm/Makefile > @@ -9,6 +9,7 @@ common-objs-$(CONFIG_KVM_TRACE) +=3D $(ad > common-objs-$(CONFIG_KVM_TRACE) +=3D $(addprefix ../../../virt/kvm/, kv= m_trace.o) > > kvm-objs :=3D $(common-objs-y) powerpc.o emulate.o > +obj-$(CONFIG_KVM_BOOKE_EXIT_TIMING) +=3D exittiming.o > obj-$(CONFIG_KVM) +=3D kvm.o > > AFLAGS_booke_interrupts.o :=3D -I$(obj) > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c > --- a/arch/powerpc/kvm/booke.c > +++ b/arch/powerpc/kvm/booke.c > @@ -28,6 +28,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -185,6 +186,9 @@ int kvmppc_handle_exit(struct kvm_run *r > enum emulation_result er; > int r =3D RESUME_HOST; > > + /* update before a new last_exit_type is rewritten */ > + update_timing_stats(vcpu); > + > local_irq_enable(); > > run->exit_reason =3D KVM_EXIT_UNKNOWN; > @@ -198,7 +202,7 @@ int kvmppc_handle_exit(struct kvm_run *r > break; > > case BOOKE_INTERRUPT_EXTERNAL: > - vcpu->stat.ext_intr_exits++; > + account_exit(vcpu, EXT_INTR_EXITS); > if (need_resched()) > cond_resched(); > r =3D RESUME_GUEST; > @@ -208,8 +212,7 @@ int kvmppc_handle_exit(struct kvm_run *r > /* Since we switched IVPR back to the host's value, the host > * handled this interrupt the moment we enabled interrupts. > * Now we just offer it a chance to reschedule the guest. */ > - > - vcpu->stat.dec_exits++; > + account_exit(vcpu, DEC_EXITS); > if (need_resched()) > cond_resched(); > r =3D RESUME_GUEST; > @@ -222,20 +225,21 @@ int kvmppc_handle_exit(struct kvm_run *r > vcpu->arch.esr =3D vcpu->arch.fault_esr; > kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM); > r =3D RESUME_GUEST; > + account_exit(vcpu, USR_PR_INST); > break; > } > > er =3D kvmppc_emulate_instruction(run, vcpu); > switch (er) { > case EMULATE_DONE: > + /* don't overwrite subtypes, just account kvm_stats */ > + account_exit_stat(vcpu, EMULATED_INST_EXITS); > /* Future optimization: only reload non-volatiles if > * they were actually modified by emulation. */ > - vcpu->stat.emulated_inst_exits++; > r =3D RESUME_GUEST_NV; > break; > case EMULATE_DO_DCR: > run->exit_reason =3D KVM_EXIT_DCR; > - vcpu->stat.dcr_exits++; > r =3D RESUME_HOST; > break; > case EMULATE_FAIL: > @@ -255,6 +259,7 @@ int kvmppc_handle_exit(struct kvm_run *r > > case BOOKE_INTERRUPT_FP_UNAVAIL: > kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_FP_UNAVAIL); > + account_exit(vcpu, FP_UNAVAIL); > r =3D RESUME_GUEST; > break; > > @@ -262,20 +267,20 @@ int kvmppc_handle_exit(struct kvm_run *r > vcpu->arch.dear =3D vcpu->arch.fault_dear; > vcpu->arch.esr =3D vcpu->arch.fault_esr; > kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); > - vcpu->stat.dsi_exits++; > + account_exit(vcpu, DSI_EXITS); > r =3D RESUME_GUEST; > break; > > case BOOKE_INTERRUPT_INST_STORAGE: > vcpu->arch.esr =3D vcpu->arch.fault_esr; > kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE); > - vcpu->stat.isi_exits++; > + account_exit(vcpu, ISI_EXITS); > r =3D RESUME_GUEST; > break; > > case BOOKE_INTERRUPT_SYSCALL: > kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SYSCALL); > - vcpu->stat.syscall_exits++; > + account_exit(vcpu, SYSCALL_EXITS); > r =3D RESUME_GUEST; > break; > > @@ -294,7 +299,7 @@ int kvmppc_handle_exit(struct kvm_run *r > kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); > vcpu->arch.dear =3D vcpu->arch.fault_dear; > vcpu->arch.esr =3D vcpu->arch.fault_esr; > - vcpu->stat.dtlb_real_miss_exits++; > + account_exit(vcpu, DTLB_REAL_MISS_EXITS); > r =3D RESUME_GUEST; > break; > } > @@ -312,13 +317,13 @@ int kvmppc_handle_exit(struct kvm_run *r > * invoking the guest. */ > kvmppc_mmu_map(vcpu, eaddr, vcpu->arch.paddr_accessed, gtlbe->tid, > gtlbe->word2, get_tlb_bytes(gtlbe), gtlb_index); > - vcpu->stat.dtlb_virt_miss_exits++; > + account_exit(vcpu, DTLB_VIRT_MISS_EXITS); > r =3D RESUME_GUEST; > } else { > /* Guest has mapped and accessed a page which is not > * actually RAM. */ > r =3D kvmppc_emulate_mmio(run, vcpu); > - vcpu->stat.mmio_exits++; > + account_exit(vcpu, MMIO_EXITS); > } > > break; > @@ -340,11 +345,11 @@ int kvmppc_handle_exit(struct kvm_run *r > if (gtlb_index < 0) { > /* The guest didn't have a mapping for it. */ > kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ITLB_MISS); > - vcpu->stat.itlb_real_miss_exits++; > + account_exit(vcpu, ITLB_REAL_MISS_EXITS); > break; > } > > - vcpu->stat.itlb_virt_miss_exits++; > + account_exit(vcpu, ITLB_VIRT_MISS_EXITS); > > gtlbe =3D &vcpu_44x->guest_tlb[gtlb_index]; > gpaddr =3D tlb_xlate(gtlbe, eaddr); > @@ -378,6 +383,7 @@ int kvmppc_handle_exit(struct kvm_run *r > mtspr(SPRN_DBSR, dbsr); > > run->exit_reason =3D KVM_EXIT_DEBUG; > + account_exit(vcpu, DEBUG_EXITS); > r =3D RESUME_HOST; > break; > } > @@ -398,7 +404,7 @@ int kvmppc_handle_exit(struct kvm_run *r > if (signal_pending(current)) { > run->exit_reason =3D KVM_EXIT_INTR; > r =3D (-EINTR << 2) | RESUME_HOST | (r & RESUME_FLAG_NV); > - vcpu->stat.signal_exits++; > + account_exit(vcpu, SIGNAL_EXITS); > } > } > > @@ -417,6 +423,8 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu=20 > /* Eye-catching number so we know if the guest takes an interrupt > * before it's programmed its own IVPR. */ > vcpu->arch.ivpr =3D 0x55550000; > + > + init_timing_stats(vcpu); > > return kvmppc_core_vcpu_setup(vcpu); > } > diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h > --- a/arch/powerpc/kvm/booke.h > +++ b/arch/powerpc/kvm/booke.h > @@ -22,6 +22,7 @@ > > #include > #include > +#include > > /* interrupt priortity ordering */ > #define BOOKE_IRQPRIO_DATA_STORAGE 0 > @@ -50,8 +51,10 @@ static inline void kvmppc_set_msr(struct > > vcpu->arch.msr =3D new_msr; > > - if (vcpu->arch.msr & MSR_WE) > + if (vcpu->arch.msr & MSR_WE) { > kvm_vcpu_block(vcpu); > + set_exit_type(vcpu, EMULATED_MTMSRWE_EXITS); > + }; > } > > #endif /* __KVM_BOOKE_H__ */ > diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke= _interrupts.S > --- a/arch/powerpc/kvm/booke_interrupts.S > +++ b/arch/powerpc/kvm/booke_interrupts.S > @@ -106,6 +106,18 @@ _GLOBAL(kvmppc_resume_host) > > li r6, 1 > slw r6, r6, r5 > + > +#ifdef CONFIG_KVM_BOOKE_EXIT_TIMING > + /* save exit time */ > +1: > + mfspr r7, SPRN_TBRU > + mfspr r8, SPRN_TBRL > + mfspr r9, SPRN_TBRU > + cmpw r9, r7 > + bne 1b > + stw r8, VCPU_TIMING_EXIT_TBL(r4) > + stw r9, VCPU_TIMING_EXIT_TBU(r4) > +#endif > > /* Save the faulting instruction and all GPRs for emulation. */ > andi. r7, r6, NEED_INST_MASK > @@ -375,6 +387,18 @@ lightweight_exit: > lwz r3, VCPU_SPRG7(r4) > mtspr SPRN_SPRG7, r3 > > +#ifdef CONFIG_KVM_BOOKE_EXIT_TIMING > + /* save enter time */ > +1: > + mfspr r6, SPRN_TBRU > + mfspr r7, SPRN_TBRL > + mfspr r8, SPRN_TBRU > + cmpw r8, r6 > + bne 1b > + stw r7, VCPU_TIMING_LAST_ENTER_TBL(r4) > + stw r8, VCPU_TIMING_LAST_ENTER_TBU(r4) > +#endif > + > /* Finish loading guest volatiles and jump to guest. */ > lwz r3, VCPU_CTR(r4) > mtctr r3 > diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c > --- a/arch/powerpc/kvm/emulate.c > +++ b/arch/powerpc/kvm/emulate.c > @@ -28,6 +28,7 @@ > #include > #include > #include > +#include > > void kvmppc_emulate_dec(struct kvm_vcpu *vcpu) > { > @@ -72,6 +73,9 @@ int kvmppc_emulate_instruction(struct kv > int sprn; > enum emulation_result emulated =3D EMULATE_DONE; > int advance =3D 1; > + > + /* this default type might be overwritten by subcategories */ > + set_exit_type(vcpu, EMULATED_INST_EXITS); > > switch (get_op(inst)) { > case 3: /* trap */ > diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c > --- a/arch/powerpc/kvm/powerpc.c > +++ b/arch/powerpc/kvm/powerpc.c > @@ -28,7 +28,10 @@ > #include > #include > #include > - > +#include > +#include > +#include > +#include > > gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) > { > @@ -170,11 +173,15 @@ void kvm_arch_flush_shadow(struct kvm *k > > struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) > { > - return kvmppc_core_vcpu_create(kvm, id); > + struct kvm_vcpu *vcpu; > + vcpu =3D kvmppc_core_vcpu_create(kvm, id); > + kvmppc_create_vcpu_debugfs(vcpu, id); > + return vcpu; > } > > void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) > { > + kvmppc_remove_vcpu_debugfs(vcpu); > kvmppc_core_vcpu_free(vcpu); > } > > -- > To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > =20 --=20 Gr=FCsse / regards,=20 Christian Ehrhardt IBM Linux Technology Center, Open Virtualization