Commit 878610fe authored by Suresh E. Warrier's avatar Suresh E. Warrier Committed by Alexander Graf

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: default avatarSuresh Warrier <warrier@linux.vnet.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
parent a4bd6eb0
...@@ -802,14 +802,22 @@ static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall) ...@@ -802,14 +802,22 @@ static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
XICS_DBG("XICS_RM: H_%x completing, act: %x state: %lx tgt: %p\n", XICS_DBG("XICS_RM: H_%x completing, act: %x state: %lx tgt: %p\n",
hcall, icp->rm_action, icp->rm_dbgstate.raw, icp->rm_dbgtgt); hcall, icp->rm_action, icp->rm_dbgstate.raw, icp->rm_dbgtgt);
if (icp->rm_action & XICS_RM_KICK_VCPU) if (icp->rm_action & XICS_RM_KICK_VCPU) {
icp->n_rm_kick_vcpu++;
kvmppc_fast_vcpu_kick(icp->rm_kick_target); kvmppc_fast_vcpu_kick(icp->rm_kick_target);
if (icp->rm_action & XICS_RM_CHECK_RESEND) }
if (icp->rm_action & XICS_RM_CHECK_RESEND) {
icp->n_rm_check_resend++;
icp_check_resend(xics, icp->rm_resend_icp); icp_check_resend(xics, icp->rm_resend_icp);
if (icp->rm_action & XICS_RM_REJECT) }
if (icp->rm_action & XICS_RM_REJECT) {
icp->n_rm_reject++;
icp_deliver_irq(xics, icp, icp->rm_reject); icp_deliver_irq(xics, icp, icp->rm_reject);
if (icp->rm_action & XICS_RM_NOTIFY_EOI) }
if (icp->rm_action & XICS_RM_NOTIFY_EOI) {
icp->n_rm_notify_eoi++;
kvm_notify_acked_irq(vcpu->kvm, 0, icp->rm_eoied_irq); kvm_notify_acked_irq(vcpu->kvm, 0, icp->rm_eoied_irq);
}
icp->rm_action = 0; icp->rm_action = 0;
...@@ -872,10 +880,17 @@ static int xics_debug_show(struct seq_file *m, void *private) ...@@ -872,10 +880,17 @@ static int xics_debug_show(struct seq_file *m, void *private)
struct kvm *kvm = xics->kvm; struct kvm *kvm = xics->kvm;
struct kvm_vcpu *vcpu; struct kvm_vcpu *vcpu;
int icsid, i; int icsid, i;
unsigned long t_rm_kick_vcpu, t_rm_check_resend;
unsigned long t_rm_reject, t_rm_notify_eoi;
if (!kvm) if (!kvm)
return 0; return 0;
t_rm_kick_vcpu = 0;
t_rm_notify_eoi = 0;
t_rm_check_resend = 0;
t_rm_reject = 0;
seq_printf(m, "=========\nICP state\n=========\n"); seq_printf(m, "=========\nICP state\n=========\n");
kvm_for_each_vcpu(i, vcpu, kvm) { kvm_for_each_vcpu(i, vcpu, kvm) {
...@@ -890,8 +905,16 @@ static int xics_debug_show(struct seq_file *m, void *private) ...@@ -890,8 +905,16 @@ static int xics_debug_show(struct seq_file *m, void *private)
icp->server_num, state.xisr, icp->server_num, state.xisr,
state.pending_pri, state.cppr, state.mfrr, state.pending_pri, state.cppr, state.mfrr,
state.out_ee, state.need_resend); state.out_ee, state.need_resend);
t_rm_kick_vcpu += icp->n_rm_kick_vcpu;
t_rm_notify_eoi += icp->n_rm_notify_eoi;
t_rm_check_resend += icp->n_rm_check_resend;
t_rm_reject += icp->n_rm_reject;
} }
seq_puts(m, "ICP Guest Real Mode exit totals: ");
seq_printf(m, "\tkick_vcpu=%lu check_resend=%lu reject=%lu notify_eoi=%lu\n",
t_rm_kick_vcpu, t_rm_check_resend,
t_rm_reject, t_rm_notify_eoi);
for (icsid = 0; icsid <= KVMPPC_XICS_MAX_ICS_ID; icsid++) { for (icsid = 0; icsid <= KVMPPC_XICS_MAX_ICS_ID; icsid++) {
struct kvmppc_ics *ics = xics->ics[icsid]; struct kvmppc_ics *ics = xics->ics[icsid];
......
...@@ -78,6 +78,12 @@ struct kvmppc_icp { ...@@ -78,6 +78,12 @@ struct kvmppc_icp {
u32 rm_reject; u32 rm_reject;
u32 rm_eoied_irq; u32 rm_eoied_irq;
/* Counters for each reason we exited real mode */
unsigned long n_rm_kick_vcpu;
unsigned long n_rm_check_resend;
unsigned long n_rm_reject;
unsigned long n_rm_notify_eoi;
/* Debug stuff for real mode */ /* Debug stuff for real mode */
union kvmppc_icp_state rm_dbgstate; union kvmppc_icp_state rm_dbgstate;
struct kvm_vcpu *rm_dbgtgt; struct kvm_vcpu *rm_dbgtgt;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment