diff options
author | Suresh E. Warrier <warrier@linux.vnet.ibm.com> | 2015-03-20 05:39:45 -0400 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2015-04-21 09:21:30 -0400 |
commit | 878610fe9884a34a282cd4431237343864324d23 (patch) | |
tree | e87987f0da6ea462d6a790cebe3673fba8a6d8ff /arch/powerpc | |
parent | a4bd6eb07ca72d21a7a34499ad34cfef6f527d4e (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.c | 31 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_xics.h | 6 |
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; |