From patchwork Tue Jun 21 12:21:47 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zachary Amsden X-Patchwork-Id: 901302 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p5LCLpSM023011 for ; Tue, 21 Jun 2011 12:21:52 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752997Ab1FUMVt (ORCPT ); Tue, 21 Jun 2011 08:21:49 -0400 Received: from mx1.redhat.com ([209.132.183.28]:8050 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751737Ab1FUMVt (ORCPT ); Tue, 21 Jun 2011 08:21:49 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5LCLnnJ016241 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 21 Jun 2011 08:21:49 -0400 Received: from [10.11.8.134] (vpn-8-134.rdu.redhat.com [10.11.8.134]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p5LCLm0p021937 for ; Tue, 21 Jun 2011 08:21:48 -0400 Message-ID: <4E008CDB.5080501@redhat.com> Date: Tue, 21 Jun 2011 05:21:47 -0700 From: Zachary Amsden User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100621 Fedora/3.0.5-1.fc13 Thunderbird/3.0.5 MIME-Version: 1.0 To: kvm Subject: Fwd: [KVM TSC emulation 3/9] Leave TSC synchronization window open with each new sync X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Tue, 21 Jun 2011 12:21:52 +0000 (UTC) -------- Original Message -------- Subject: [KVM TSC emulation 3/9] Leave TSC synchronization window open with each new sync Date: Mon, 20 Jun 2011 16:59:31 -0700 From: Zachary Amsden To: Avi Kivity , Marcelo Tosatti , Glauber Costa , Frank Arnold , Joerg Roedel , Jan Kiszka , linux-kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Zachary Amsden , Avi Kivity , Marcelo Tosatti , Glauber Costa , Frank Arnold , Joerg Roedel , Jan Kiszka , linux-kvm@vger.kernel.org CC: Zachary Amsden , Zachary Amsden Currently, when the TSC is written by the guest, the variable ns is updated to force the current write to appear to have taken place at the time of the first write in this sync phase. This leaves a cliff at the end of the match window where updates will fall of the end. There are two scenarios where this can be a problem in practe - first, on a system with a large number of VCPUs, the sync period may last for an extended period of time. The second way this can happen is if the VM reboots very rapidly and we catch a VCPU TSC synchronization just around the edge. We may be unaware of the reboot, and thus the first VCPU might synchronize with an old set of the timer (at, say 0.97 seconds ago, when first powered on). The second VCPU can come in 0.04 seconds later to try to synchronize, but it misses the window because it is just over the threshold. Instead, stop doing this artificial setback of the ns variable and just update it with every write of the TSC. It may be observed that doing so causes values computed by compute_guest_tsc to diverge slightly across CPUs - note that the last_tsc_ns and last_tsc_write variable are used here, and now they last_tsc_ns will be different for each VCPU, reflecting the actual time of the update. However, compute_guest_tsc is used only for guests which already have TSC stability issues, and further, note that the previous patch has caused last_tsc_write to be incremented by the difference in nanoseconds, converted back into guest cycles. As such, only boundary rounding errors should be visible, which given the resolution in nanoseconds, is going to only be a few cycles and only visible in cross-CPU consistency tests. The problem can be fixed by adding a new set of variables to track the start offset and start write value for the current sync cycle. Signed-off-by: Zachary Amsden --- arch/x86/kvm/x86.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 457bd79..2176714 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1076,7 +1076,6 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data) offset = kvm_x86_ops->compute_tsc_offset(vcpu, data); pr_debug("kvm: adjusted tsc offset by %llu\n", delta); } - ns = kvm->arch.last_tsc_nsec; } kvm->arch.last_tsc_nsec = ns; kvm->arch.last_tsc_write = data;