OSDN Git Service

KVM: stats: Add halt polling related histogram stats
authorJing Zhang <jingzhangos@google.com>
Mon, 2 Aug 2021 16:56:33 +0000 (16:56 +0000)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 20 Aug 2021 20:06:33 +0000 (16:06 -0400)
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>
arch/powerpc/kvm/book3s_hv.c
include/linux/kvm_host.h
include/linux/kvm_types.h
virt/kvm/kvm_main.c

index 813ca15..6d63c8e 100644 (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 */
index 58a8ffe..e4d712e 100644 (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;
 
index 291ef55..de7fb5f 100644 (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
index e6fc579..3e67c93 100644 (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);