aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorSuresh E. Warrier <warrier@linux.vnet.ibm.com>2015-03-20 05:39:45 -0400
committerAlexander Graf <agraf@suse.de>2015-04-21 09:21:30 -0400
commit878610fe9884a34a282cd4431237343864324d23 (patch)
treee87987f0da6ea462d6a790cebe3673fba8a6d8ff /arch/powerpc
parenta4bd6eb07ca72d21a7a34499ad34cfef6f527d4e (diff)
KVM: PPC: Book3S HV: Add guest->host real mode completion counters
Add counters to track number of times we switch from guest real mode to host virtual mode during an interrupt-related hyper call because the hypercall requires actions that cannot be completed in real mode. This will help when making optimizations that reduce guest-host transitions. It is safe to use an ordinary increment rather than an atomic operation because there is one ICP per virtual CPU and kvmppc_xics_rm_complete() only works on the ICP for the current VCPU. The counters are displayed as part of IPC and ICP state provided by /sys/debug/kernel/powerpc/kvm* for each VM. Signed-off-by: Suresh Warrier <warrier@linux.vnet.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kvm/book3s_xics.c31
-rw-r--r--arch/powerpc/kvm/book3s_xics.h6
2 files changed, 33 insertions, 4 deletions
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index a4a8d9f0dcb7..60bdbac8beba 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -802,14 +802,22 @@ static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
802 XICS_DBG("XICS_RM: H_%x completing, act: %x state: %lx tgt: %p\n", 802 XICS_DBG("XICS_RM: H_%x completing, act: %x state: %lx tgt: %p\n",
803 hcall, icp->rm_action, icp->rm_dbgstate.raw, icp->rm_dbgtgt); 803 hcall, icp->rm_action, icp->rm_dbgstate.raw, icp->rm_dbgtgt);
804 804
805 if (icp->rm_action & XICS_RM_KICK_VCPU) 805 if (icp->rm_action & XICS_RM_KICK_VCPU) {
806 icp->n_rm_kick_vcpu++;
806 kvmppc_fast_vcpu_kick(icp->rm_kick_target); 807 kvmppc_fast_vcpu_kick(icp->rm_kick_target);
807 if (icp->rm_action & XICS_RM_CHECK_RESEND) 808 }
809 if (icp->rm_action & XICS_RM_CHECK_RESEND) {
810 icp->n_rm_check_resend++;
808 icp_check_resend(xics, icp->rm_resend_icp); 811 icp_check_resend(xics, icp->rm_resend_icp);
809 if (icp->rm_action & XICS_RM_REJECT) 812 }
813 if (icp->rm_action & XICS_RM_REJECT) {
814 icp->n_rm_reject++;
810 icp_deliver_irq(xics, icp, icp->rm_reject); 815 icp_deliver_irq(xics, icp, icp->rm_reject);
811 if (icp->rm_action & XICS_RM_NOTIFY_EOI) 816 }
817 if (icp->rm_action & XICS_RM_NOTIFY_EOI) {
818 icp->n_rm_notify_eoi++;
812 kvm_notify_acked_irq(vcpu->kvm, 0, icp->rm_eoied_irq); 819 kvm_notify_acked_irq(vcpu->kvm, 0, icp->rm_eoied_irq);
820 }
813 821
814 icp->rm_action = 0; 822 icp->rm_action = 0;
815 823
@@ -872,10 +880,17 @@ static int xics_debug_show(struct seq_file *m, void *private)
872 struct kvm *kvm = xics->kvm; 880 struct kvm *kvm = xics->kvm;
873 struct kvm_vcpu *vcpu; 881 struct kvm_vcpu *vcpu;
874 int icsid, i; 882 int icsid, i;
883 unsigned long t_rm_kick_vcpu, t_rm_check_resend;
884 unsigned long t_rm_reject, t_rm_notify_eoi;
875 885
876 if (!kvm) 886 if (!kvm)
877 return 0; 887 return 0;
878 888
889 t_rm_kick_vcpu = 0;
890 t_rm_notify_eoi = 0;
891 t_rm_check_resend = 0;
892 t_rm_reject = 0;
893
879 seq_printf(m, "=========\nICP state\n=========\n"); 894 seq_printf(m, "=========\nICP state\n=========\n");
880 895
881 kvm_for_each_vcpu(i, vcpu, kvm) { 896 kvm_for_each_vcpu(i, vcpu, kvm) {
@@ -890,8 +905,16 @@ static int xics_debug_show(struct seq_file *m, void *private)
890 icp->server_num, state.xisr, 905 icp->server_num, state.xisr,
891 state.pending_pri, state.cppr, state.mfrr, 906 state.pending_pri, state.cppr, state.mfrr,
892 state.out_ee, state.need_resend); 907 state.out_ee, state.need_resend);
908 t_rm_kick_vcpu += icp->n_rm_kick_vcpu;
909 t_rm_notify_eoi += icp->n_rm_notify_eoi;
910 t_rm_check_resend += icp->n_rm_check_resend;
911 t_rm_reject += icp->n_rm_reject;
893 } 912 }
894 913
914 seq_puts(m, "ICP Guest Real Mode exit totals: ");
915 seq_printf(m, "\tkick_vcpu=%lu check_resend=%lu reject=%lu notify_eoi=%lu\n",
916 t_rm_kick_vcpu, t_rm_check_resend,
917 t_rm_reject, t_rm_notify_eoi);
895 for (icsid = 0; icsid <= KVMPPC_XICS_MAX_ICS_ID; icsid++) { 918 for (icsid = 0; icsid <= KVMPPC_XICS_MAX_ICS_ID; icsid++) {
896 struct kvmppc_ics *ics = xics->ics[icsid]; 919 struct kvmppc_ics *ics = xics->ics[icsid];
897 920
diff --git a/arch/powerpc/kvm/book3s_xics.h b/arch/powerpc/kvm/book3s_xics.h
index 73f0f2723c07..de970eca2167 100644
--- a/arch/powerpc/kvm/book3s_xics.h
+++ b/arch/powerpc/kvm/book3s_xics.h
@@ -78,6 +78,12 @@ struct kvmppc_icp {
78 u32 rm_reject; 78 u32 rm_reject;
79 u32 rm_eoied_irq; 79 u32 rm_eoied_irq;
80 80
81 /* Counters for each reason we exited real mode */
82 unsigned long n_rm_kick_vcpu;
83 unsigned long n_rm_check_resend;
84 unsigned long n_rm_reject;
85 unsigned long n_rm_notify_eoi;
86
81 /* Debug stuff for real mode */ 87 /* Debug stuff for real mode */
82 union kvmppc_icp_state rm_dbgstate; 88 union kvmppc_icp_state rm_dbgstate;
83 struct kvm_vcpu *rm_dbgtgt; 89 struct kvm_vcpu *rm_dbgtgt;