|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v1 19/28] x86/hvm: avic: enable SVM AVIC statistics reporting
From: Denis Mukhin <dmukhin@xxxxxxxx>
Introduce performance counters for AVIC.
Enable statistics reporing via new 'dump_posted_intr' mechanism.
Signed-off-by: Denis Mukhin <dmukhin@xxxxxxxx>
---
xen/arch/x86/hvm/svm/avic.c | 50 ++++++++++++++++++++++++
xen/arch/x86/hvm/svm/avic.h | 1 +
xen/arch/x86/hvm/svm/svm.c | 1 +
xen/arch/x86/include/asm/hvm/svm-types.h | 5 +++
4 files changed, 57 insertions(+)
diff --git a/xen/arch/x86/hvm/svm/avic.c b/xen/arch/x86/hvm/svm/avic.c
index 0bcab0465227..4dcd2c94ea87 100644
--- a/xen/arch/x86/hvm/svm/avic.c
+++ b/xen/arch/x86/hvm/svm/avic.c
@@ -201,6 +201,17 @@ static void avic_vcpu_enable(const struct vcpu *v, bool
enable)
v->domain->max_vcpus);
}
+static void avic_stats_reset(struct vcpu *v)
+{
+ struct svm_vcpu *sv = &v->arch.hvm.svm;
+
+ memset(sv->avic_cnt_incomp_ipi, 0, sizeof(sv->avic_cnt_incomp_ipi));
+ sv->avic_cnt_noaccel = 0;
+ sv->avic_cnt_post_intr = 0;
+ sv->avic_cnt_doorbell = 0;
+ sv->avic_cnt_kick = 0;
+}
+
int svm_avic_vmcb_create(struct vcpu *v)
{
struct domain *d = v->domain;
@@ -237,6 +248,8 @@ int svm_avic_vmcb_create(struct vcpu *v)
ACCESS_ONCE(*sv->avic_physical_id) = entry;
ACCESS_ONCE(sv->avic_shadow_id) = entry;
+ avic_stats_reset(v);
+
avic_vcpu_enable(v, true);
return 0;
@@ -380,6 +393,8 @@ void svm_avic_vmexit_incomp_ipi(struct cpu_user_regs *regs)
BUG_ON(sv->avic_physical_id == NULL);
+ sv->avic_cnt_incomp_ipi[id]++;
+
switch ( id )
{
case AVIC_IPI_FAILURE_INVALID_INT_TYPE:
@@ -627,6 +642,8 @@ void svm_avic_vmexit_noaccel(struct cpu_user_regs *regs)
uint32_t offset = vmcb->exitinfo1 & AVIC_UNACCEL_ACCESS_OFFSET_MASK;
uint32_t rw = (vmcb->exitinfo1 >> 32) & AVIC_UNACCEL_ACCESS_WRITE_MASK;
+ sv->avic_cnt_noaccel++;
+
if ( is_svm_avic_vmexit_noaccel_trap(offset) )
{
/* Handle AVIC Trap (intercept right after the access). */
@@ -675,6 +692,8 @@ static void avic_deliver_posted_intr(struct vcpu *v)
/* Ensure the pending interrupt wakes vCPU. */
vcpu_unblock(v);
+ sv->avic_cnt_doorbell++;
+
/*
* AMD APM, 5.29.8.2 Doorbell Mechanism
* The serializing semantics of WRMSR are relaxed when writing to
@@ -684,24 +703,55 @@ static void avic_deliver_posted_intr(struct vcpu *v)
}
else
{
+ sv->avic_cnt_kick++;
+
vcpu_kick(v);
}
}
void cf_check svm_avic_hvm_deliver_posted_intr(struct vcpu *v, uint8_t vector)
{
+ struct svm_vcpu *sv = &v->arch.hvm.svm;
+
ASSERT(v != current);
if ( svm_avic_vcpu_enabled(v) )
{
+ sv->avic_cnt_post_intr++;
+
avic_deliver_posted_intr(v);
}
else
{
+ sv->avic_cnt_kick++;
+
vcpu_kick(v);
}
}
+void cf_check svm_avic_hvm_dump_posted_intr(const struct vcpu *v)
+{
+ const struct svm_vcpu *sv = &v->arch.hvm.svm;
+
+ /* NB: Do not gate with svm_avic_vcpu_enabled() check for tests */
+ printk("%pv: AVIC: incomp_ipi =
%"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64""
+ " noaccel = %"PRIu64""
+ " post_intr = %"PRIu64""
+ " doorbell = %"PRIu64""
+ " kick = %"PRIu64""
+ "\n",
+ v,
+ sv->avic_cnt_incomp_ipi[AVIC_IPI_FAILURE_INVALID_INT_TYPE],
+ sv->avic_cnt_incomp_ipi[AVIC_IPI_FAILURE_TARGET_NOT_RUNNING],
+ sv->avic_cnt_incomp_ipi[AVIC_IPI_FAILURE_INVALID_TARGET],
+ sv->avic_cnt_incomp_ipi[AVIC_IPI_FAILURE_INVALID_BACKING_PAGE],
+ sv->avic_cnt_incomp_ipi[AVIC_IPI_FAILURE_INVALID_IPI_VECTOR],
+ sv->avic_cnt_noaccel,
+ sv->avic_cnt_post_intr,
+ sv->avic_cnt_doorbell,
+ sv->avic_cnt_kick);
+}
+
/*
* Local variables:
* mode: C
diff --git a/xen/arch/x86/hvm/svm/avic.h b/xen/arch/x86/hvm/svm/avic.h
index 098924925e89..24d5fab59b29 100644
--- a/xen/arch/x86/hvm/svm/avic.h
+++ b/xen/arch/x86/hvm/svm/avic.h
@@ -33,5 +33,6 @@ void svm_avic_vcpu_switch_to(struct vcpu *v);
void svm_avic_vcpu_switch_from(struct vcpu *v);
void cf_check svm_avic_hvm_deliver_posted_intr(struct vcpu *v, uint8_t vector);
+void cf_check svm_avic_hvm_dump_posted_intr(const struct vcpu *v);
#endif /* __SVM_AVIC_H__ */
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 2fac76725c4f..83977d411b0a 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -2519,6 +2519,7 @@ static void __init svm_avic_start(void)
return;
svm_function_table.deliver_posted_intr = svm_avic_hvm_deliver_posted_intr;
+ svm_function_table.dump_posted_intr = svm_avic_hvm_dump_posted_intr;
svm_function_table.caps.virtual_intr_delivery = true;
}
diff --git a/xen/arch/x86/include/asm/hvm/svm-types.h
b/xen/arch/x86/include/asm/hvm/svm-types.h
index cc40b1b02095..ac411f781ed4 100644
--- a/xen/arch/x86/include/asm/hvm/svm-types.h
+++ b/xen/arch/x86/include/asm/hvm/svm-types.h
@@ -53,6 +53,11 @@ struct svm_vcpu {
uint32_t avic_dfr;
uint64_t *avic_physical_id;
uint64_t avic_shadow_id;
+ uint64_t avic_cnt_incomp_ipi[AVIC_IPI_FAILURE_MAX];
+ uint64_t avic_cnt_noaccel;
+ uint64_t avic_cnt_post_intr;
+ uint64_t avic_cnt_doorbell;
+ uint64_t avic_cnt_kick;
};
struct nestedsvm {
--
2.55.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |