Re: [Xen-devel] [PATCH v2 10/10] x86/SVM: Add AMD AVIC key handler
>>> On 10.01.17 at 12:14,wrote: > On 01/05/2017 11:07 PM, Jan Beulich wrote: > On 31.12.16 at 06:46, wrote: >>> +void __init setup_avic_dump(void) >>> +{ >>> +register_keyhandler('j', avic_dump, "dump SVM AVIC", 1); >>> +} >> >> For one the description should include the word "stats". And then >> I'm rather uncertain this is work burning one of the few remaining >> available keys. Could this be made a domctl instead? > > Not sure how you are thinking about using domctl to output statistics. > Are there examples? Could you please describe? Provide a domctl to obtain the values, and a new xl command to wrap that domctl. Jan ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH v2 10/10] x86/SVM: Add AMD AVIC key handler
Jan, On 01/05/2017 11:07 PM, Jan Beulich wrote: On 31.12.16 at 06:46,wrote: +void __init setup_avic_dump(void) +{ +register_keyhandler('j', avic_dump, "dump SVM AVIC", 1); +} For one the description should include the word "stats". And then I'm rather uncertain this is work burning one of the few remaining available keys. Could this be made a domctl instead? Jan Not sure how you are thinking about using domctl to output statistics. Are there examples? Could you please describe? Thanks, Suravee ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH v2 10/10] x86/SVM: Add AMD AVIC key handler
>>> On 31.12.16 at 06:46,wrote: > +void __init setup_avic_dump(void) > +{ > +register_keyhandler('j', avic_dump, "dump SVM AVIC", 1); > +} For one the description should include the word "stats". And then I'm rather uncertain this is work burning one of the few remaining available keys. Could this be made a domctl instead? Jan ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH v2 10/10] x86/SVM: Add AMD AVIC key handler
Hi Boris/Andrew, On 1/3/17 23:04, Andrew Cooper wrote: On 03/01/17 16:01, Boris Ostrovsky wrote: +static void avic_dump(unsigned char ch) +{ +struct domain *d; +struct vcpu *v; + +printk("*** SVM AVIC Statistics **\n"); + +rcu_read_lock(_read_lock); + +for_each_domain ( d ) +{ +if ( !is_hvm_domain(d) ) || !svm_avic_vcpu_enabled(d->v[0]) (or something along these lines)? It isn't safe to deference the vcpu array like this, which in turn highlights that the avic predicate should be per-domain, not per-cpu. Under no circumstances should we have AVIC on some vcpus but not others of the same domain. ~Andrew Let me add something like: static inline bool svm_is_avic_domain(struct domain *d) { return ( d->arch.hvm_domain.svm.avic_physical_id_table != 0 ); } This should allow us to check whether the svm_avic_dom_init() is enabled successfully. Thanks, Suravee ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH v2 10/10] x86/SVM: Add AMD AVIC key handler
On 03/01/17 16:01, Boris Ostrovsky wrote: >> >> +static void avic_dump(unsigned char ch) >> +{ >> +struct domain *d; >> +struct vcpu *v; >> + >> +printk("*** SVM AVIC Statistics **\n"); >> + >> +rcu_read_lock(_read_lock); >> + >> +for_each_domain ( d ) >> +{ >> +if ( !is_hvm_domain(d) ) > || !svm_avic_vcpu_enabled(d->v[0]) (or something along these lines)? It isn't safe to deference the vcpu array like this, which in turn highlights that the avic predicate should be per-domain, not per-cpu. Under no circumstances should we have AVIC on some vcpus but not others of the same domain. ~Andrew ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH v2 10/10] x86/SVM: Add AMD AVIC key handler
> > +static void avic_dump(unsigned char ch) > +{ > +struct domain *d; > +struct vcpu *v; > + > +printk("*** SVM AVIC Statistics **\n"); > + > +rcu_read_lock(_read_lock); > + > +for_each_domain ( d ) > +{ > +if ( !is_hvm_domain(d) ) || !svm_avic_vcpu_enabled(d->v[0]) (or something along these lines)? > +continue; > +printk(">>> Domain %d <<<\n", d->domain_id); > +for_each_vcpu ( d, v ) > +{ > +printk("\tVCPU %d\n", v->vcpu_id); > +printk("\t* incomp_ipi = %u\n", > + v->arch.hvm_svm.cnt_avic_incomp_ipi); > +printk("\t* noaccel= %u\n", > + v->arch.hvm_svm.cnt_avic_noaccel); > +printk("\t* post_intr = %u\n", > + v->arch.hvm_svm.cnt_avic_post_intr); > +printk("\t* doorbell = %u\n", > + v->arch.hvm_svm.cnt_avic_doorbell); > +} > +} > + > +rcu_read_unlock(_read_lock); > + > +printk("**\n"); > + > +} > + > +void __init setup_avic_dump(void) > +{ if ( !svm_avic ) return; ? -boris > +register_keyhandler('j', avic_dump, "dump SVM AVIC", 1); > +} > + ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel
[Xen-devel] [PATCH v2 10/10] x86/SVM: Add AMD AVIC key handler
Adding new key-handler "j" for dumping AVIC-related information. Here is an example of per-domain statistics being dumped. *** SVM AVIC Statistics ** >>> Domain 1 <<< VCPU 0 * incomp_ipi = 3110 * noaccel= 236475 * post_intr = 116176 * doorbell = 715 VCPU 1 * incomp_ipi = 2565 * noaccel= 233061 * post_intr = 115765 * doorbell = 771 ** Signed-off-by: Suravee SuthikulpanitCc: Konrad Rzeszutek Wilk Cc: Jan Beulich Cc: Boris Ostrovsky --- xen/arch/x86/hvm/svm/avic.c| 48 ++ xen/arch/x86/hvm/svm/svm.c | 1 + xen/include/asm-x86/hvm/svm/vmcb.h | 6 + 3 files changed, 55 insertions(+) diff --git a/xen/arch/x86/hvm/svm/avic.c b/xen/arch/x86/hvm/svm/avic.c index faa5e45..1aea724 100644 --- a/xen/arch/x86/hvm/svm/avic.c +++ b/xen/arch/x86/hvm/svm/avic.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -320,6 +321,8 @@ void svm_avic_vmexit_do_incomp_ipi(struct cpu_user_regs *regs) u32 id = vmcb->exitinfo2 >> 32; u32 index = vmcb->exitinfo2 && 0xFF; +curr->arch.hvm_svm.cnt_avic_incomp_ipi++; + switch ( id ) { case AVIC_INCMP_IPI_ERR_INVALID_INT_TYPE: @@ -580,6 +583,8 @@ void svm_avic_vmexit_do_noaccel(struct cpu_user_regs *regs) u32 offset = vmcb->exitinfo1 & 0xFF0; u32 rw = (vmcb->exitinfo1 >> 32) & 0x1; +curr->arch.hvm_svm.cnt_avic_noaccel++; + switch ( offset ) { case APIC_ID: @@ -654,16 +659,59 @@ void svm_avic_deliver_posted_intr(struct vcpu *v, u8 vec) if ( vlapic_test_and_set_vector(vec, >regs->data[APIC_IRR]) ) return; +v->arch.hvm_svm.cnt_avic_post_intr++; /* * If vcpu is running on another cpu, hit the doorbell to signal * it to process interrupt. Otherwise, kick it. */ if ( v->is_running && (v != current) ) +{ wrmsrl(AVIC_DOORBELL, cpu_data[v->processor].apicid); +v->arch.hvm_svm.cnt_avic_doorbell++; +} else vcpu_kick(v); } +static void avic_dump(unsigned char ch) +{ +struct domain *d; +struct vcpu *v; + +printk("*** SVM AVIC Statistics **\n"); + +rcu_read_lock(_read_lock); + +for_each_domain ( d ) +{ +if ( !is_hvm_domain(d) ) +continue; +printk(">>> Domain %d <<<\n", d->domain_id); +for_each_vcpu ( d, v ) +{ +printk("\tVCPU %d\n", v->vcpu_id); +printk("\t* incomp_ipi = %u\n", + v->arch.hvm_svm.cnt_avic_incomp_ipi); +printk("\t* noaccel= %u\n", + v->arch.hvm_svm.cnt_avic_noaccel); +printk("\t* post_intr = %u\n", + v->arch.hvm_svm.cnt_avic_post_intr); +printk("\t* doorbell = %u\n", + v->arch.hvm_svm.cnt_avic_doorbell); +} +} + +rcu_read_unlock(_read_lock); + +printk("**\n"); + +} + +void __init setup_avic_dump(void) +{ +register_keyhandler('j', avic_dump, "dump SVM AVIC", 1); +} + /* * Local variables: * mode: C diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 7c0cda0..b8861d8 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1456,6 +1456,7 @@ const struct hvm_function_table * __init start_svm(void) } setup_vmcb_dump(); +setup_avic_dump(); svm_feature_flags = (current_cpu_data.extended_cpuid_level >= 0x800A ? cpuid_edx(0x800A) : 0); diff --git a/xen/include/asm-x86/hvm/svm/vmcb.h b/xen/include/asm-x86/hvm/svm/vmcb.h index 9abf077..e2b810e 100644 --- a/xen/include/asm-x86/hvm/svm/vmcb.h +++ b/xen/include/asm-x86/hvm/svm/vmcb.h @@ -552,6 +552,12 @@ struct arch_svm_struct { struct avic_phy_apic_id_ent *avic_last_phy_id; u32 avic_last_ldr; + +/* AVIC Statistics */ +u32 cnt_avic_incomp_ipi; +u32 cnt_avic_noaccel; +u32 cnt_avic_post_intr; +u32 cnt_avic_doorbell; }; struct vmcb_struct *alloc_vmcb(void); -- 1.9.1 ___ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel