Skip to content

Commit cb95312

Browse files
dmatlackbonzini
authored andcommitted
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 <[email protected]> Signed-off-by: Jon Cargille <[email protected]> Reviewed-by: Jim Mattson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 93dff2f commit cb95312

File tree

10 files changed

+33
-3
lines changed

10 files changed

+33
-3
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,8 @@ struct kvm_vm_stat {
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ struct kvm_vcpu_stat {
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,8 @@ struct kvm_vcpu_stat {
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,8 @@ struct kvm_vcpu_stat {
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2667,18 +2667,27 @@ static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
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)
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 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
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);

0 commit comments

Comments
 (0)