From patchwork Tue Aug 14 08:24:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 1318641 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id E2FBADF215 for ; Tue, 14 Aug 2012 08:24:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753951Ab2HNIYZ (ORCPT ); Tue, 14 Aug 2012 04:24:25 -0400 Received: from goliath.siemens.de ([192.35.17.28]:18212 "EHLO goliath.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751905Ab2HNIYW (ORCPT ); Tue, 14 Aug 2012 04:24:22 -0400 Received: from mail1.siemens.de (localhost [127.0.0.1]) by goliath.siemens.de (8.13.6/8.13.6) with ESMTP id q7E8O4Yk020024; Tue, 14 Aug 2012 10:24:05 +0200 Received: from mchn199C.mchp.siemens.de ([139.22.49.95]) by mail1.siemens.de (8.13.6/8.13.6) with SMTP id q7E8O3xA007146; Tue, 14 Aug 2012 10:24:03 +0200 Message-ID: <502A0B23.2080701@siemens.com> Date: Tue, 14 Aug 2012 10:24:03 +0200 From: Jan Kiszka User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 To: Avi Kivity , Marcelo Tosatti CC: qemu-devel , kvm , qemu-stable , Michael Tokarev , Gerd Hoffmann , Gleb Natapov Subject: [PATCH uq/master 1/2] kvm: i8254: Cache kernel clock offset in KVMPITState Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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 --- 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; } }