On Mon, May 14, 2012 at 9:06 AM, Marc Zyngier <marc.zyngier at arm.com> wrote: > Exit statistics can be a very valuable information when looking > at KVM performance. > > Expose them through debugfs. > > Signed-off-by: Marc Zyngier <marc.zyngier at arm.com> > --- > ?arch/arm/include/asm/kvm_host.h | ? ?5 +++++ > ?arch/arm/kvm/arm.c ? ? ? ? ? ? ?| ? ?5 ++++- > ?arch/arm/kvm/emulate.c ? ? ? ? ?| ? ?1 + > ?arch/arm/kvm/guest.c ? ? ? ? ? ?| ? 13 +++++++++++++ > ?arch/arm/kvm/mmu.c ? ? ? ? ? ? ?| ? ?8 ++++++++ > ?5 files changed, 31 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h > index e6fd8ff..ffef12b 100644 > --- a/arch/arm/include/asm/kvm_host.h > +++ b/arch/arm/include/asm/kvm_host.h > @@ -118,6 +118,11 @@ struct kvm_vm_stat { > ?}; > > ?struct kvm_vcpu_stat { > + ? ? ? u32 exits; > + ? ? ? u32 mmio_exits; > + ? ? ? u32 kmmio_exits; > + ? ? ? u32 wfi_exits; > + ? ? ? u32 irq_exits; > ? ? ? ?u32 halt_wakeup; > ?}; > > diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c > index 7cd8190..86eca66 100644 > --- a/arch/arm/kvm/arm.c > +++ b/arch/arm/kvm/arm.c > @@ -435,8 +435,10 @@ static inline int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, > ?{ > ? ? ? ?unsigned long hsr_ec; > > - ? ? ? if (exception_index == ARM_EXCEPTION_IRQ) > + ? ? ? if (exception_index == ARM_EXCEPTION_IRQ) { > + ? ? ? ? ? ? ? vcpu->stat.irq_exits++; > ? ? ? ? ? ? ? ?return 0; > + ? ? ? } > > ? ? ? ?if (exception_index != ARM_EXCEPTION_HVC) { > ? ? ? ? ? ? ? ?kvm_pr_unimpl("Unsupported exception type: %d", > @@ -514,6 +516,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) > > ? ? ? ? ? ? ? ?kvm_vgic_sync_from_cpu(vcpu); > ? ? ? ? ? ? ? ?vcpu->mode = OUTSIDE_GUEST_MODE; > + ? ? ? ? ? ? ? vcpu->stat.exits++; > ? ? ? ? ? ? ? ?kvm_guest_exit(); > ? ? ? ? ? ? ? ?local_irq_enable(); > > diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c > index d810c30..3ceab47 100644 > --- a/arch/arm/kvm/emulate.c > +++ b/arch/arm/kvm/emulate.c > @@ -443,6 +443,7 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) > ?int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run) > ?{ > ? ? ? ?trace_kvm_wfi(vcpu->arch.regs.pc); > + ? ? ? vcpu->stat.wfi_exits++; > ? ? ? ?if (!vcpu->arch.irq_lines && !kvm_vgic_vcpu_pending_irq(vcpu)) > ? ? ? ? ? ? ? ?vcpu->arch.wait_for_interrupts = 1; > ? ? ? ?return 0; > diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c > index c0adab0..d2ad91a 100644 > --- a/arch/arm/kvm/guest.c > +++ b/arch/arm/kvm/guest.c > @@ -24,7 +24,20 @@ > ?#include <asm/kvm_asm.h> > ?#include <asm/kvm_emulate.h> > > +#define VM_STAT(x) { #x, offsetof(struct kvm, stat.x), KVM_STAT_VM } > +#define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU } > + > ?struct kvm_stats_debugfs_item debugfs_entries[] = { > + ? ? ? /* vcpu stats */ > + ? ? ? VCPU_STAT(exits), > + ? ? ? VCPU_STAT(mmio_exits), > + ? ? ? VCPU_STAT(kmmio_exits), > + ? ? ? VCPU_STAT(wfi_exits), > + ? ? ? VCPU_STAT(irq_exits), > + ? ? ? VCPU_STAT(halt_wakeup), > + > + ? ? ? /* vm stats */ > + ? ? ? VM_STAT(remote_tlb_flush), > ? ? ? ?{ NULL } > ?}; > > diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c > index 2d4fc68..04898d8 100644 > --- a/arch/arm/kvm/mmu.c > +++ b/arch/arm/kvm/mmu.c > @@ -604,6 +604,14 @@ static int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, > ? ? ? ? ? ? ? ?memcpy(run->mmio.data, vcpu_reg(vcpu, rd), len); > > ? ? ? ?run->exit_reason = vgic_handle_mmio(vcpu, run); > + ? ? ? switch (run->exit_reason) { > + ? ? ? case KVM_EXIT_MMIO: > + ? ? ? ? ? ? ? vcpu->stat.mmio_exits++; > + ? ? ? ? ? ? ? break; > + ? ? ? case KVM_EXIT_UNKNOWN: > + ? ? ? ? ? ? ? vcpu->stat.kmmio_exits++; > + ? ? ? ? ? ? ? break; > + ? ? ? } > > ? ? ? ?/* > ? ? ? ? * The MMIO instruction is emulated and should not be re-executed > -- > 1.7.7.1 > nice. Thanks, -Christoffer