KVM: stats: Add halt polling related histogram stats

Add three log histogram stats to record the distribution of time spent
on successful polling, failed polling and VCPU wait.
halt_poll_success_hist: Distribution of spent time for a successful poll.
halt_poll_fail_hist: Distribution of spent time for a failed poll.
halt_wait_hist: Distribution of time a VCPU has spent on waiting.

Signed-off-by: Jing Zhang <jingzhangos@google.com>
Message-Id: <20210802165633.1866976-6-jingzhangos@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Jing Zhang 2021-08-02 16:56:33 +00:00 committed by Paolo Bonzini
parent 87bcc5fa09
commit 8ccba534a1
4 changed files with 38 additions and 3 deletions

View File

@ -4146,17 +4146,29 @@ out:
if (do_sleep) {
vc->runner->stat.generic.halt_wait_ns +=
ktime_to_ns(cur) - ktime_to_ns(start_wait);
KVM_STATS_LOG_HIST_UPDATE(
vc->runner->stat.generic.halt_wait_hist,
ktime_to_ns(cur) - ktime_to_ns(start_wait));
/* Attribute failed poll time */
if (vc->halt_poll_ns)
if (vc->halt_poll_ns) {
vc->runner->stat.generic.halt_poll_fail_ns +=
ktime_to_ns(start_wait) -
ktime_to_ns(start_poll);
KVM_STATS_LOG_HIST_UPDATE(
vc->runner->stat.generic.halt_poll_fail_hist,
ktime_to_ns(start_wait) -
ktime_to_ns(start_poll));
}
} else {
/* Attribute successful poll time */
if (vc->halt_poll_ns)
if (vc->halt_poll_ns) {
vc->runner->stat.generic.halt_poll_success_ns +=
ktime_to_ns(cur) -
ktime_to_ns(start_poll);
KVM_STATS_LOG_HIST_UPDATE(
vc->runner->stat.generic.halt_poll_success_hist,
ktime_to_ns(cur) - ktime_to_ns(start_poll));
}
}
/* Adjust poll time */

View File

@ -1453,7 +1453,13 @@ struct _kvm_stats_desc {
STATS_DESC_COUNTER(VCPU_GENERIC, halt_wakeup), \
STATS_DESC_TIME_NSEC(VCPU_GENERIC, halt_poll_success_ns), \
STATS_DESC_TIME_NSEC(VCPU_GENERIC, halt_poll_fail_ns), \
STATS_DESC_TIME_NSEC(VCPU_GENERIC, halt_wait_ns)
STATS_DESC_TIME_NSEC(VCPU_GENERIC, halt_wait_ns), \
STATS_DESC_LOGHIST_TIME_NSEC(VCPU_GENERIC, halt_poll_success_hist, \
HALT_POLL_HIST_COUNT), \
STATS_DESC_LOGHIST_TIME_NSEC(VCPU_GENERIC, halt_poll_fail_hist, \
HALT_POLL_HIST_COUNT), \
STATS_DESC_LOGHIST_TIME_NSEC(VCPU_GENERIC, halt_wait_hist, \
HALT_POLL_HIST_COUNT)
extern struct dentry *kvm_debugfs_dir;

View File

@ -76,6 +76,8 @@ struct kvm_mmu_memory_cache {
};
#endif
#define HALT_POLL_HIST_COUNT 32
struct kvm_vm_stat_generic {
u64 remote_tlb_flush;
};
@ -88,6 +90,9 @@ struct kvm_vcpu_stat_generic {
u64 halt_poll_success_ns;
u64 halt_poll_fail_ns;
u64 halt_wait_ns;
u64 halt_poll_success_hist[HALT_POLL_HIST_COUNT];
u64 halt_poll_fail_hist[HALT_POLL_HIST_COUNT];
u64 halt_wait_hist[HALT_POLL_HIST_COUNT];
};
#define KVM_STATS_NAME_SIZE 48

View File

@ -3222,13 +3222,23 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
++vcpu->stat.generic.halt_successful_poll;
if (!vcpu_valid_wakeup(vcpu))
++vcpu->stat.generic.halt_poll_invalid;
KVM_STATS_LOG_HIST_UPDATE(
vcpu->stat.generic.halt_poll_success_hist,
ktime_to_ns(ktime_get()) -
ktime_to_ns(start));
goto out;
}
cpu_relax();
poll_end = cur = ktime_get();
} while (kvm_vcpu_can_poll(cur, stop));
KVM_STATS_LOG_HIST_UPDATE(
vcpu->stat.generic.halt_poll_fail_hist,
ktime_to_ns(ktime_get()) - ktime_to_ns(start));
}
prepare_to_rcuwait(&vcpu->wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
@ -3244,6 +3254,8 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
if (waited) {
vcpu->stat.generic.halt_wait_ns +=
ktime_to_ns(cur) - ktime_to_ns(poll_end);
KVM_STATS_LOG_HIST_UPDATE(vcpu->stat.generic.halt_wait_hist,
ktime_to_ns(cur) - ktime_to_ns(poll_end));
}
out:
kvm_arch_vcpu_unblocking(vcpu);