public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: Marcelo Tosatti <marcelo-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org>
Cc: kvm-devel <kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Subject: Re: [RFC] fix VMX TSC synchronicity
Date: Sun, 13 Jan 2008 14:19:29 +0200	[thread overview]
Message-ID: <478A01D1.7000402@qumranet.com> (raw)
In-Reply-To: <20080111204933.GA28318@dmt>

Marcelo Tosatti wrote:
> The boot TSC sync check is failing on recent Linux SMP guests on TSC
> stable hosts.
>
>   

What about tsc unstable hosts?  If your patch convinces the guest its 
tsc is table, while the host tsc is not, then it may cause confusion 
later on.

> Following patch attempts to address the problems, which are:
>
> 1) APIC_DM_STARTUP, which is only called for vcpu's other than vcpu0,
> will trigger ->vcpu_reset(), setting the TSC to 0. Fix that by moving
> the guest_write_tsc(0) to vcpu_load.
>
> 2) vcpu's are initialized at different times by QEMU (vcpu0 init happens
> way earlier than the rest). Fix that by initializing the TSC of vcpu's >
> 0 with reference to vcpu0 init tsc value. This way TSC synchronization
> is kept (apparently Xen does something similar).
>
> 3) The code which adjusts the TSC of a VCPU on physical CPU switch is
> meant to guarantee that the guest sees a monotonically increasing value.
> However there is a large gap, in terms of clocks, between the time which
> the source CPU TSC is read and the time the destination CPU TSC is read.
> So move those two reads to happen at vcpu_clear.
>
> I believe that 3) is the reason for the -no-kvm-irqchip problems
> reported by Avi on RHEL5, with kernels < 2.6.21 (where vcpu->cpu pinning
> would fix the problem). Unfortunately I could reproduce that problem.
>
> 4-way guest with constant tick at 250Hz now reliably sees the TSC's
> synchronized, and idle guest CPU consumption is reduced by 50% (3-4%
> instead of 8%, the latter with acpi_pm_good boot parameter).
>
>
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 4741806..e1c8cf4 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -47,6 +47,8 @@ struct vcpu_vmx {
>  	struct kvm_vcpu       vcpu;
>  	int                   launched;
>  	u8                    fail;
> +	u64		      first_tsc;
> +	u64		      tsc_this;
>  	u32                   idt_vectoring_info;
>  	struct kvm_msr_entry *guest_msrs;
>  	struct kvm_msr_entry *host_msrs;
> @@ -254,6 +256,7 @@ static void vcpu_clear(struct vcpu_vmx *vmx)
>  	if (vmx->vcpu.cpu == -1)
>  		return;
>  	smp_call_function_single(vmx->vcpu.cpu, __vcpu_clear, vmx, 0, 1);
> +	rdtscll(vmx->tsc_this);
>  	vmx->launched = 0;
>  }
>  
> @@ -480,6 +483,8 @@ static void vmx_load_host_state(struct vcpu_vmx *vmx)
>  	reload_host_efer(vmx);
>  }
>  
> +static void guest_write_tsc(u64 host_tsc, u64 guest_tsc);
> +
>  /*
>   * Switches to specified vcpu, until a matching vcpu_put(), but assumes
>   * vcpu mutex is already taken.
> @@ -488,7 +493,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  {
>  	struct vcpu_vmx *vmx = to_vmx(vcpu);
>  	u64 phys_addr = __pa(vmx->vmcs);
> -	u64 tsc_this, delta;
> +	u64 delta;
>  
>  	if (vcpu->cpu != cpu) {
>  		vcpu_clear(vmx);
> @@ -511,6 +516,19 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  		struct descriptor_table dt;
>  		unsigned long sysenter_esp;
>  
> +		if (unlikely(vcpu->cpu == -1)) {
>   

This can happen after migration, I believe.

> +			rdtscll(vcpu->arch.host_tsc);
> +			vmx->tsc_this = vcpu->arch.host_tsc;
> +			if (vcpu->vcpu_id == 0) {
> +				guest_write_tsc(vcpu->arch.host_tsc, 0);
> +				vmx->first_tsc = vcpu->arch.host_tsc;
> +			} else {
> +				struct vcpu_vmx *cpu0;
> +				cpu0 = to_vmx(vcpu->kvm->vcpus[0]);
> +				guest_write_tsc(cpu0->first_tsc, 0);
> +			}
> +		}
> +
>   

Depending on vcpu_id == 0 can cause problems (for example, if vcpu 0 is 
somehow not the first to run).

We might initialize the tsc base on vm creation, and if the host tsc is 
synced, then the guest tsc should also be.

>  		vcpu->cpu = cpu;
>  		/*
>  		 * Linux uses per-cpu TSS and GDT, so set these when switching
> @@ -526,8 +544,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  		/*
>  		 * Make sure the time stamp counter is monotonous.
>  		 */
> -		rdtscll(tsc_this);
> -		delta = vcpu->arch.host_tsc - tsc_this;
> +		delta = vcpu->arch.host_tsc - vmx->tsc_this;
>  		vmcs_write64(TSC_OFFSET, vmcs_read64(TSC_OFFSET) + delta);
>   

