[Android-virt] [PATCH 15/15] ARM: KVM: Add exit statistics to debugfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux