aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
authorSuraj Jitindar Singh <sjitindarsingh@gmail.com>2016-08-02 00:03:23 -0400
committerPaul Mackerras <paulus@ozlabs.org>2016-09-07 22:25:37 -0400
commit2a27f514a47d39c50aaa5c07831ab35178955d47 (patch)
treeb4e3b63f4a22278b1cd4c8cf0568cc71aec6b3a9 /arch/powerpc/kvm
parent8a7e75d47b68193339f8727cf4503271d0a0b1d0 (diff)
KVM: PPC: Implement existing and add new halt polling vcpu stats
vcpu stats are used to collect information about a vcpu which can be viewed in the debugfs. For example halt_attempted_poll and halt_successful_poll are used to keep track of the number of times the vcpu attempts to and successfully polls. These stats are currently not used on powerpc. Implement incrementation of the halt_attempted_poll and halt_successful_poll vcpu stats for powerpc. Since these stats are summed over all the vcpus for all running guests it doesn't matter which vcpu they are attributed to, thus we choose the current runner vcpu of the vcore. Also add new vcpu stats: halt_poll_success_ns, halt_poll_fail_ns and halt_wait_ns to be used to accumulate the total time spend polling successfully, polling unsuccessfully and waiting respectively, and halt_successful_wait to accumulate the number of times the vcpu waits. Given that halt_poll_success_ns, halt_poll_fail_ns and halt_wait_ns are expressed in nanoseconds it is necessary to represent these as 64-bit quantities, otherwise they would overflow after only about 4 seconds. Given that the total time spend either polling or waiting will be known and the number of times that each was done, it will be possible to determine the average poll and wait times. This will give the ability to tune the kvm module parameters based on the calculated average wait and poll times. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Reviewed-by: David Matlack <dmatlack@google.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/book3s.c4
-rw-r--r--arch/powerpc/kvm/book3s_hv.c36
2 files changed, 35 insertions, 5 deletions
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 47018fcbf7d6..71eb8f3d3b54 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -52,8 +52,12 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
52 { "dec", VCPU_STAT(dec_exits) }, 52 { "dec", VCPU_STAT(dec_exits) },
53 { "ext_intr", VCPU_STAT(ext_intr_exits) }, 53 { "ext_intr", VCPU_STAT(ext_intr_exits) },
54 { "queue_intr", VCPU_STAT(queue_intr) }, 54 { "queue_intr", VCPU_STAT(queue_intr) },
55 { "halt_poll_success_ns", VCPU_STAT(halt_poll_success_ns) },
56 { "halt_poll_fail_ns", VCPU_STAT(halt_poll_fail_ns) },
57 { "halt_wait_ns", VCPU_STAT(halt_wait_ns) },
55 { "halt_successful_poll", VCPU_STAT(halt_successful_poll), }, 58 { "halt_successful_poll", VCPU_STAT(halt_successful_poll), },
56 { "halt_attempted_poll", VCPU_STAT(halt_attempted_poll), }, 59 { "halt_attempted_poll", VCPU_STAT(halt_attempted_poll), },
60 { "halt_successful_wait", VCPU_STAT(halt_successful_wait) },
57 { "halt_poll_invalid", VCPU_STAT(halt_poll_invalid) }, 61 { "halt_poll_invalid", VCPU_STAT(halt_poll_invalid) },
58 { "halt_wakeup", VCPU_STAT(halt_wakeup) }, 62 { "halt_wakeup", VCPU_STAT(halt_wakeup) },
59 { "pf_storage", VCPU_STAT(pf_storage) }, 63 { "pf_storage", VCPU_STAT(pf_storage) },
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 3c85c3b28fc5..30ff8ab5aba1 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -2680,15 +2680,16 @@ static int kvmppc_vcore_check_block(struct kvmppc_vcore *vc)
2680 */ 2680 */
2681static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc) 2681static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)
2682{ 2682{
2683 ktime_t cur, start_poll, start_wait;
2683 int do_sleep = 1; 2684 int do_sleep = 1;
2684 ktime_t cur, start;
2685 u64 block_ns; 2685 u64 block_ns;
2686 DECLARE_SWAITQUEUE(wait); 2686 DECLARE_SWAITQUEUE(wait);
2687 2687
2688 /* Poll for pending exceptions and ceded state */ 2688 /* Poll for pending exceptions and ceded state */
2689 cur = start = ktime_get(); 2689 cur = start_poll = ktime_get();
2690 if (vc->halt_poll_ns) { 2690 if (vc->halt_poll_ns) {
2691 ktime_t stop = ktime_add_ns(start, vc->halt_poll_ns); 2691 ktime_t stop = ktime_add_ns(start_poll, vc->halt_poll_ns);
2692 ++vc->runner->stat.halt_attempted_poll;
2692 2693
2693 vc->vcore_state = VCORE_POLLING; 2694 vc->vcore_state = VCORE_POLLING;
2694 spin_unlock(&vc->lock); 2695 spin_unlock(&vc->lock);
@@ -2704,8 +2705,10 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)
2704 spin_lock(&vc->lock); 2705 spin_lock(&vc->lock);
2705 vc->vcore_state = VCORE_INACTIVE; 2706 vc->vcore_state = VCORE_INACTIVE;
2706 2707
2707 if (!do_sleep) 2708 if (!do_sleep) {
2709 ++vc->runner->stat.halt_successful_poll;
2708 goto out; 2710 goto out;
2711 }
2709 } 2712 }
2710 2713
2711 prepare_to_swait(&vc->wq, &wait, TASK_INTERRUPTIBLE); 2714 prepare_to_swait(&vc->wq, &wait, TASK_INTERRUPTIBLE);
@@ -2713,9 +2716,14 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)
2713 if (kvmppc_vcore_check_block(vc)) { 2716 if (kvmppc_vcore_check_block(vc)) {
2714 finish_swait(&vc->wq, &wait); 2717 finish_swait(&vc->wq, &wait);
2715 do_sleep = 0; 2718 do_sleep = 0;
2719 /* If we polled, count this as a successful poll */
2720 if (vc->halt_poll_ns)
2721 ++vc->runner->stat.halt_successful_poll;
2716 goto out; 2722 goto out;
2717 } 2723 }
2718 2724
2725 start_wait = ktime_get();
2726
2719 vc->vcore_state = VCORE_SLEEPING; 2727 vc->vcore_state = VCORE_SLEEPING;
2720 trace_kvmppc_vcore_blocked(vc, 0); 2728 trace_kvmppc_vcore_blocked(vc, 0);
2721 spin_unlock(&vc->lock); 2729 spin_unlock(&vc->lock);
@@ -2724,11 +2732,29 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)
2724 spin_lock(&vc->lock); 2732 spin_lock(&vc->lock);
2725 vc->vcore_state = VCORE_INACTIVE; 2733 vc->vcore_state = VCORE_INACTIVE;
2726 trace_kvmppc_vcore_blocked(vc, 1); 2734 trace_kvmppc_vcore_blocked(vc, 1);
2735 ++vc->runner->stat.halt_successful_wait;
2727 2736
2728 cur = ktime_get(); 2737 cur = ktime_get();
2729 2738
2730out: 2739out:
2731 block_ns = ktime_to_ns(cur) - ktime_to_ns(start); 2740 block_ns = ktime_to_ns(cur) - ktime_to_ns(start_poll);
2741
2742 /* Attribute wait time */
2743 if (do_sleep) {
2744 vc->runner->stat.halt_wait_ns +=
2745 ktime_to_ns(cur) - ktime_to_ns(start_wait);
2746 /* Attribute failed poll time */
2747 if (vc->halt_poll_ns)
2748 vc->runner->stat.halt_poll_fail_ns +=
2749 ktime_to_ns(start_wait) -
2750 ktime_to_ns(start_poll);
2751 } else {
2752 /* Attribute successful poll time */
2753 if (vc->halt_poll_ns)
2754 vc->runner->stat.halt_poll_success_ns +=
2755 ktime_to_ns(cur) -
2756 ktime_to_ns(start_poll);
2757 }
2732 2758
2733 /* Adjust poll time */ 2759 /* Adjust poll time */
2734 if (halt_poll_max_ns) { 2760 if (halt_poll_max_ns) {