From patchwork Tue Mar 13 22:47:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 131537 Delivered-To: patch@linaro.org Received: by 10.46.84.17 with SMTP id i17csp167339ljb; Tue, 13 Mar 2018 16:23:56 -0700 (PDT) X-Google-Smtp-Source: AG47ELvlVDaNeBkKrP0VCZA/NztpyWVCeHOKAXJrhKVilMda+jNtlt2CEJn0ib9GIptA56dL1zyu X-Received: by 10.200.42.177 with SMTP id b46mr3973671qta.321.1520983436501; Tue, 13 Mar 2018 16:23:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1520983436; cv=none; d=google.com; s=arc-20160816; b=IOXF+14dIMNNK2I+sQM1sxegc/vTaXbe6V2sbTHJNk1WOc8Y0dkuLBL2tBFuAkkEk1 TMXcSnpqqKdfGjEJQJ8preCaPvVwekP3zUaqlJYvLAL1cAllApiwuWvaST+0Ch25B9M0 leQeGkZ/Zos6U0S/keioSHbdGWW8cLcF/ngrXKIvN5iTx+N6w7hxifiY1IWICLMbNyfe pBP0n4vPswIUdGluxsV01mY3cCquVuK5Vq2f8BoeUTw1JINoSQ681Lxut1s/tM9d0Eji vIML8gANNcuPGh45BZItiNr03manZClcg8tQjZNqmGTDXauiJJXj1OQd5JemIT61kR+7 eQZw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=0gWafmiRSPTaWEmXlFXCR87hdsMuZo8RIGdEgNRtP3Y=; b=VPctpI5FaTvwmiFUKetUcQdc8ODfT19gEeYucXoaRy29+jH+ckfbW3ARNwcXBBtZMW n7NnU4mM9RngG5S0OCk/BNDLANRyQfDtWb0P265gpSdMnA/es5sHR51f4AP3F0whXPyY m29I2Psld4gehuJlmsG8eS6uwg4nQVFC2kN5pd2NWiytZZxyqoNUW0NAw2ZCe5PurSyU OoaXuxykLPfEvrYhnPzlZ6Eo/SXsVYGjP7hs4qK+dONyDFE5+/QFOE18rudHLyVezAFA AbZrTl1faMU58x35K5YVM4+p4gP2iCQgh68XAfUozVO8HkFm1vrpwkPz6sinzYjd2t7N fU+A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=ZK8PYYJv; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id a132si852513qkg.299.2018.03.13.16.23.56 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 13 Mar 2018 16:23:56 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=ZK8PYYJv; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from localhost ([::1]:43478 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evtGt-0002ui-Qt for patch@linaro.org; Tue, 13 Mar 2018 19:23:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58633) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evsig-0006L6-VE for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evsif-00047g-SS for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:35 -0400 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:40562) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1evsif-00047K-M6 for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:33 -0400 Received: by mail-wr0-x244.google.com with SMTP id s12so14430wre.7 for ; Tue, 13 Mar 2018 15:48:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0gWafmiRSPTaWEmXlFXCR87hdsMuZo8RIGdEgNRtP3Y=; b=ZK8PYYJvE3UfQ73hoUpZ5SpK6Fes8HSrtfND2+i49aLtHxO6yt4FAgpxU7PDpKFYkO PQE3YbMM8ROup8/UzAKL56mKz/OXH+b+8hrEPLxsAGBY4HZYYhgWLuqgDbeZnl+fDlph EgB5vggkW/E1N102lKElSZeQMrSA/47EP5jbeSq5NtDN4iPB8iv8gvNx4MHSzZw5pE3M mG41d8zpcLLrUeeRbo8qj1AsJEK4F9LrgPkkl20acKoh6ebrWBkDd2jFxPHeKhH4PN34 oDfhl8N13Z7fN/ZoXSq5VmqFghRVTF8mmnsCojzw2xWCGVtEHDwnsdaisyWk0fAvvGXn WHXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=0gWafmiRSPTaWEmXlFXCR87hdsMuZo8RIGdEgNRtP3Y=; b=qQHUqpDHaX7c8wmjiL9LhyEt1iHwKddkqfG6/UMo2HIq/hH3u8KAm4RGIJKAR7TyUZ o7gIW4H5BFQUpwL9z4CWJbCOOQloiAZ2KW/MleKptnyIIPJ9rwEFxts/J3aVkVnToXqY g+2RY45kWd4QmWF5Iaw91ECifLc6Ms7U5ouYO8vSS8HhOu71qBLz65vTOAnakiGX+w58 e9yy9pYrILfMz6TAHD3ky6Yzv4a8VR7WbhoMk8I/CzldFcdrPb/GrJDc5QpNv1A5xcM0 HXPKIEAl+NLpE5P6UO00CkR2RAY8j3eLjsWLBVGwmCb7wE6DfQtC/0Om6J3rpthz2ZEs 6u0Q== X-Gm-Message-State: AElRT7Fm3dZ6p0Q4j0N8dH6yVm66C1SQtw7T+4la0bI2mu2WaAfPC1ts nn1sRxJ1vJfRpvBDX3m2ZbpUAbKT X-Received: by 10.223.195.206 with SMTP id d14mr2026117wrg.0.1520981312246; Tue, 13 Mar 2018 15:48:32 -0700 (PDT) Received: from donizetti.lan (94-36-191-219.adsl-ull.clienti.tiscali.it. [94.36.191.219]) by smtp.gmail.com with ESMTPSA id x107sm1557951wrb.97.2018.03.13.15.48.31 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 15:48:31 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 13 Mar 2018 23:47:08 +0100 Message-Id: <20180313224719.4954-59-pbonzini@redhat.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313224719.4954-1-pbonzini@redhat.com> References: <20180313224719.4954-1-pbonzini@redhat.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PULL 58/69] replay/replay.c: bump REPLAY_VERSION again X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This time commit 802f045a5f61b781df55e4492d896b4d20503ba7 broke the replay file format. Also add a comment about this to replay-internal.h. Signed-off-by: Alex Bennée Reviewed-off-by: Pavel Dovgalyuk Acked-by: Paolo Bonzini Message-Id: <20180227095231.1060.91180.stgit@pasha-VirtualBox> Signed-off-by: Paolo Bonzini --- replay/replay-internal.h | 2 +- replay/replay.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) -- 2.14.3 diff --git a/replay/replay-internal.h b/replay/replay-internal.h index be96d7e879..8e4c701751 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -12,7 +12,7 @@ * */ - +/* Any changes to order/number of events will need to bump REPLAY_VERSION */ enum ReplayEvents { /* for instruction event */ EVENT_INSTRUCTION, diff --git a/replay/replay.c b/replay/replay.c index 7a23c62d61..9cddb6bfc9 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -22,7 +22,7 @@ /* Current version of the replay mechanism. Increase it when file format changes. */ -#define REPLAY_VERSION 0xe02006 +#define REPLAY_VERSION 0xe02007 /* Size of replay log header */ #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t)) From patchwork Tue Mar 13 22:47:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 131542 Delivered-To: patch@linaro.org Received: by 10.46.84.17 with SMTP id i17csp204761ljb; Tue, 13 Mar 2018 17:13:30 -0700 (PDT) X-Google-Smtp-Source: AG47ELsPCYfzCEVyqBEMkIAPqNsZ/Fy9IDD2lUhoxOId8kXO8e3KOdqVy3FXDZKvSgDuOlAjifi+ X-Received: by 10.200.112.91 with SMTP id y27mr4042883qtm.295.1520986410204; Tue, 13 Mar 2018 17:13:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1520986410; cv=none; d=google.com; s=arc-20160816; b=JnQs8x4AMUrxdsTYojCFuDymqy1uqKAmd1EtYWRkJcGsegclij5p3uRRQr9cXd5Mcj JtjCB2jrQh15srGcz4afA2e7Ebo4rXx2k9ILM4yZutlVTGXaguCFp4Ha9Fa8ywkr83ff Ec3LW557Ok8MRoX6y2FwILtjNynh0c9SKt9Z5gUkPzWO5U1Ij9fRcAEOXfoxl05MUByf nb8Yu8x0yQp10/SkZhOsgIDvg/1fsFoMqLnDwaZvfveR52Cpf9YJZ3J1g8RsRF5fPmUD E/QSESrGPgGbTLK84zCK2OHxIEjGwb6ofS9gO9GzeE/K22nEjqZ8rrYAITF7S0qOXtVA J+bw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=Kwu9R4Oqu/XdgRnje5Q8FcF8hFd8m9i/JhVoPskPzvQ=; b=wSemOA3VtCAYIpDPbUnCgc57Q6nndKGEm7ILHoLm4YkjfHJ0n04EdzBYdEPkBr9GVs N1ceahsuXO+aQgZshAfZ91tbSXm/ZCUUPYXb9//nWod66mdreCL1GCXpbWcImYxqzEPD F/ueqlQfpkGumf1Y3+GAZAWxlf2t0HF2cEUxTMJeMgQbdXwoCxr6xR4/b0mOGxKlnCED bXoD5G9OZQqLeCnn0HgAORiF+WaJ0V2wbMYSJ7SWeaPZhrVsYjdfwL1cT0WE38D7Os6A 6BOlTQe6LxJy6BSrj8JcwuNX9xK2ZaN2ONjKw4z61hbYqQPL6TxB5Ggz1Zt3/M3pxPXQ N7qA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=jepM2SVe; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id 6si1412664qto.475.2018.03.13.17.13.30 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 13 Mar 2018 17:13:30 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=jepM2SVe; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from localhost ([::1]:43507 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evtMi-0000c7-Qf for patch@linaro.org; Tue, 13 Mar 2018 19:29:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58670) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evsii-0006Mh-Cn for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evsih-00049M-Bw for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:36 -0400 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:37059) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1evsih-00048O-6J for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:35 -0400 Received: by mail-wm0-x244.google.com with SMTP id 139so881430wmn.2 for ; Tue, 13 Mar 2018 15:48:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Kwu9R4Oqu/XdgRnje5Q8FcF8hFd8m9i/JhVoPskPzvQ=; b=jepM2SVe01KD/NOj0IQ6G4vnE5Joqti+6K5tT7WuQ++XgCN2rW7hgujMiVN5NjYAov 9sHlGpHFxgyHmLwW9W77P3I0x6uv+Np9GeCn5tPW7peIQl19K1IodkAqlTfDIhAKJvKL 9OWR4jpVonw9Pduf2XS0B7ibBMdYPtNrnP9Ded1vYTOxaFHPceYCun3XeYmV8fGAUPwg iIXCQbKqLFDYtd10AhM1HLokUCTpVhjEIAam0GEOkTCwDs0aWDUBjRje1pjmQCM3eG0Q JkLBrNGtAlncs0PPXutFbLVJARcgJyyqISc2Z9/4AWuE4cSrZV7QwUPvM4ePsBspgIKm pMsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=Kwu9R4Oqu/XdgRnje5Q8FcF8hFd8m9i/JhVoPskPzvQ=; b=SPAItG5r07TxvrHIbPovY3Z/7/dCKjJ4BaGhR14InKv5R0+llzDreXDowTT/Bjh8+o oyAGlcr4biscp73+9rS165WfGOzZDK1ZaK8KBG+udaEMkYkqtdwNUoIbDxLxILlDoa8q Vv3uZteVUvXTod2ddPD9DSKMG8nx9hlCIcToNaho+u8iiMc1BM/Wvo4urpwRorf13rcw GZNyBnAbHARgvE58tEI2K20s+Gavz230D1+0G+fG5X+/WD3DvHgcZ8SwLNv5AtAP6SyP MC8meK3m0lnFvtXa/bLMD27qL9encvBuxa3zUFdRueCJc0REvBjib2a8xYRgofch2snu zgpA== X-Gm-Message-State: AElRT7F3/G+O6Vi14RFeCvLd2+Ul157wR0x1RWW5xs7OyZepHyggKNkR JO9A1lEYL4itip7odOerSgFW6glC X-Received: by 10.28.144.5 with SMTP id s5mr2084180wmd.98.1520981313802; Tue, 13 Mar 2018 15:48:33 -0700 (PDT) Received: from donizetti.lan (94-36-191-219.adsl-ull.clienti.tiscali.it. [94.36.191.219]) by smtp.gmail.com with ESMTPSA id x107sm1557951wrb.97.2018.03.13.15.48.32 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 15:48:33 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 13 Mar 2018 23:47:09 +0100 Message-Id: <20180313224719.4954-60-pbonzini@redhat.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313224719.4954-1-pbonzini@redhat.com> References: <20180313224719.4954-1-pbonzini@redhat.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::244 Subject: [Qemu-devel] [PULL 59/69] replay/replay-internal.c: track holding of replay_lock X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This is modelled after the iothread mutex lock. We keep a TLS flag to indicate when that thread has acquired the lock and assert we don't double-lock or release when we shouldn't have. Signed-off-by: Alex Bennée Tested-by: Pavel Dovgalyuk Message-Id: <20180227095237.1060.44661.stgit@pasha-VirtualBox> Signed-off-by: Paolo Bonzini --- replay/replay-internal.c | 11 +++++++++++ 1 file changed, 11 insertions(+) -- 2.14.3 diff --git a/replay/replay-internal.c b/replay/replay-internal.c index fca8514012..0d7e1d6bc4 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -169,6 +169,8 @@ void replay_finish_event(void) replay_fetch_data_kind(); } +static __thread bool replay_locked; + void replay_mutex_init(void) { qemu_mutex_init(&lock); @@ -179,13 +181,22 @@ void replay_mutex_destroy(void) qemu_mutex_destroy(&lock); } +static bool replay_mutex_locked(void) +{ + return replay_locked; +} + void replay_mutex_lock(void) { + g_assert(!replay_mutex_locked()); qemu_mutex_lock(&lock); + replay_locked = true; } void replay_mutex_unlock(void) { + g_assert(replay_mutex_locked()); + replay_locked = false; qemu_mutex_unlock(&lock); } From patchwork Tue Mar 13 22:47:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 131540 Delivered-To: patch@linaro.org Received: by 10.46.84.17 with SMTP id i17csp178711ljb; Tue, 13 Mar 2018 16:38:46 -0700 (PDT) X-Google-Smtp-Source: AG47ELvtncn98cnZYlA1CrEAkCoLCPnZuHVwh97fIZ+ABL4A+JI96WnX6nrTf9SvCIBnD2fxHQ2j X-Received: by 10.55.134.135 with SMTP id i129mr3544710qkd.177.1520984326513; Tue, 13 Mar 2018 16:38:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1520984326; cv=none; d=google.com; s=arc-20160816; b=Of7K7ljWN6Ytsb9FelwVj2UpwLJk91MaYqSRat0RNBrpG0vsthLMtbUPpYke2aHVIQ Bmato5sHRUcFE0GiM3s6zLdZYaNnrZHM+BGs3EpwVkUWcXTF0LQaJ6AUe7En03KL/wHw nFpvFPmgtoogSRQuRQsw3K8dKnZC1KY/OH423f7hoyCLMFJf/6iic8QivsUjosviI0mM mboc9AN5/rfs9DCP+g+NTK9zSQU8f3kcdE+yNqm+NRUiReZWLujETn1MVFxp3pDkPFy1 suNoB2/bLjqSdJXA27PgY6+RmE+XeK0ulFGHE+Ee4egfDuijJMdpWlOChSha0/P8ZD1Q +Nkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=XTH1yi6oxPFB16KTQCK1koIP4f8avjYkPChlxnpddOA=; b=WDOqsFvSWE25om05FraUBHzVM3Oq9FEFN2D+BTfk5JsEEdOP3CCheQYGVFJO5JsR4m dmgDUDpRhY/5UCPME6q9gANFYhgOG9riADKZd37yIoG0oZEEdqIGqRTdffCcVy0Lr5fd 2DhNMTC9ghl2ORLVRNbbFqzqAVyI575gSO+gnBGfRjLQcc8fhklsqoyUbzCDxsK+NOzi S3nzyRNvl+27dqmycLaav2u0WOz/dJ0ggdFHedKmLreKjORbbL42xlszpPkeqqUUPGfF /UHjvlEO8HN1GmVd71LpO8GpjYf4l/r74UpV1Cgt6HOhcUIwPTiLW1kWYUxu3dctdmg7 TFow== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=cJ6FIVJ+; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id n30si1417249qtb.398.2018.03.13.16.38.46 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 13 Mar 2018 16:38:46 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=cJ6FIVJ+; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from localhost ([::1]:43562 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evtVF-0007g0-UN for patch@linaro.org; Tue, 13 Mar 2018 19:38:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58694) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evsij-0006Ne-Eo for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evsii-0004AK-HW for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:37 -0400 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:33977) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1evsii-00049c-9l for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:36 -0400 Received: by mail-wr0-x243.google.com with SMTP id o8so2599343wra.1 for ; Tue, 13 Mar 2018 15:48:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XTH1yi6oxPFB16KTQCK1koIP4f8avjYkPChlxnpddOA=; b=cJ6FIVJ+fhKeV7kjG7yyEPKJES+y/Yl10e//L4/EX3J65EJUeouUMohAcD49yPBH1w lrznMQ5fvqtz5ifKAcm7XhB88zUTpRjCPyXOUiQUTquWHvqyVYxr0rG+NQAfAd/aDzwu aD+WXPJzNKNMthuBk+J+O6JyG1umtdyZXZuQyx8GMlWBJ8QisukgJDxb6nAmGeQhz1YX yQGh4fdUQ9NPKppc/AXYc5BT/k+D1jHZrwgLmkkF0kv3xL33Zazy1dkkst5rlxHUN7Mw sYGPjva/7+pxh5Qja3qYq2zP44prMjqWdrB4OEADkdslsLutUTPJ6HLIs/Gox2Lmfh64 bsKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=XTH1yi6oxPFB16KTQCK1koIP4f8avjYkPChlxnpddOA=; b=Am0inZ9SkDrcmOM5WALDSjrF0Y2zc+uXqqtfVRRJBUah1MgL2V1Y9+ke/g5PFp7sp3 CceNxUhtYUVBBo8xsYzVC5vuSbu1Ir1ENuBt9O/ua/mzJkFukVy2k6+jUw/0WXkHYxjg Ua+TEqvQiukdKyT5l6TCrZBdCVyomvt0Oqf8++KDdB8qYNoi3s1qxkUp/u6DYVbNgg4r PW0/jRWpayXYK9f5KSgg+qtoBVZ9LaJbk+tveORTdbu4UYADenHfYo/BVFmgZ3ezDyPX IKearLibCKBb0WQqh0QFtZSdnhiFYuiv6n3bhhzbX4AaLNOZDLObh7gs/1kQcOXSvJj0 WItg== X-Gm-Message-State: AElRT7FUQqHFNdrB3KcGZPLrD5/Gawbd+Feug66xOknrQqHAu87Ja5Fi C472DhXgKapsGWrV4tHwYxL/wr62 X-Received: by 10.223.135.26 with SMTP id a26mr1986792wra.211.1520981314827; Tue, 13 Mar 2018 15:48:34 -0700 (PDT) Received: from donizetti.lan (94-36-191-219.adsl-ull.clienti.tiscali.it. [94.36.191.219]) by smtp.gmail.com with ESMTPSA id x107sm1557951wrb.97.2018.03.13.15.48.33 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 15:48:34 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 13 Mar 2018 23:47:10 +0100 Message-Id: <20180313224719.4954-61-pbonzini@redhat.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313224719.4954-1-pbonzini@redhat.com> References: <20180313224719.4954-1-pbonzini@redhat.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::243 Subject: [Qemu-devel] [PULL 60/69] replay: make locking visible outside replay code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée The replay_mutex_lock/unlock/locked functions are now going to be used for ensuring lock-step behaviour between the two threads. Make them public API functions and also provide stubs for non-QEMU builds on common paths. Signed-off-by: Alex Bennée Signed-off-by: Pavel Dovgalyuk Message-Id: <20180227095242.1060.16601.stgit@pasha-VirtualBox> Signed-off-by: Paolo Bonzini --- include/sysemu/replay.h | 13 +++++++++++++ replay/replay-internal.c | 2 +- replay/replay-internal.h | 6 +++--- stubs/replay.c | 8 ++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) -- 2.14.3 diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 401de12130..3ced6bc231 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -48,6 +48,19 @@ extern ReplayMode replay_mode; /* Name of the initial VM snapshot */ extern char *replay_snapshot; +/* Replay locking + * + * The locks are needed to protect the shared structures and log file + * when doing record/replay. They also are the main sync-point between + * the main-loop thread and the vCPU thread. This was a role + * previously filled by the BQL which has been busy trying to reduce + * its impact across the code. This ensures blocks of events stay + * sequential and reproducible. + */ + +void replay_mutex_lock(void); +void replay_mutex_unlock(void); + /* Replay process control functions */ /*! Enables recording or saving event log with specified parameters */ diff --git a/replay/replay-internal.c b/replay/replay-internal.c index 0d7e1d6bc4..7cdefeaa04 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -181,7 +181,7 @@ void replay_mutex_destroy(void) qemu_mutex_destroy(&lock); } -static bool replay_mutex_locked(void) +bool replay_mutex_locked(void) { return replay_locked; } diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 8e4c701751..41eee66e9b 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -100,12 +100,12 @@ int64_t replay_get_qword(void); void replay_get_array(uint8_t *buf, size_t *size); void replay_get_array_alloc(uint8_t **buf, size_t *size); -/* Mutex functions for protecting replay log file */ +/* Mutex functions for protecting replay log file and ensuring + * synchronisation between vCPU and main-loop threads. */ void replay_mutex_init(void); void replay_mutex_destroy(void); -void replay_mutex_lock(void); -void replay_mutex_unlock(void); +bool replay_mutex_locked(void); /*! Checks error status of the file. */ void replay_check_error(void); diff --git a/stubs/replay.c b/stubs/replay.c index 9c8aa48c9c..04279abb2c 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -72,3 +72,11 @@ uint64_t blkreplay_next_id(void) { return 0; } + +void replay_mutex_lock(void) +{ +} + +void replay_mutex_unlock(void) +{ +} From patchwork Tue Mar 13 22:47:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 131538 Delivered-To: patch@linaro.org Received: by 10.46.84.17 with SMTP id i17csp176483ljb; Tue, 13 Mar 2018 16:35:36 -0700 (PDT) X-Google-Smtp-Source: AG47ELte2+4DieQ7Ce5cI/RlXOhx/qrWs5E30wld+mTsKJdzFW4s+ygR0NSpN4/yCCFM5qC4pEsK X-Received: by 10.237.55.71 with SMTP id i65mr4080371qtb.27.1520984136073; Tue, 13 Mar 2018 16:35:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1520984136; cv=none; d=google.com; s=arc-20160816; b=lrOrok8WV/uQNJDY4BmXnxbfp/SqVQjPUzsCz1F9niVVQOazyyQhPxbYBTlIprv33j bMzTF9NVKHKY2mscLmsS7LZ9YUYOTUV+jGQdv/6OHuVHInquBvIrwcVWNtaMZ/b4pSBG IsT4+X8QuGSe0TMs3U79eu6B/7OEk1KUHiID+N4OnkIDxzwpjSxuPw3AvhJZzL2o61yd e9ovBWfdljAc3N3Af143bb9KHrR1mIMwvwyt16lCqhdlwsX7FLGi8fQ2Jxb9EqxL7ReU 3LeRkuBv0tFM9KkJxxRbEwT5eegpgZClqVC/P1PvFTIyMn4waUeO8XUP5GtlUiP39jnU 7IcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=fgYiUTid+XNCv/a+4jIL7xv2lGthhnQtJJPPnG39TFs=; b=WPwMDNIK6uSKm0nd4jt0yjmiLbCPVJ30DareVargOdRsscvw6z+Gr45zM/6W9M+iXH N9GFictYRoMcQqw/n1A6HC9Po+AMUDDcrxTr1+4VFmUQLCTazwiyPd0KUJ6hyyhzqEAD P3ZshdG4Z890PijPs1VWFcKmoce0sTw6AJVWQvsPD/34fAgNYFtoND71HZnarL4Z1qRn evq8yOux5gQiqf/c3GXlejt3OV2jXs+EuI6+TuQRIBC3VmwbbAcksVl7X1RHE/Y56C0p nE5cIslWu6+cgXphM2AO5dZpOtk6Ti1xF0J1U8aAoViykY5ciokQoHS23sGh2pWGxP3f DA+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=uMcxXLea; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id m39si964177qkh.445.2018.03.13.16.35.35 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 13 Mar 2018 16:35:36 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=uMcxXLea; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from localhost ([::1]:43543 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evtSB-00054Z-Dm for patch@linaro.org; Tue, 13 Mar 2018 19:35:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58772) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evsip-0006TL-R4 for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evsil-0004C7-T6 for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:43 -0400 Received: from mail-wm0-x241.google.com ([2a00:1450:400c:c09::241]:38151) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1evsil-0004Bj-GW for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:39 -0400 Received: by mail-wm0-x241.google.com with SMTP id z9so880786wmb.3 for ; Tue, 13 Mar 2018 15:48:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fgYiUTid+XNCv/a+4jIL7xv2lGthhnQtJJPPnG39TFs=; b=uMcxXLea/tOy5hcyJ8o9aDBHg1nEkbn8RIBLZZY+zPv+lOyAHY6ySjEgmWUfdkPlv+ T6SKzAEl4C8GWOKE7teiHlcoek73ML3kqExhXA9148OobldX61PJC0Omu6awmq5FhTIt D3Durcu+LuKnt+sQ/RmPgjXitVGML19JRnnC/Zzfdh/G9DCopvKl2r23dhemXpFqRlMT qrn7sv7fwMqgmAnsAhDLioAbXQsGNsPuISNsgE8S+KKERyOtpr2TbmXllOjXuWPZVdK7 Q3wt6xiTrpLQcdgbhrAy0W1Cz80mjlV0cTFo5J6wF8lXO46RdVvhRLL1SXKMCrkCSYg8 L2pg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=fgYiUTid+XNCv/a+4jIL7xv2lGthhnQtJJPPnG39TFs=; b=gfQaOqKQ+JwBuVtp2c2wvAmibG7GKx5TXzrNLoAtBnBv2aTwbHvJmY0gXry2dTCMiE zlUl3WZ8/fZn7T5F1jjbxkfWB5ND7m3whnhJN9/gX967hTKe1SnPtq8rDvHuMVwbuWDU XPdWkbZQ04IfrHnJghpk50KgeO5yZhk+SjYdWY53BGLOthKIVRXOFpLAH2DLR/t3+q3d hI+ejKs8B1R98Zx0YsU5TLXVP2+WpOBHedUadze3gsf7Sw/FKAB6iekXx103aphpiDgz aw4eV2zpNBn0/bDArajpDYgdHKqV0TK8LsfOPWRqEb8WXCEaf2+kB5LaYid2DJeG6t/H Cbrg== X-Gm-Message-State: AElRT7FN6y/j7hvFrnF0bAZqsIyyJeknwCyyiCrvBTxEqAcRjGrGPJSf 29ktAQgDaXyZEDmD2SLFX3Zfuz4P X-Received: by 10.28.74.199 with SMTP id n68mr2087038wmi.83.1520981317854; Tue, 13 Mar 2018 15:48:37 -0700 (PDT) Received: from donizetti.lan (94-36-191-219.adsl-ull.clienti.tiscali.it. [94.36.191.219]) by smtp.gmail.com with ESMTPSA id x107sm1557951wrb.97.2018.03.13.15.48.35 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 15:48:37 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 13 Mar 2018 23:47:12 +0100 Message-Id: <20180313224719.4954-63-pbonzini@redhat.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313224719.4954-1-pbonzini@redhat.com> References: <20180313224719.4954-1-pbonzini@redhat.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::241 Subject: [Qemu-devel] [PULL 62/69] replay: push replay_mutex_lock up the call tree X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée Now instead of using the replay_lock to guard the output of the log we now use it to protect the whole execution section. This replaces what the BQL used to do when it was held during TCG execution. We also introduce some rules for locking order - mainly that you cannot take the replay_mutex while holding the BQL. This leads to some slight sophistry during start-up and extending the replay_mutex_destroy function to unlock the mutex without checking for the BQL condition so it can be cleanly dropped in the non-replay case. Signed-off-by: Alex Bennée Signed-off-by: Pavel Dovgalyuk Tested-by: Pavel Dovgalyuk Message-Id: <20180227095248.1060.40374.stgit@pasha-VirtualBox> Signed-off-by: Paolo Bonzini Signed-off-by: Alex Bennée --- cpus.c | 24 ++++++++++++++++++++++-- docs/replay.txt | 22 ++++++++++++++++++++++ replay/replay-audio.c | 14 ++++---------- replay/replay-char.c | 21 ++++++++------------- replay/replay-events.c | 20 +++++++------------- replay/replay-internal.c | 24 ++++++++++++++++-------- replay/replay-time.c | 10 +++++----- replay/replay.c | 34 +++++++++++++--------------------- util/main-loop.c | 15 +++++++++++---- vl.c | 1 + 10 files changed, 109 insertions(+), 76 deletions(-) -- 2.14.3 diff --git a/cpus.c b/cpus.c index c652da84cf..2e6701795b 100644 --- a/cpus.c +++ b/cpus.c @@ -1317,6 +1317,8 @@ static void prepare_icount_for_run(CPUState *cpu) insns_left = MIN(0xffff, cpu->icount_budget); cpu->icount_decr.u16.low = insns_left; cpu->icount_extra = cpu->icount_budget - insns_left; + + replay_mutex_lock(); } } @@ -1332,6 +1334,8 @@ static void process_icount_data(CPUState *cpu) cpu->icount_budget = 0; replay_account_executed_instructions(); + + replay_mutex_unlock(); } } @@ -1346,11 +1350,9 @@ static int tcg_cpu_exec(CPUState *cpu) #ifdef CONFIG_PROFILER ti = profile_getclock(); #endif - qemu_mutex_unlock_iothread(); cpu_exec_start(cpu); ret = cpu_exec(cpu); cpu_exec_end(cpu); - qemu_mutex_lock_iothread(); #ifdef CONFIG_PROFILER tcg_time += profile_getclock() - ti; #endif @@ -1417,6 +1419,9 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) cpu->exit_request = 1; while (1) { + qemu_mutex_unlock_iothread(); + replay_mutex_lock(); + qemu_mutex_lock_iothread(); /* Account partial waits to QEMU_CLOCK_VIRTUAL. */ qemu_account_warp_timer(); @@ -1425,6 +1430,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) */ handle_icount_deadline(); + replay_mutex_unlock(); + if (!cpu) { cpu = first_cpu; } @@ -1440,11 +1447,13 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) if (cpu_can_run(cpu)) { int r; + qemu_mutex_unlock_iothread(); prepare_icount_for_run(cpu); r = tcg_cpu_exec(cpu); process_icount_data(cpu); + qemu_mutex_lock_iothread(); if (r == EXCP_DEBUG) { cpu_handle_guest_debug(cpu); @@ -1634,7 +1643,9 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) while (1) { if (cpu_can_run(cpu)) { int r; + qemu_mutex_unlock_iothread(); r = tcg_cpu_exec(cpu); + qemu_mutex_lock_iothread(); switch (r) { case EXCP_DEBUG: cpu_handle_guest_debug(cpu); @@ -1781,12 +1792,21 @@ void pause_all_vcpus(void) } } + /* We need to drop the replay_lock so any vCPU threads woken up + * can finish their replay tasks + */ + replay_mutex_unlock(); + while (!all_vcpus_paused()) { qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex); CPU_FOREACH(cpu) { qemu_cpu_kick(cpu); } } + + qemu_mutex_unlock_iothread(); + replay_mutex_lock(); + qemu_mutex_lock_iothread(); } void cpu_resume(CPUState *cpu) diff --git a/docs/replay.txt b/docs/replay.txt index c52407fe23..959633e7ea 100644 --- a/docs/replay.txt +++ b/docs/replay.txt @@ -49,6 +49,28 @@ Modifications of qemu include: * recording/replaying user input (mouse and keyboard) * adding internal checkpoints for cpu and io synchronization +Locking and thread synchronisation +---------------------------------- + +Previously the synchronisation of the main thread and the vCPU thread +was ensured by the holding of the BQL. However the trend has been to +reduce the time the BQL was held across the system including under TCG +system emulation. As it is important that batches of events are kept +in sequence (e.g. expiring timers and checkpoints in the main thread +while instruction checkpoints are written by the vCPU thread) we need +another lock to keep things in lock-step. This role is now handled by +the replay_mutex_lock. It used to be held only for each event being +written but now it is held for a whole execution period. This results +in a deterministic ping-pong between the two main threads. + +As the BQL is now a finer grained lock than the replay_lock it is almost +certainly a bug, and a source of deadlocks, to take the +replay_mutex_lock while the BQL is held. This is enforced by an assert. +While the unlocks are usually in the reverse order, this is not +necessary; you can drop the replay_lock while holding the BQL, without +doing a more complicated unlock_iothread/replay_unlock/lock_iothread +sequence. + Non-deterministic events ------------------------ diff --git a/replay/replay-audio.c b/replay/replay-audio.c index 3d837434d4..b113836de4 100644 --- a/replay/replay-audio.c +++ b/replay/replay-audio.c @@ -19,20 +19,17 @@ void replay_audio_out(int *played) { if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_AUDIO_OUT); replay_put_dword(*played); - replay_mutex_unlock(); } else if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); replay_account_executed_instructions(); - replay_mutex_lock(); if (replay_next_event_is(EVENT_AUDIO_OUT)) { *played = replay_get_dword(); replay_finish_event(); - replay_mutex_unlock(); } else { - replay_mutex_unlock(); error_report("Missing audio out event in the replay log"); abort(); } @@ -44,8 +41,8 @@ void replay_audio_in(int *recorded, void *samples, int *wpos, int size) int pos; uint64_t left, right; if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_AUDIO_IN); replay_put_dword(*recorded); replay_put_dword(*wpos); @@ -55,10 +52,9 @@ void replay_audio_in(int *recorded, void *samples, int *wpos, int size) replay_put_qword(left); replay_put_qword(right); } - replay_mutex_unlock(); } else if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); replay_account_executed_instructions(); - replay_mutex_lock(); if (replay_next_event_is(EVENT_AUDIO_IN)) { *recorded = replay_get_dword(); *wpos = replay_get_dword(); @@ -69,9 +65,7 @@ void replay_audio_in(int *recorded, void *samples, int *wpos, int size) audio_sample_from_uint64(samples, pos, left, right); } replay_finish_event(); - replay_mutex_unlock(); } else { - replay_mutex_unlock(); error_report("Missing audio in event in the replay log"); abort(); } diff --git a/replay/replay-char.c b/replay/replay-char.c index cbf7c04a9f..736cc8c2e6 100755 --- a/replay/replay-char.c +++ b/replay/replay-char.c @@ -96,25 +96,24 @@ void *replay_event_char_read_load(void) void replay_char_write_event_save(int res, int offset) { + g_assert(replay_mutex_locked()); + replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_WRITE); replay_put_dword(res); replay_put_dword(offset); - replay_mutex_unlock(); } void replay_char_write_event_load(int *res, int *offset) { + g_assert(replay_mutex_locked()); + replay_account_executed_instructions(); - replay_mutex_lock(); if (replay_next_event_is(EVENT_CHAR_WRITE)) { *res = replay_get_dword(); *offset = replay_get_dword(); replay_finish_event(); - replay_mutex_unlock(); } else { - replay_mutex_unlock(); error_report("Missing character write event in the replay log"); exit(1); } @@ -122,23 +121,21 @@ void replay_char_write_event_load(int *res, int *offset) int replay_char_read_all_load(uint8_t *buf) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + if (replay_next_event_is(EVENT_CHAR_READ_ALL)) { size_t size; int res; replay_get_array(buf, &size); replay_finish_event(); - replay_mutex_unlock(); res = (int)size; assert(res >= 0); return res; } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR)) { int res = replay_get_dword(); replay_finish_event(); - replay_mutex_unlock(); return res; } else { - replay_mutex_unlock(); error_report("Missing character read all event in the replay log"); exit(1); } @@ -146,19 +143,17 @@ int replay_char_read_all_load(uint8_t *buf) void replay_char_read_all_save_error(int res) { + g_assert(replay_mutex_locked()); assert(res < 0); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_READ_ALL_ERROR); replay_put_dword(res); - replay_mutex_unlock(); } void replay_char_read_all_save_buf(uint8_t *buf, int offset) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_READ_ALL); replay_put_array(buf, offset); - replay_mutex_unlock(); } diff --git a/replay/replay-events.c b/replay/replay-events.c index e858254074..54dd9d2606 100644 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -79,16 +79,14 @@ bool replay_has_events(void) void replay_flush_events(void) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } - replay_mutex_unlock(); } void replay_disable_events(void) @@ -102,14 +100,14 @@ void replay_disable_events(void) void replay_clear_events(void) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } - replay_mutex_unlock(); } /*! Adds specified async event to the queue */ @@ -136,9 +134,8 @@ void replay_add_event(ReplayAsyncEventKind event_kind, event->opaque2 = opaque2; event->id = id; - replay_mutex_lock(); + g_assert(replay_mutex_locked()); QTAILQ_INSERT_TAIL(&events_list, event, events); - replay_mutex_unlock(); } void replay_bh_schedule_event(QEMUBH *bh) @@ -207,13 +204,11 @@ static void replay_save_event(Event *event, int checkpoint) /* Called with replay mutex locked */ void replay_save_events(int checkpoint) { + g_assert(replay_mutex_locked()); while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); replay_save_event(event, checkpoint); - - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } @@ -292,6 +287,7 @@ static Event *replay_read_event(int checkpoint) /* Called with replay mutex locked */ void replay_read_events(int checkpoint) { + g_assert(replay_mutex_locked()); while (replay_state.data_kind == EVENT_ASYNC) { Event *event = replay_read_event(checkpoint); if (!event) { @@ -299,9 +295,7 @@ void replay_read_events(int checkpoint) } replay_finish_event(); read_event_kind = -1; - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); g_free(event); } diff --git a/replay/replay-internal.c b/replay/replay-internal.c index fa7bba6dfd..8e7474f787 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -174,6 +174,9 @@ static __thread bool replay_locked; void replay_mutex_init(void) { qemu_mutex_init(&lock); + /* Hold the mutex while we start-up */ + qemu_mutex_lock(&lock); + replay_locked = true; } bool replay_mutex_locked(void) @@ -181,25 +184,31 @@ bool replay_mutex_locked(void) return replay_locked; } +/* Ordering constraints, replay_lock must be taken before BQL */ void replay_mutex_lock(void) { - g_assert(!replay_mutex_locked()); - qemu_mutex_lock(&lock); - replay_locked = true; + if (replay_mode != REPLAY_MODE_NONE) { + g_assert(!qemu_mutex_iothread_locked()); + g_assert(!replay_mutex_locked()); + qemu_mutex_lock(&lock); + replay_locked = true; + } } void replay_mutex_unlock(void) { - g_assert(replay_mutex_locked()); - replay_locked = false; - qemu_mutex_unlock(&lock); + if (replay_mode != REPLAY_MODE_NONE) { + g_assert(replay_mutex_locked()); + replay_locked = false; + qemu_mutex_unlock(&lock); + } } /*! Saves cached instructions. */ void replay_save_instructions(void) { if (replay_file && replay_mode == REPLAY_MODE_RECORD) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); int diff = (int)(replay_get_current_step() - replay_state.current_step); /* Time can only go forward */ @@ -210,6 +219,5 @@ void replay_save_instructions(void) replay_put_dword(diff); replay_state.current_step += diff; } - replay_mutex_unlock(); } } diff --git a/replay/replay-time.c b/replay/replay-time.c index f70382a88f..6a7565ec8d 100644 --- a/replay/replay-time.c +++ b/replay/replay-time.c @@ -17,13 +17,13 @@ int64_t replay_save_clock(ReplayClockKind kind, int64_t clock) { - replay_save_instructions(); if (replay_file) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + + replay_save_instructions(); replay_put_event(EVENT_CLOCK + kind); replay_put_qword(clock); - replay_mutex_unlock(); } return clock; @@ -46,16 +46,16 @@ void replay_read_next_clock(ReplayClockKind kind) /*! Reads next clock event from the input. */ int64_t replay_read_clock(ReplayClockKind kind) { + g_assert(replay_file && replay_mutex_locked()); + replay_account_executed_instructions(); if (replay_file) { int64_t ret; - replay_mutex_lock(); if (replay_next_event_is(EVENT_CLOCK + kind)) { replay_read_next_clock(kind); } ret = replay_state.cached_clock[kind]; - replay_mutex_unlock(); return ret; } diff --git a/replay/replay.c b/replay/replay.c index 5d05ee0460..90f98b7490 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -81,7 +81,7 @@ int replay_get_instructions(void) void replay_account_executed_instructions(void) { if (replay_mode == REPLAY_MODE_PLAY) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); if (replay_state.instructions_count > 0) { int count = (int)(replay_get_current_step() - replay_state.current_step); @@ -100,24 +100,22 @@ void replay_account_executed_instructions(void) qemu_notify_event(); } } - replay_mutex_unlock(); } } bool replay_exception(void) { + if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_EXCEPTION); - replay_mutex_unlock(); return true; } else if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); bool res = replay_has_exception(); if (res) { - replay_mutex_lock(); replay_finish_event(); - replay_mutex_unlock(); } return res; } @@ -129,10 +127,9 @@ bool replay_has_exception(void) { bool res = false; if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); replay_account_executed_instructions(); - replay_mutex_lock(); res = replay_next_event_is(EVENT_EXCEPTION); - replay_mutex_unlock(); } return res; @@ -141,17 +138,15 @@ bool replay_has_exception(void) bool replay_interrupt(void) { if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_INTERRUPT); - replay_mutex_unlock(); return true; } else if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); bool res = replay_has_interrupt(); if (res) { - replay_mutex_lock(); replay_finish_event(); - replay_mutex_unlock(); } return res; } @@ -163,10 +158,9 @@ bool replay_has_interrupt(void) { bool res = false; if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); replay_account_executed_instructions(); - replay_mutex_lock(); res = replay_next_event_is(EVENT_INTERRUPT); - replay_mutex_unlock(); } return res; } @@ -174,9 +168,8 @@ bool replay_has_interrupt(void) void replay_shutdown_request(ShutdownCause cause) { if (replay_mode == REPLAY_MODE_RECORD) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); replay_put_event(EVENT_SHUTDOWN + cause); - replay_mutex_unlock(); } } @@ -190,9 +183,9 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint) return true; } - replay_mutex_lock(); if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); if (replay_next_event_is(EVENT_CHECKPOINT + checkpoint)) { replay_finish_event(); } else if (replay_state.data_kind != EVENT_ASYNC) { @@ -205,12 +198,12 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint) checkpoint were processed */ res = replay_state.data_kind != EVENT_ASYNC; } else if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_put_event(EVENT_CHECKPOINT + checkpoint); replay_save_events(checkpoint); res = true; } out: - replay_mutex_unlock(); return res; } @@ -233,8 +226,6 @@ static void replay_enable(const char *fname, int mode) atexit(replay_finish); - replay_mutex_init(); - replay_file = fopen(fname, fmode); if (replay_file == NULL) { fprintf(stderr, "Replay: open %s: %s\n", fname, strerror(errno)); @@ -242,8 +233,9 @@ static void replay_enable(const char *fname, int mode) } replay_filename = g_strdup(fname); - replay_mode = mode; + replay_mutex_init(); + replay_state.data_kind = -1; replay_state.instructions_count = 0; replay_state.current_step = 0; diff --git a/util/main-loop.c b/util/main-loop.c index 7558eb5f53..992f9b0f34 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -29,6 +29,7 @@ #include "qemu/sockets.h" // struct in_addr needed for libslirp.h #include "sysemu/qtest.h" #include "sysemu/cpus.h" +#include "sysemu/replay.h" #include "slirp/libslirp.h" #include "qemu/main-loop.h" #include "block/aio.h" @@ -245,18 +246,19 @@ static int os_host_main_loop_wait(int64_t timeout) timeout = SCALE_MS; } + if (timeout) { spin_counter = 0; - qemu_mutex_unlock_iothread(); } else { spin_counter++; } + qemu_mutex_unlock_iothread(); + replay_mutex_unlock(); ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout); - if (timeout) { - qemu_mutex_lock_iothread(); - } + replay_mutex_lock(); + qemu_mutex_lock_iothread(); glib_pollfds_poll(); @@ -463,8 +465,13 @@ static int os_host_main_loop_wait(int64_t timeout) poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout); qemu_mutex_unlock_iothread(); + + replay_mutex_unlock(); + g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns); + replay_mutex_lock(); + qemu_mutex_lock_iothread(); if (g_poll_ret > 0) { for (i = 0; i < w->num; i++) { diff --git a/vl.c b/vl.c index e81152417a..5925a4b502 100644 --- a/vl.c +++ b/vl.c @@ -3058,6 +3058,7 @@ int main(int argc, char **argv, char **envp) qemu_init_cpu_list(); qemu_init_cpu_loop(); + qemu_mutex_lock_iothread(); atexit(qemu_run_exit_notifiers); From patchwork Tue Mar 13 22:47:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 131539 Delivered-To: patch@linaro.org Received: by 10.46.84.17 with SMTP id i17csp177219ljb; Tue, 13 Mar 2018 16:36:40 -0700 (PDT) X-Google-Smtp-Source: AG47ELutAkw8RhPpA4sOjIDUZPjbUtAeFpKHXnGkCkisKGiiDVJ/NBKEp8V+k5/X76AqANSFMLQf X-Received: by 10.55.239.26 with SMTP id j26mr3795848qkk.315.1520984200334; Tue, 13 Mar 2018 16:36:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1520984200; cv=none; d=google.com; s=arc-20160816; b=SKAxVgp9yJQ8OkrHCf09QsNmoevIeUh8cwa2H14yR4BaWro9R8F5b3rZMN8eI0epe2 3Hl0SUfuifF4sIGSa4ooBqOaE6yJoND01zA9kblwsQ2+GVcnF2zTsEUzb7eCswcdAUPS xfrR4TfB4mQ8J6RGHAza6E5DC3pgx3sSsJHaM0kmvYjBOmZBk5IOBaq8VCCgRBPtIn2d 5vXQUM/4OeoIOftaF4e8PaLmJRkDaHA3+RVCYaKnUnTETobRXah10DayN7ARVgwF6VKS gCDgjyeUjj3qYR4yuq3bdR4VqQEQ52ZkSnVhD21iRHmJW1t8oF1HLH06PYRrnFZgGAYZ U+rg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=4Vlrd7SbMe43nB+/halXfcomflyEBlE8n2JZ+Snr2Jg=; b=ZkeN5okgAhYs6BEyus6hgBquIVT2FOgaFGDGoMdG4vCmtamelLe6h9gSuZLCxaJaQt VvebOMC5II4dfIHxNWY9sFOPGW4fK/N2C3APFP3oWNm6YtYyp2eSC+9d2spviRZEhCWD RtotcJdm8RzQbyAyu4a0gUuKWS0XHmkMX4YUG7EdXyxm1sDXnSmYb+Slcbjddxl+SyIH C/F98GuJBXsZv8EYTfiZIrrGzrDfC7gg9D6FCh6p1+jyx5wRx7Bgs2B8ezsoYsSmWYm8 OPgXcdyV5wELLgXKypR5Kq6b4/MXmi+wh/gH3YmCgfiHJPzakvpc/K3q8Gbxjr6uOrTA xbPg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=i8+7cD65; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id p57si1447856qtf.335.2018.03.13.16.36.40 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 13 Mar 2018 16:36:40 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=i8+7cD65; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from localhost ([::1]:43550 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evtTD-0005yS-OC for patch@linaro.org; Tue, 13 Mar 2018 19:36:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58809) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evsir-0006Up-90 for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evsip-0004Eu-CR for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:45 -0400 Received: from mail-wr0-x234.google.com ([2a00:1450:400c:c0c::234]:35976) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1evsip-0004EG-1P for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:48:43 -0400 Received: by mail-wr0-x234.google.com with SMTP id d10so2573276wrf.3 for ; Tue, 13 Mar 2018 15:48:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=4Vlrd7SbMe43nB+/halXfcomflyEBlE8n2JZ+Snr2Jg=; b=i8+7cD65lAhNKWvXqTodXfJWwQu0QoQFhqHxsPTVegK02NlB7n5wyYexd5qZ/FtBRx QiFo+VTIu1kTXyEt3T0eWBdcy0Iop0H9/8hKYl6fwlSE8tHfSNEOqBHUtuvkFvOOlRdY RcuPxwLL3OppLKfo03spP6TfHpxakOEnF8JWndYCEuBzftoet4FHcreXkjZ9klmbE1iv Uq2kcNuhpApgu7ZRzyhiCAioYcMmhOlZJH6njIJ3JW1LNRKXP650gcCuWwOHxcFWJeBH vCxjGsOk/iutXNm5Es3TyfuG5ihtY9nQLloiMjdNlU5t4I5PVxXWQNpGW/JibRsN/sJ7 T/fw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=4Vlrd7SbMe43nB+/halXfcomflyEBlE8n2JZ+Snr2Jg=; b=qc0V0UjCp4VqLXwE4S6kVsFs8O03NfMFA9iJuNWbyRpQxYZEzvoIBmWF7ev72KvFTl 07oEVbr8Ltux8Y51ROzOQrFSirm83i1/wmVVRhhyCEjbiIlcsCdChYtiLZHPlKADez4P f4p4QRl0bnvNYwvEG8EJeVDD0pTdze0tykwVAQ6SokkLv+Prroyke7Qlr6ztDIAN2uz3 I4D6henD3klf65Q/gM0YOBfX6p2qdqv2YOl4Wy83V2uHVRiB6//EzBZIarz3vgstpQql krzDEWQpjw4Y7bV11naLUTwWi1DW+m5Vd0gL4D7Q/uUOx06uPuSB+9T0sV8GYutoIJ6Q t6+Q== X-Gm-Message-State: AElRT7EYLfQjvbog3p6PEV3JAMWjpyGXzfuAhZFJ/BzROR86HfkX2dbs qtm2SWllZlfq5NxGyiZraBeOrk5c X-Received: by 10.223.176.237 with SMTP id j42mr1939890wra.25.1520981321487; Tue, 13 Mar 2018 15:48:41 -0700 (PDT) Received: from donizetti.lan (94-36-191-219.adsl-ull.clienti.tiscali.it. [94.36.191.219]) by smtp.gmail.com with ESMTPSA id x107sm1557951wrb.97.2018.03.13.15.48.40 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 15:48:40 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 13 Mar 2018 23:47:15 +0100 Message-Id: <20180313224719.4954-66-pbonzini@redhat.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313224719.4954-1-pbonzini@redhat.com> References: <20180313224719.4954-1-pbonzini@redhat.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::234 Subject: [Qemu-devel] [PULL 65/69] scripts/replay-dump.py: replay log dumper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This script is a debugging tool for looking through the contents of a replay log file. It is incomplete but should fail gracefully at events it doesn't understand. It currently understands two different log formats as the audio record/replay support was merged during since MTTCG. It was written to help debug what has caused the BQL changes to break replay support. Signed-off-by: Alex Bennée Message-Id: <20180227095310.1060.14500.stgit@pasha-VirtualBox> Signed-off-by: Paolo Bonzini --- scripts/replay-dump.py | 308 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100755 scripts/replay-dump.py -- 2.14.3 diff --git a/scripts/replay-dump.py b/scripts/replay-dump.py new file mode 100755 index 0000000000..e274086277 --- /dev/null +++ b/scripts/replay-dump.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Dump the contents of a recorded execution stream +# +# Copyright (c) 2017 Alex Bennée +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see . + +import argparse +import struct +from collections import namedtuple + +# This mirrors some of the global replay state which some of the +# stream loading refers to. Some decoders may read the next event so +# we need handle that case. Calling reuse_event will ensure the next +# event is read from the cache rather than advancing the file. + +class ReplayState(object): + def __init__(self): + self.event = -1 + self.event_count = 0 + self.already_read = False + self.current_checkpoint = 0 + self.checkpoint = 0 + + def set_event(self, ev): + self.event = ev + self.event_count += 1 + + def get_event(self): + self.already_read = False + return self.event + + def reuse_event(self, ev): + self.event = ev + self.already_read = True + + def set_checkpoint(self): + self.checkpoint = self.event - self.checkpoint_start + + def get_checkpoint(self): + return self.checkpoint + +replay_state = ReplayState() + +# Simple read functions that mirror replay-internal.c +# The file-stream is big-endian and manually written out a byte at a time. + +def read_byte(fin): + "Read a single byte" + return struct.unpack('>B', fin.read(1))[0] + +def read_event(fin): + "Read a single byte event, but save some state" + if replay_state.already_read: + return replay_state.get_event() + else: + replay_state.set_event(read_byte(fin)) + return replay_state.event + +def read_word(fin): + "Read a 16 bit word" + return struct.unpack('>H', fin.read(2))[0] + +def read_dword(fin): + "Read a 32 bit word" + return struct.unpack('>I', fin.read(4))[0] + +def read_qword(fin): + "Read a 64 bit word" + return struct.unpack('>Q', fin.read(8))[0] + +# Generic decoder structure +Decoder = namedtuple("Decoder", "eid name fn") + +def call_decode(table, index, dumpfile): + "Search decode table for next step" + decoder = next((d for d in table if d.eid == index), None) + if not decoder: + print "Could not decode index: %d" % (index) + print "Entry is: %s" % (decoder) + print "Decode Table is:\n%s" % (table) + return False + else: + return decoder.fn(decoder.eid, decoder.name, dumpfile) + +# Print event +def print_event(eid, name, string=None, event_count=None): + "Print event with count" + if not event_count: + event_count = replay_state.event_count + + if string: + print "%d:%s(%d) %s" % (event_count, name, eid, string) + else: + print "%d:%s(%d)" % (event_count, name, eid) + + +# Decoders for each event type + +def decode_unimp(eid, name, _unused_dumpfile): + "Unimplimented decoder, will trigger exit" + print "%s not handled - will now stop" % (name) + return False + +# Checkpoint decoder +def swallow_async_qword(eid, name, dumpfile): + "Swallow a qword of data without looking at it" + step_id = read_qword(dumpfile) + print " %s(%d) @ %d" % (name, eid, step_id) + return True + +async_decode_table = [ Decoder(0, "REPLAY_ASYNC_EVENT_BH", swallow_async_qword), + Decoder(1, "REPLAY_ASYNC_INPUT", decode_unimp), + Decoder(2, "REPLAY_ASYNC_INPUT_SYNC", decode_unimp), + Decoder(3, "REPLAY_ASYNC_CHAR_READ", decode_unimp), + Decoder(4, "REPLAY_ASYNC_EVENT_BLOCK", decode_unimp), + Decoder(5, "REPLAY_ASYNC_EVENT_NET", decode_unimp), +] +# See replay_read_events/replay_read_event +def decode_async(eid, name, dumpfile): + """Decode an ASYNC event""" + + print_event(eid, name) + + async_event_kind = read_byte(dumpfile) + async_event_checkpoint = read_byte(dumpfile) + + if async_event_checkpoint != replay_state.current_checkpoint: + print " mismatch between checkpoint %d and async data %d" % ( + replay_state.current_checkpoint, async_event_checkpoint) + return True + + return call_decode(async_decode_table, async_event_kind, dumpfile) + + +def decode_instruction(eid, name, dumpfile): + ins_diff = read_dword(dumpfile) + print_event(eid, name, "0x%x" % (ins_diff)) + return True + +def decode_audio_out(eid, name, dumpfile): + audio_data = read_dword(dumpfile) + print_event(eid, name, "%d" % (audio_data)) + return True + +def decode_checkpoint(eid, name, dumpfile): + """Decode a checkpoint. + + Checkpoints contain a series of async events with their own specific data. + """ + replay_state.set_checkpoint() + # save event count as we peek ahead + event_number = replay_state.event_count + next_event = read_event(dumpfile) + + # if the next event is EVENT_ASYNC there are a bunch of + # async events to read, otherwise we are done + if next_event != 3: + print_event(eid, name, "no additional data", event_number) + else: + print_event(eid, name, "more data follows", event_number) + + replay_state.reuse_event(next_event) + return True + +def decode_checkpoint_init(eid, name, dumpfile): + print_event(eid, name) + return True + +def decode_interrupt(eid, name, dumpfile): + print_event(eid, name) + return True + +def decode_clock(eid, name, dumpfile): + clock_data = read_qword(dumpfile) + print_event(eid, name, "0x%x" % (clock_data)) + return True + + +# pre-MTTCG merge +v5_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), + Decoder(1, "EVENT_INTERRUPT", decode_interrupt), + Decoder(2, "EVENT_EXCEPTION", decode_unimp), + Decoder(3, "EVENT_ASYNC", decode_async), + Decoder(4, "EVENT_SHUTDOWN", decode_unimp), + Decoder(5, "EVENT_CHAR_WRITE", decode_unimp), + Decoder(6, "EVENT_CHAR_READ_ALL", decode_unimp), + Decoder(7, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), + Decoder(8, "EVENT_CLOCK_HOST", decode_clock), + Decoder(9, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), + Decoder(10, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), + Decoder(11, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), + Decoder(12, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), + Decoder(13, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), + Decoder(14, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), + Decoder(15, "EVENT_CP_CLOCK_HOST", decode_checkpoint), + Decoder(16, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), + Decoder(17, "EVENT_CP_INIT", decode_checkpoint_init), + Decoder(18, "EVENT_CP_RESET", decode_checkpoint), +] + +# post-MTTCG merge, AUDIO support added +v6_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), + Decoder(1, "EVENT_INTERRUPT", decode_interrupt), + Decoder(2, "EVENT_EXCEPTION", decode_unimp), + Decoder(3, "EVENT_ASYNC", decode_async), + Decoder(4, "EVENT_SHUTDOWN", decode_unimp), + Decoder(5, "EVENT_CHAR_WRITE", decode_unimp), + Decoder(6, "EVENT_CHAR_READ_ALL", decode_unimp), + Decoder(7, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), + Decoder(8, "EVENT_AUDIO_OUT", decode_audio_out), + Decoder(9, "EVENT_AUDIO_IN", decode_unimp), + Decoder(10, "EVENT_CLOCK_HOST", decode_clock), + Decoder(11, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), + Decoder(12, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), + Decoder(13, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), + Decoder(14, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), + Decoder(15, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), + Decoder(16, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), + Decoder(17, "EVENT_CP_CLOCK_HOST", decode_checkpoint), + Decoder(18, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), + Decoder(19, "EVENT_CP_INIT", decode_checkpoint_init), + Decoder(20, "EVENT_CP_RESET", decode_checkpoint), +] + +# Shutdown cause added +v7_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), + Decoder(1, "EVENT_INTERRUPT", decode_interrupt), + Decoder(2, "EVENT_EXCEPTION", decode_unimp), + Decoder(3, "EVENT_ASYNC", decode_async), + Decoder(4, "EVENT_SHUTDOWN", decode_unimp), + Decoder(5, "EVENT_SHUTDOWN_HOST_ERR", decode_unimp), + Decoder(6, "EVENT_SHUTDOWN_HOST_QMP", decode_unimp), + Decoder(7, "EVENT_SHUTDOWN_HOST_SIGNAL", decode_unimp), + Decoder(8, "EVENT_SHUTDOWN_HOST_UI", decode_unimp), + Decoder(9, "EVENT_SHUTDOWN_GUEST_SHUTDOWN", decode_unimp), + Decoder(10, "EVENT_SHUTDOWN_GUEST_RESET", decode_unimp), + Decoder(11, "EVENT_SHUTDOWN_GUEST_PANIC", decode_unimp), + Decoder(12, "EVENT_SHUTDOWN___MAX", decode_unimp), + Decoder(13, "EVENT_CHAR_WRITE", decode_unimp), + Decoder(14, "EVENT_CHAR_READ_ALL", decode_unimp), + Decoder(15, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), + Decoder(16, "EVENT_AUDIO_OUT", decode_audio_out), + Decoder(17, "EVENT_AUDIO_IN", decode_unimp), + Decoder(18, "EVENT_CLOCK_HOST", decode_clock), + Decoder(19, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), + Decoder(20, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), + Decoder(21, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), + Decoder(22, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), + Decoder(23, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), + Decoder(24, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), + Decoder(25, "EVENT_CP_CLOCK_HOST", decode_checkpoint), + Decoder(26, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), + Decoder(27, "EVENT_CP_INIT", decode_checkpoint_init), + Decoder(28, "EVENT_CP_RESET", decode_checkpoint), +] + +def parse_arguments(): + "Grab arguments for script" + parser = argparse.ArgumentParser() + parser.add_argument("-f", "--file", help='record/replay dump to read from', + required=True) + return parser.parse_args() + +def decode_file(filename): + "Decode a record/replay dump" + dumpfile = open(filename, "rb") + + # read and throwaway the header + version = read_dword(dumpfile) + junk = read_qword(dumpfile) + + print "HEADER: version 0x%x" % (version) + + if version == 0xe02007: + event_decode_table = v7_event_table + replay_state.checkpoint_start = 12 + elif version == 0xe02006: + event_decode_table = v6_event_table + replay_state.checkpoint_start = 12 + else: + event_decode_table = v5_event_table + replay_state.checkpoint_start = 10 + + try: + decode_ok = True + while decode_ok: + event = read_event(dumpfile) + decode_ok = call_decode(event_decode_table, event, dumpfile) + finally: + dumpfile.close() + +if __name__ == "__main__": + args = parse_arguments() + decode_file(args.file)