From patchwork Tue Aug 13 15:10:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Roth X-Patchwork-Id: 266841 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (unknown [IPv6:2001:4830:134:3::12]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id EE6B42C0104 for ; Wed, 14 Aug 2013 01:22:50 +1000 (EST) Received: from localhost ([::1]:49794 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V9GQq-0000yV-R6 for incoming@patchwork.ozlabs.org; Tue, 13 Aug 2013 11:22:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60039) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V9GGW-0004uG-Q0 for qemu-devel@nongnu.org; Tue, 13 Aug 2013 11:12:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V9GGQ-0003pR-7u for qemu-devel@nongnu.org; Tue, 13 Aug 2013 11:12:08 -0400 Received: from mail-oa0-x233.google.com ([2607:f8b0:4003:c02::233]:47463) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V9GGQ-0003pH-2r; Tue, 13 Aug 2013 11:12:02 -0400 Received: by mail-oa0-f51.google.com with SMTP id h1so11436359oag.38 for ; Tue, 13 Aug 2013 08:12:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=vmv81dREqZ4fXfFLbXBQunsIDF1spSt5nVFSlaq86cc=; b=aiVh6shwM+AmUSQqwqUwIMZUW6sOJ5yAXgNPQLZJef1DoDg85H2FQAT9+6zvi8yeE5 glMVZXNpN5weEkQXzTIuWP2NqciJaAmEr3egteerv7LkKLSsQLn0FS7DX/WdabsgoKfJ a9PtX8woylojmqft78Mo8BMUJlLYYIURdnZeZ1pxXWcrIfWnz1vbTVoWpAyIuILTbPdw QFC5zuFxfyplKJu9k4c6a32LgMkoGL5D8J1Xi0tgYtSTIneepv7GHKFb1qAOSUN3XUTj t09U90A5YvGJizOgzVWfLEL9bufkITuKGXRh1KKHoM5mtQyodMWc+ilDmwBrIH5u0cV2 CMmg== X-Received: by 10.60.61.115 with SMTP id o19mr572860oer.85.1376406721627; Tue, 13 Aug 2013 08:12:01 -0700 (PDT) Received: from loki.austin.ibm.com ([32.97.110.51]) by mx.google.com with ESMTPSA id uz16sm12947878obc.5.2013.08.13.08.12.00 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 13 Aug 2013 08:12:01 -0700 (PDT) From: Michael Roth To: qemu-devel@nongnu.org Date: Tue, 13 Aug 2013 10:10:40 -0500 Message-Id: <1376406680-16302-17-git-send-email-mdroth@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1376406680-16302-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1376406680-16302-1-git-send-email-mdroth@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4003:c02::233 Cc: aliguori@us.ibm.com, qemu-stable@nongnu.org Subject: [Qemu-devel] [PATCH 16/56] kvmclock: clock should count only if vm is running 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: Marcelo Tosatti kvmclock should not count while vm is paused, because: 1) if the vm is paused for long periods, timekeeping math can overflow while converting the (large) clocksource delta to nanoseconds. 2) Users rely on CLOCK_MONOTONIC to count run time, that is, time which OS has been in a runnable state (see CLOCK_BOOTTIME). Change kvmclock driver so as to save clock value when vm transitions from runnable to stopped state, and to restore clock value from stopped to runnable transition. Cc: qemu-stable@nongnu.org Signed-off-by: Marcelo Tosatti Signed-off-by: Gleb Natapov Signed-off-by: Paolo Bonzini (cherry picked from commit 00f4d64ee76e873be881a82d893a591487aa7950) Signed-off-by: Michael Roth --- hw/i386/kvm/clock.c | 64 ++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index 87d4d0f..98e5ca5 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -28,38 +28,6 @@ typedef struct KVMClockState { bool clock_valid; } KVMClockState; -static void kvmclock_pre_save(void *opaque) -{ - KVMClockState *s = opaque; - struct kvm_clock_data data; - int ret; - - if (s->clock_valid) { - return; - } - ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); - if (ret < 0) { - fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); - data.clock = 0; - } - s->clock = data.clock; - /* - * If the VM is stopped, declare the clock state valid to avoid re-reading - * it on next vmsave (which would return a different value). Will be reset - * when the VM is continued. - */ - s->clock_valid = !runstate_is_running(); -} - -static int kvmclock_post_load(void *opaque, int version_id) -{ - KVMClockState *s = opaque; - struct kvm_clock_data data; - - data.clock = s->clock; - data.flags = 0; - return kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data); -} static void kvmclock_vm_state_change(void *opaque, int running, RunState state) @@ -70,8 +38,18 @@ static void kvmclock_vm_state_change(void *opaque, int running, int ret; if (running) { + struct kvm_clock_data data; + s->clock_valid = false; + data.clock = s->clock; + data.flags = 0; + ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data); + if (ret < 0) { + fprintf(stderr, "KVM_SET_CLOCK failed: %s\n", strerror(ret)); + abort(); + } + if (!cap_clock_ctrl) { return; } @@ -84,6 +62,26 @@ static void kvmclock_vm_state_change(void *opaque, int running, return; } } + } else { + struct kvm_clock_data data; + int ret; + + if (s->clock_valid) { + return; + } + ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); + if (ret < 0) { + fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); + abort(); + } + s->clock = data.clock; + + /* + * If the VM is stopped, declare the clock state valid to + * avoid re-reading it on next vmsave (which would return + * a different value). Will be reset when the VM is continued. + */ + s->clock_valid = true; } } @@ -100,8 +98,6 @@ static const VMStateDescription kvmclock_vmsd = { .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, - .pre_save = kvmclock_pre_save, - .post_load = kvmclock_post_load, .fields = (VMStateField[]) { VMSTATE_UINT64(clock, KVMClockState), VMSTATE_END_OF_LIST()