This is a little roundabout, how about moving the delta calculation 
immediately after the call to vcpu_clear()?

I don't think this is the cause of the problem, it can't account for 
more than a few hundred cycles, compared to the much greater vmentry cost.

Anyway it should be in a separate patch.



-- 
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace

  reply	other threads:[~2008-01-13 12:19 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-11 20:49 [RFC] fix VMX TSC synchronicity Marcelo Tosatti
2008-01-13 12:19 ` Avi Kivity [this message]
     [not found]   ` <478A01D1.7000402-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-14 16:06     ` Marcelo Tosatti
2008-01-14 20:46       ` Marcelo Tosatti
2008-01-15 14:59         ` Avi Kivity
2008-01-15 14:33       ` Avi Kivity
     [not found]         ` <478CC448.1030901-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-15 14:50           ` Alexander Graf
     [not found]             ` <478CC819.3040106-r27SGEef+tmzQB+pC5nmwQ@public.gmane.org>
2008-01-15 15:09               ` Avi Kivity
     [not found]                 ` <478CCCA9.2080300-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-15 16:42                   ` Alexander Graf
     [not found]                     ` <478CE277.9010109-r27SGEef+tmzQB+pC5nmwQ@public.gmane.org>
2008-01-15 17:46                       ` Avi Kivity
     [not found]                         ` <478CF186.5030304-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-15 18:29                           ` Amit Shah
2008-01-16  5:51                   ` Andi Kleen
     [not found]                     ` <p73ir1ul3ls.fsf-KvMlXPVkKihbpigZmTR7Iw@public.gmane.org>
2008-01-16  8:46                       ` Avi Kivity
     [not found]                         ` <478DC453.1000404-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-16 13:34                           ` Andi Kleen
     [not found]                             ` <478E08E5.2030507@qumranet.com>
     [not found]                               ` <478E08E5.2030507-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-16 13:54                                 ` Andi Kleen
     [not found]                                   ` <20080116135415.GA14664-qrUzlfsMFqo/4alezvVtWx2eb7JE58TQ@public.gmane.org>
2008-01-16 13:56                                     ` Avi Kivity
2008-01-17 18:43                                     ` Marcelo Tosatti
2008-01-17 18:56                                       ` Andi Kleen
2008-01-20 14:59                                       ` Avi Kivity
2008-05-04 15:40                                       ` Avi Kivity
2008-05-06 13:55                                         ` Avi Kivity
  -- strict thread matches above, loose matches on Subject: below --
2008-01-12  3:11 Will Trives
2008-01-12 12:28 ` Marcelo Tosatti
2008-01-12 13:48   ` Will Trives
2008-01-12 20:51     ` Avi Kivity

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=478A01D1.7000402@qumranet.com \
    --to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=marcelo-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox