Re: [PATCH kvm-unit-tests] vmexit: add self-ipi speed tests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 17/12/2016 09:16, Paolo Bonzini wrote:
> These are designed to test APICv and optimizations of KVM_REQ_EVENT.

Results:

                                apicv=1   apicv=0

self_ipi_sti_nop                2404      5230 *
self_ipi_sti_hlt                3438      5848
self_ipi_tpr                    2401      4852
self_ipi_tpr_sti_nop            2422      6155 **
self_ipi_tpr_sti_hlt            3564      7177

x2apic_self_ipi_sti_nop         967       4511 *
x2apic_self_ipi_sti_hlt         2099      5537
x2apic_self_ipi_tpr             1057      4780
x2apic_self_ipi_tpr_sti_nop     1077      6100 **
x2apic_self_ipi_tpr_sti_hlt     2213      7127

With enable_apicv=0, the lines marked (**) are slower than those marked
(*), and IIUC that's what the patch is designed to fix.  I haven't yet
tried applying it and running the test, though.

Paolo

> Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
> ---
>  lib/x86/apic.c |  21 +++++++++++
>  lib/x86/apic.h |   2 +
>  x86/vmexit.c   | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 139 insertions(+)
> 
> diff --git a/lib/x86/apic.c b/lib/x86/apic.c
> index a9ed28d..aec968e 100644
> --- a/lib/x86/apic.c
> +++ b/lib/x86/apic.c
> @@ -113,6 +113,27 @@ uint32_t apic_id(void)
>      return apic_ops->id();
>  }
>  
> +uint8_t apic_get_tpr(void)
> +{
> +	unsigned long tpr;
> +
> +#ifdef __x86_64__
> +	asm volatile ("mov %%cr8, %0" : "=r"(tpr));
> +#else
> +	tpr = apic_read(APIC_TPR) >> 4;
> +#endif	
> +	return tpr;
> +}
> +
> +void apic_set_tpr(uint8_t tpr)
> +{
> +#ifdef __x86_64__
> +	asm volatile ("mov %0, %%cr8" : : "r"((unsigned long) tpr));
> +#else
> +	apic_write(APIC_TPR, tpr << 4);
> +#endif	
> +}
> +
>  int enable_x2apic(void)
>  {
>      unsigned a, b, c, d;
> diff --git a/lib/x86/apic.h b/lib/x86/apic.h
> index dbd6c9b..192268c 100644
> --- a/lib/x86/apic.h
> +++ b/lib/x86/apic.h
> @@ -21,6 +21,8 @@ typedef struct {
>  void mask_pic_interrupts(void);
>  
>  void eoi(void);
> +uint8_t apic_get_tpr(void);
> +void apic_set_tpr(uint8_t tpr);
>  
>  void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e);
>  void ioapic_write_reg(unsigned reg, uint32_t value);
> diff --git a/x86/vmexit.c b/x86/vmexit.c
> index 2d99d5f..cf53130 100644
> --- a/x86/vmexit.c
> +++ b/x86/vmexit.c
> @@ -6,6 +6,10 @@
>  #include "x86/vm.h"
>  #include "x86/desc.h"
>  #include "x86/acpi.h"
> +#include "x86/apic.h"
> +#include "x86/isr.h"
> +
> +#define IPI_TEST_VECTOR	0xb0
>  
>  struct test {
>  	void (*func)(void);
> @@ -61,6 +65,107 @@ static void nop(void *junk)
>  {
>  }
>  
> +static void self_ipi_isr(isr_regs_t *regs)
> +{
> +	eoi();
> +}
> +
> +static void x2apic_self_ipi(int vec)
> +{
> +	wrmsr(0x83f, vec);
> +}
> +
> +static void apic_self_ipi(int vec)
> +{
> +        apic_icr_write(APIC_INT_ASSERT | APIC_DEST_SELF | APIC_DEST_PHYSICAL |
> +		       APIC_DM_FIXED | IPI_TEST_VECTOR, vec);
> +}
> +
> +static void self_ipi_sti_nop(void)
> +{
> +	irq_disable();
> +	apic_self_ipi(IPI_TEST_VECTOR);
> +	asm volatile("sti; nop");
> +}
> +
> +static void self_ipi_sti_hlt(void)
> +{
> +	irq_disable();
> +	apic_self_ipi(IPI_TEST_VECTOR);
> +	asm volatile("sti; hlt");
> +}
> +
> +static void self_ipi_tpr(void)
> +{
> +	apic_set_tpr(0x0f);
> +	apic_self_ipi(IPI_TEST_VECTOR);
> +	apic_set_tpr(0x00);
> +	asm volatile("nop");
> +}
> +
> +static void self_ipi_tpr_sti_nop(void)
> +{
> +	irq_disable();
> +	apic_set_tpr(0x0f);
> +	apic_self_ipi(IPI_TEST_VECTOR);
> +	apic_set_tpr(0x00);
> +	asm volatile("sti; nop");
> +}
> +
> +static void self_ipi_tpr_sti_hlt(void)
> +{
> +	irq_disable();
> +	apic_set_tpr(0x0f);
> +	apic_self_ipi(IPI_TEST_VECTOR);
> +	apic_set_tpr(0x00);
> +	asm volatile("sti; hlt");
> +}
> +
> +static int is_x2apic(void)
> +{
> +    return rdmsr(MSR_IA32_APICBASE) & APIC_EXTD;
> +}
> +
> +static void x2apic_self_ipi_sti_nop(void)
> +{
> +	irq_disable();
> +	x2apic_self_ipi(IPI_TEST_VECTOR);
> +	asm volatile("sti; nop");
> +}
> +
> +static void x2apic_self_ipi_sti_hlt(void)
> +{
> +	irq_disable();
> +	x2apic_self_ipi(IPI_TEST_VECTOR);
> +	asm volatile("sti; hlt");
> +}
> +
> +static void x2apic_self_ipi_tpr(void)
> +{
> +	apic_set_tpr(0x0f);
> +	x2apic_self_ipi(IPI_TEST_VECTOR);
> +	apic_set_tpr(0x00);
> +	asm volatile("nop");
> +}
> +
> +static void x2apic_self_ipi_tpr_sti_nop(void)
> +{
> +	irq_disable();
> +	apic_set_tpr(0x0f);
> +	x2apic_self_ipi(IPI_TEST_VECTOR);
> +	apic_set_tpr(0x00);
> +	asm volatile("sti; nop");
> +}
> +
> +static void x2apic_self_ipi_tpr_sti_hlt(void)
> +{
> +	irq_disable();
> +	apic_set_tpr(0x0f);
> +	x2apic_self_ipi(IPI_TEST_VECTOR);
> +	apic_set_tpr(0x00);
> +	asm volatile("sti; hlt");
> +}
> +
>  static void ipi(void)
>  {
>  	on_cpu(1, nop, 0);
> @@ -281,6 +386,16 @@ static struct test tests[] = {
>  	{ inl_nop_kernel, "inl_from_kernel", .parallel = 1 },
>  	{ outl_elcr_kernel, "outl_to_kernel", .parallel = 1 },
>  	{ mov_dr, "mov_dr", .parallel = 1 },
> +	{ self_ipi_sti_nop, "self_ipi_sti_nop", .parallel = 1, },
> +	{ self_ipi_sti_hlt, "self_ipi_sti_hlt", .parallel = 1, },
> +	{ self_ipi_tpr, "self_ipi_tpr", .parallel = 1, },
> +	{ self_ipi_tpr_sti_nop, "self_ipi_tpr_sti_nop", .parallel = 1, },
> +	{ self_ipi_tpr_sti_hlt, "self_ipi_tpr_sti_hlt", .parallel = 1, },
> +	{ x2apic_self_ipi_sti_nop, "x2apic_self_ipi_sti_nop", is_x2apic, .parallel = 1, },
> +	{ x2apic_self_ipi_sti_hlt, "x2apic_self_ipi_sti_hlt", is_x2apic, .parallel = 1, },
> +	{ x2apic_self_ipi_tpr, "x2apic_self_ipi_tpr", is_x2apic, .parallel = 1, },
> +	{ x2apic_self_ipi_tpr_sti_nop, "x2apic_self_ipi_tpr_sti_nop", is_x2apic, .parallel = 1, },
> +	{ x2apic_self_ipi_tpr_sti_hlt, "x2apic_self_ipi_tpr_sti_hlt", is_x2apic, .parallel = 1, },
>  	{ ipi, "ipi", is_smp, .parallel = 0, },
>  	{ ipi_halt, "ipi+halt", is_smp, .parallel = 0, },
>  	{ ple_round_robin, "ple-round-robin", .parallel = 1 },
> @@ -376,6 +491,7 @@ int main(int ac, char **av)
>  
>  	smp_init();
>  	setup_vm();
> +	handle_irq(IPI_TEST_VECTOR, self_ipi_isr);
>  	nr_cpus = cpu_count();
>  
>  	for (i = cpu_count(); i > 0; i--)
> 
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux