From patchwork Mon Oct 28 16:32:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 286593 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3DD482C007B for ; Tue, 29 Oct 2013 03:33:06 +1100 (EST) Received: from localhost ([::1]:42113 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VapkV-0002yV-2w for incoming@patchwork.ozlabs.org; Mon, 28 Oct 2013 12:33:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39590) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vapk6-0002v9-0U for qemu-devel@nongnu.org; Mon, 28 Oct 2013 12:32:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Vapjx-0005VA-IY for qemu-devel@nongnu.org; Mon, 28 Oct 2013 12:32:37 -0400 Received: from mail-qa0-x22d.google.com ([2607:f8b0:400d:c00::22d]:61956) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vapjx-0005V5-Dr for qemu-devel@nongnu.org; Mon, 28 Oct 2013 12:32:29 -0400 Received: by mail-qa0-f45.google.com with SMTP id ii20so2212537qab.18 for ; Mon, 28 Oct 2013 09:32:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id; bh=pJ7KVU3Xj4Z9qLRU61bKtkn2Dn4K2zAUZnKLkjfZr38=; b=IX7y6CZYfWI6MfnH5JsuH0im/NfM5oqw9EgS3kwEoLnGo5Dt/IASrcffzxEpItSLKi Yjtt/RRmgy/cJ1At0buurhGiEBxKDiYe8+fqTSGDMGif93qcILFNxs5QE+9HzZqx38UI TYk3KbwoG1fxFNsGH3dfXPSD9pAtYo6zA1BC8OOOD8dObWH08KDa32anYy7pY/eGySld 5/cb8B1MW0fjaK1U1nTeXV7Q6PDY3MZa8xBXHcp+28JIhXWbIGAJ/NSVgXsaM/DFq7Ye V7QdTVpkBXS80pf2RYEm+lHfvqgi602GcPe3sei90oQiLDUITC/Zd/6pkImPbm98ryg4 MluA== X-Received: by 10.224.14.79 with SMTP id f15mr3258827qaa.113.1382977948970; Mon, 28 Oct 2013 09:32:28 -0700 (PDT) Received: from yakj.usersys.redhat.com (net-37-117-137-113.cust.dsl.vodafone.it. [37.117.137.113]) by mx.google.com with ESMTPSA id jw9sm44770882qeb.2.2013.10.28.09.32.26 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 28 Oct 2013 09:32:27 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 28 Oct 2013 17:32:18 +0100 Message-Id: <1382977938-13844-1-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400d:c00::22d Subject: [Qemu-devel] [PATCH 1.7] timers: fix stop/cont with -icount 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 Stop/cont commands are broken with -icount due to a deadlock. The real problem is that the computation of timers_state.cpu_ticks_offset makes no sense with -icount enabled: we set it to an icount clock value in cpu_disable_ticks, and subtract a TSC (or similar, whatever cpu_get_real_ticks happens to return) value in cpu_enable_ticks. The fix is simple. timers_state.cpu_ticks_offset is only used together with cpu_get_real_ticks, so we can use cpu_get_real_ticks in cpu_disable_ticks. There is no need to update cpu_ticks_prev at the time cpu_disable_ticks is called; instead, we can do it the next time cpu_get_ticks is called. The change to cpu_disable_ticks is the important part of the patch. The rest modifies the code to always check timers_state.cpu_ticks_prev, even when the ticks are not advancing (i.e. the VM is stopped). It also makes a similar change to cpu_get_clock_locked, so that the code remains similar for cpu_get_ticks and cpu_get_clock_locked. Signed-off-by: Paolo Bonzini --- cpus.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/cpus.c b/cpus.c index 398229e..c2c6864 100644 --- a/cpus.c +++ b/cpus.c @@ -165,36 +165,38 @@ int64_t cpu_get_icount(void) /* Caller must hold the BQL */ int64_t cpu_get_ticks(void) { + int64_t ticks; + if (use_icount) { return cpu_get_icount(); } - if (!timers_state.cpu_ticks_enabled) { - return timers_state.cpu_ticks_offset; - } else { - int64_t ticks; - ticks = cpu_get_real_ticks(); - if (timers_state.cpu_ticks_prev > ticks) { - /* Note: non increasing ticks may happen if the host uses - software suspend */ - timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks; - } - timers_state.cpu_ticks_prev = ticks; - return ticks + timers_state.cpu_ticks_offset; + + ticks = timers_state.cpu_ticks_offset; + if (timers_state.cpu_ticks_enabled) { + ticks += cpu_get_real_ticks(); + } + + if (timers_state.cpu_ticks_prev > ticks) { + /* Note: non increasing ticks may happen if the host uses + software suspend */ + timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks; + ticks = timers_state.cpu_ticks_prev; } + + timers_state.cpu_ticks_prev = ticks; + return ticks; } static int64_t cpu_get_clock_locked(void) { - int64_t ti; + int64_t ticks; - if (!timers_state.cpu_ticks_enabled) { - ti = timers_state.cpu_clock_offset; - } else { - ti = get_clock(); - ti += timers_state.cpu_clock_offset; + ticks = timers_state.cpu_clock_offset; + if (timers_state.cpu_ticks_enabled) { + ticks += get_clock(); } - return ti; + return ticks; } /* return the host CPU monotonic timer and handle stop/restart */ @@ -235,7 +237,7 @@ void cpu_disable_ticks(void) /* Here, the really thing protected by seqlock is cpu_clock_offset. */ seqlock_write_lock(&timers_state.vm_clock_seqlock); if (timers_state.cpu_ticks_enabled) { - timers_state.cpu_ticks_offset = cpu_get_ticks(); + timers_state.cpu_ticks_offset += cpu_get_real_ticks(); timers_state.cpu_clock_offset = cpu_get_clock_locked(); timers_state.cpu_ticks_enabled = 0; }