History

kvm: add halt-polling cpu usage stats

Two new stats for exposing halt-polling cpu usage: halt_poll_success_ns halt_poll_fail_ns Thus sum of these 2 stats is the total cpu time spent polling. "success" means the VCPU polled until a virtual interrupt was delivered. "fail" means the VCPU had to schedule out (either because the maximum poll time was reached or it needed to yield the CPU). To avoid touching every arch's kvm_vcpu_stat struct, only update and export halt-polling cpu usage stats if we're on x86. Exporting cpu usage as a u64 and in nanoseconds means we will overflow at ~500 years, which seems reasonably large. Signed-off-by: David Matlack <dmatlack@google.com> Signed-off-by: Jon Cargille <jcargill@google.com> Reviewed-by: Jim Mattson <jmattson@google.com>

David Matlack committed 6 years ago

Commit cb953121 parent 93dff2f10 files · +33 −3Browse files

Unified · Split

10 files
  1. arch/arm64/include/asm/kvm_host.h +2 −0
  2. arch/arm64/kvm/guest.c +2 −0
  3. arch/mips/include/asm/kvm_host.h +2 −0
  4. arch/mips/kvm/mips.c +2 −0
  5. arch/powerpc/kvm/booke.c +2 −0
  6. arch/s390/include/asm/kvm_host.h +2 −0
  7. arch/s390/kvm/kvm-s390.c +2 −0
  8. arch/x86/include/asm/kvm_host.h +2 −0
  9. arch/x86/kvm/x86.c +2 −0
  10. virt/kvm/kvm_main.c +15 −3
