From patchwork Tue Aug 14 23:59:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 177519 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A2B622C0098 for ; Wed, 15 Aug 2012 10:03:11 +1000 (EST) Received: from localhost ([::1]:55919 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T1R4n-0004HF-Fe for incoming@patchwork.ozlabs.org; Tue, 14 Aug 2012 20:03:09 -0400 Received: from eggs.gnu.org ([208.118.235.92]:50302) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T1R4W-0004Dm-3A for qemu-devel@nongnu.org; Tue, 14 Aug 2012 20:02:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T1R4U-00018v-Hz for qemu-devel@nongnu.org; Tue, 14 Aug 2012 20:02:52 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35170) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T1R4U-00018W-9D for qemu-devel@nongnu.org; Tue, 14 Aug 2012 20:02:50 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q7F02nTJ011304 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 14 Aug 2012 20:02:49 -0400 Received: from amt.cnet (vpn1-6-27.gru2.redhat.com [10.97.6.27]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q7F02mwh013383; Tue, 14 Aug 2012 20:02:49 -0400 Received: from amt.cnet (amt.cnet [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id 98CAB65223B; Tue, 14 Aug 2012 20:59:54 -0300 (BRT) Received: (from marcelo@localhost) by amt.cnet (8.14.5/8.14.5/Submit) id q7ENxrV8007596; Tue, 14 Aug 2012 20:59:53 -0300 From: Marcelo Tosatti To: Anthony Liguori Date: Tue, 14 Aug 2012 20:59:46 -0300 Message-Id: <205df4d1a87cbb14a50655fb2c0a987467fb29d6.1344988789.git.mtosatti@redhat.com> In-Reply-To: References: X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Jan Kiszka , Marcelo Tosatti , qemu-devel@nongnu.org, kvm@vger.kernel.org Subject: [Qemu-devel] [PATCH 1/4] kvm: i8254: Cache kernel clock offset in KVMPITState X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Jan Kiszka To prepare the final fix for clock calibration issues with the in-kernel PIT, we want to cache the offset between vmclock and the clock used by the in-kernel PIT. So far, we only need to update it when the VM state changes between running and stopped because we only read the in-kernel PIT state while the VM is running. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- hw/kvm/i8254.c | 38 ++++++++++++++++++++++++-------------- 1 files changed, 24 insertions(+), 14 deletions(-) diff --git a/hw/kvm/i8254.c b/hw/kvm/i8254.c index c5d3711..c235d80 100644 --- a/hw/kvm/i8254.c +++ b/hw/kvm/i8254.c @@ -35,7 +35,8 @@ typedef struct KVMPITState { PITCommonState pit; LostTickPolicy lost_tick_policy; - bool state_valid; + bool vm_stopped; + int64_t kernel_clock_offset; } KVMPITState; static int64_t abs64(int64_t v) @@ -43,19 +44,11 @@ static int64_t abs64(int64_t v) return v < 0 ? -v : v; } -static void kvm_pit_get(PITCommonState *pit) +static void kvm_pit_update_clock_offset(KVMPITState *s) { - KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit); - struct kvm_pit_state2 kpit; - struct kvm_pit_channel_state *kchan; - struct PITChannelState *sc; int64_t offset, clock_offset; struct timespec ts; - int i, ret; - - if (s->state_valid) { - return; - } + int i; /* * Measure the delta between CLOCK_MONOTONIC, the base used for @@ -72,6 +65,21 @@ static void kvm_pit_get(PITCommonState *pit) clock_offset = offset; } } + s->kernel_clock_offset = clock_offset; +} + +static void kvm_pit_get(PITCommonState *pit) +{ + KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit); + struct kvm_pit_state2 kpit; + struct kvm_pit_channel_state *kchan; + struct PITChannelState *sc; + int i, ret; + + /* No need to re-read the state if VM is stopped. */ + if (s->vm_stopped) { + return; + } if (kvm_has_pit_state2()) { ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT2, &kpit); @@ -106,7 +114,7 @@ static void kvm_pit_get(PITCommonState *pit) sc->mode = kchan->mode; sc->bcd = kchan->bcd; sc->gate = kchan->gate; - sc->count_load_time = kchan->count_load_time + clock_offset; + sc->count_load_time = kchan->count_load_time + s->kernel_clock_offset; } sc = &pit->channels[0]; @@ -211,10 +219,12 @@ static void kvm_pit_vm_state_change(void *opaque, int running, KVMPITState *s = opaque; if (running) { - s->state_valid = false; + kvm_pit_update_clock_offset(s); + s->vm_stopped = false; } else { + kvm_pit_update_clock_offset(s); kvm_pit_get(&s->pit); - s->state_valid = true; + s->vm_stopped = true; } }