arch/arm64/include/asm/kvm_host.h+2−0
@@ -415,6 +415,8 @@ struct kvm_vm_stat { · 414 unmodified lines
415415 struct kvm_vcpu_stat {
416416 u64 halt_successful_poll;
417417 u64 halt_attempted_poll;
418+ u64 halt_poll_success_ns;
419+ u64 halt_poll_fail_ns;
418420 u64 halt_poll_invalid;
419421 u64 halt_wakeup;
420422 u64 hvc_exit_stat;
arch/arm64/kvm/guest.c+2−0
@@ -40,6 +40,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { · 39 unmodified lines
4040 VCPU_STAT("mmio_exit_user", mmio_exit_user),
4141 VCPU_STAT("mmio_exit_kernel", mmio_exit_kernel),
4242 VCPU_STAT("exits", exits),
43+ VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),
44+ VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),
4345 { NULL }
4446 };
4547
arch/mips/include/asm/kvm_host.h+2−0
@@ -174,6 +174,8 @@ struct kvm_vcpu_stat { · 173 unmodified lines
174174 #endif
175175 u64 halt_successful_poll;
176176 u64 halt_attempted_poll;
177+ u64 halt_poll_success_ns;
178+ u64 halt_poll_fail_ns;
177179 u64 halt_poll_invalid;
178180 u64 halt_wakeup;
179181 };
arch/mips/kvm/mips.c+2−0
@@ -72,6 +72,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { · 71 unmodified lines
7272 VCPU_STAT("halt_attempted_poll", halt_attempted_poll),
7373 VCPU_STAT("halt_poll_invalid", halt_poll_invalid),
7474 VCPU_STAT("halt_wakeup", halt_wakeup),
75+ VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),
76+ VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),
7577 {NULL}
7678 };
7779
arch/powerpc/kvm/booke.c+2−0
@@ -54,6 +54,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { · 53 unmodified lines
5454 VCPU_STAT("halt_wakeup", halt_wakeup),
5555 VCPU_STAT("doorbell", dbell_exits),
5656 VCPU_STAT("guest doorbell", gdbell_exits),
57+ VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),
58+ VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),
5759 VM_STAT("remote_tlb_flush", remote_tlb_flush),
5860 { NULL }
5961 };
arch/s390/include/asm/kvm_host.h+2−0
@@ -375,6 +375,8 @@ struct kvm_vcpu_stat { · 374 unmodified lines
375375 u64 halt_poll_invalid;
376376 u64 halt_no_poll_steal;
377377 u64 halt_wakeup;
378+ u64 halt_poll_success_ns;
379+ u64 halt_poll_fail_ns;
378380 u64 instruction_lctl;
379381 u64 instruction_lctlg;
380382 u64 instruction_stctl;
arch/s390/kvm/kvm-s390.c+2−0
@@ -75,6 +75,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { · 74 unmodified lines
7575 VCPU_STAT("halt_poll_invalid", halt_poll_invalid),
7676 VCPU_STAT("halt_no_poll_steal", halt_no_poll_steal),
7777 VCPU_STAT("halt_wakeup", halt_wakeup),
78+ VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),
79+ VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),
7880 VCPU_STAT("instruction_lctlg", instruction_lctlg),
7981 VCPU_STAT("instruction_lctl", instruction_lctl),
8082 VCPU_STAT("instruction_stctl", instruction_stctl),
arch/x86/include/asm/kvm_host.h+2−0
@@ -1031,6 +1031,8 @@ struct kvm_vcpu_stat { · 1030 unmodified lines
10311031 u64 irq_injections;
10321032 u64 nmi_injections;
10331033 u64 req_event;
1034+ u64 halt_poll_success_ns;
1035+ u64 halt_poll_fail_ns;
10341036 };
10351037
10361038 struct x86_instruction_info;
arch/x86/kvm/x86.c+2−0
@@ -217,6 +217,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { · 216 unmodified lines
217217 VCPU_STAT("nmi_injections", nmi_injections),
218218 VCPU_STAT("req_event", req_event),
219219 VCPU_STAT("l1d_flush", l1d_flush),
220+ VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),
221+ VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),
220222 VM_STAT("mmu_shadow_zapped", mmu_shadow_zapped),
221223 VM_STAT("mmu_pte_write", mmu_pte_write),
222224 VM_STAT("mmu_pte_updated", mmu_pte_updated),
virt/kvm/kvm_main.c+15−3
@@ -2667,18 +2667,27 @@ out: · 2666 unmodified lines
26672667 return ret;
26682668 }
26692669
2670+static inline void
2671+update_halt_poll_stats(struct kvm_vcpu *vcpu, u64 poll_ns, bool waited)
2672+{
2673+ if (waited)
2674+ vcpu->stat.halt_poll_fail_ns += poll_ns;
2675+ else
2676+ vcpu->stat.halt_poll_success_ns += poll_ns;
2677+}
2678+
26702679 /*
26712680 * The vCPU has executed a HLT instruction with in-kernel mode enabled.
26722681 */
26732682 void kvm_vcpu_block(struct kvm_vcpu *vcpu)
26742683 {
2675− ktime_t start, cur;
2684+ ktime_t start, cur, poll_end;
26762685 bool waited = false;
26772686 u64 block_ns;
26782687
26792688 kvm_arch_vcpu_blocking(vcpu);
26802689
2681− start = cur = ktime_get();
2690+ start = cur = poll_end = ktime_get();
26822691 if (vcpu->halt_poll_ns && !kvm_arch_no_poll(vcpu)) {
26832692 ktime_t stop = ktime_add_ns(ktime_get(), vcpu->halt_poll_ns);
26842693
@@ -2694,7 +2703,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu) · 9 unmodified lines
26942703 ++vcpu->stat.halt_poll_invalid;
26952704 goto out;
26962705 }
2697− cur = ktime_get();
2706+ poll_end = cur = ktime_get();
26982707 } while (single_task_running() && ktime_before(cur, stop));
26992708 }
27002709
@@ -2714,6 +2723,9 @@ out: · 13 unmodified lines
27142723 kvm_arch_vcpu_unblocking(vcpu);
27152724 block_ns = ktime_to_ns(cur) - ktime_to_ns(start);
27162725
2726+ update_halt_poll_stats(
2727+ vcpu, ktime_to_ns(ktime_sub(poll_end, start)), waited);
2728+
27172729 if (!kvm_arch_no_poll(vcpu)) {
27182730 if (!vcpu_valid_wakeup(vcpu)) {
27192731 shrink_halt_poll_ns(vcpu);