From patchwork Wed Oct 10 13:33:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981865 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZpY6Ftbz9s8F for ; Thu, 11 Oct 2018 00:35:01 +1100 (AEDT) Received: from localhost ([::1]:57303 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEdf-0003zM-1E for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:34:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33645) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZO-0001YI-Oy for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEZN-0002I1-Vx for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:34 -0400 Received: from mail.ispras.ru ([83.149.199.45]:43882) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZN-0002HS-KU for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:33 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 309D3540089; Wed, 10 Oct 2018 16:30:32 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:33:45 +0300 Message-ID: <20181010133345.24538.84595.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 02/19] replay: disable default snapshot for record/replay 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch disables setting '-snapshot' option on by default in record/replay mode. This is needed for creating vmstates in record and replay modes. Signed-off-by: Pavel Dovgalyuk --- vl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/vl.c b/vl.c index 4e25c78..46238d2 100644 --- a/vl.c +++ b/vl.c @@ -3124,7 +3124,13 @@ int main(int argc, char **argv, char **envp) drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS); break; case QEMU_OPTION_snapshot: - snapshot = 1; + { + Error *blocker = NULL; + snapshot = 1; + error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, + "-snapshot"); + replay_add_blocker(blocker); + } break; case QEMU_OPTION_numa: opts = qemu_opts_parse_noisily(qemu_find_opts("numa"), @@ -4416,7 +4422,7 @@ int main(int argc, char **argv, char **envp) qapi_free_BlockdevOptions(bdo->bdo); g_free(bdo); } - if (snapshot || replay_mode != REPLAY_MODE_NONE) { + if (snapshot) { qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, NULL); } From patchwork Wed Oct 10 13:33:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981864 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZkx56vnz9s8F for ; Thu, 11 Oct 2018 00:31:53 +1100 (AEDT) Received: from localhost ([::1]:57295 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEad-0001hK-3x for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:31:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33711) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZY-0001e2-K5 for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEZT-0002KL-0m for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:44 -0400 Received: from mail.ispras.ru ([83.149.199.45]:43918) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZS-0002Jx-OF for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:38 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id C6345540089; Wed, 10 Oct 2018 16:30:37 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:33:51 +0300 Message-ID: <20181010133351.24538.25271.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 03/19] replay: update docs for record/replay with block devices 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch updates the description of the command lines for using record/replay with attached block devices. Signed-off-by: Pavel Dovgalyuk --- docs/replay.txt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/replay.txt b/docs/replay.txt index 3497585..2c2c5f6 100644 --- a/docs/replay.txt +++ b/docs/replay.txt @@ -27,7 +27,7 @@ Usage of the record/replay: * First, record the execution with the following command line: qemu-system-i386 \ -icount shift=7,rr=record,rrfile=replay.bin \ - -drive file=disk.qcow2,if=none,id=img-direct \ + -drive file=disk.qcow2,if=none,snapshot,id=img-direct \ -drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay \ -device ide-hd,drive=img-blkreplay \ -netdev user,id=net1 -device rtl8139,netdev=net1 \ @@ -35,7 +35,7 @@ Usage of the record/replay: * After recording, you can replay it by using another command line: qemu-system-i386 \ -icount shift=7,rr=replay,rrfile=replay.bin \ - -drive file=disk.qcow2,if=none,id=img-direct \ + -drive file=disk.qcow2,if=none,snapshot,id=img-direct \ -drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay \ -device ide-hd,drive=img-blkreplay \ -netdev user,id=net1 -device rtl8139,netdev=net1 \ @@ -223,7 +223,7 @@ Block devices record/replay module intercepts calls of bdrv coroutine functions at the top of block drivers stack. To record and replay block operations the drive must be configured as following: - -drive file=disk.qcow2,if=none,id=img-direct + -drive file=disk.qcow2,if=none,snapshot,id=img-direct -drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay -device ide-hd,drive=img-blkreplay @@ -252,6 +252,12 @@ This snapshot is created at start of recording and restored at start of replaying. It also can be loaded while replaying to roll back the execution. +'snapshot' flag of the disk image must be removed to save the snapshots +in the overlay (or original image) instead of using the temporary overlay. + -drive file=disk.ovl,if=none,id=img-direct + -drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay + -device ide-hd,drive=img-blkreplay + Use QEMU monitor to create additional snapshots. 'savevm ' command created the snapshot and 'loadvm ' restores it. To prevent corruption of the original disk image, use overlay files linked to the original images. From patchwork Wed Oct 10 13:33:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981866 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZpf2lFjz9s8F for ; Thu, 11 Oct 2018 00:35:06 +1100 (AEDT) Received: from localhost ([::1]:57305 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEdk-000434-15 for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:35:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33728) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZZ-0001ek-GH for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEZY-0002O0-JF for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:45 -0400 Received: from mail.ispras.ru ([83.149.199.45]:43950) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZY-0002Nf-AE for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:44 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 69DB554008A; Wed, 10 Oct 2018 16:30:43 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:33:57 +0300 Message-ID: <20181010133357.24538.19180.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 04/19] replay: don't drain/flush bdrv queue while RR is working 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" In record/replay mode bdrv queue is controlled by replay mechanism. It does not allow saving or loading the snapshots when bdrv queue is not empty. Stopping the VM is not blocked by nonempty queue, but flushing the queue is still impossible there, because it may cause deadlocks in replay mode. This patch disables bdrv_drain_all and bdrv_flush_all in record/replay mode. Signed-off-by: Pavel Dovgalyuk --- block/io.c | 22 ++++++++++++++++++++++ cpus.c | 2 -- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/block/io.c b/block/io.c index bd9d688..96fb245 100644 --- a/block/io.c +++ b/block/io.c @@ -32,6 +32,7 @@ #include "qemu/cutils.h" #include "qapi/error.h" #include "qemu/error-report.h" +#include "sysemu/replay.h" #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ @@ -538,6 +539,13 @@ void bdrv_drain_all_begin(void) return; } + /* bdrv queue is managed by record/replay, + waiting for finishing the I/O requests may + be infinite */ + if (replay_events_enabled()) { + return; + } + /* AIO_WAIT_WHILE() with a NULL context can only be called from the main * loop AioContext, so make sure we're in the main context. */ assert(qemu_get_current_aio_context() == qemu_get_aio_context()); @@ -566,6 +574,13 @@ void bdrv_drain_all_end(void) { BlockDriverState *bs = NULL; + /* bdrv queue is managed by record/replay, + waiting for finishing the I/O requests may + be endless */ + if (replay_events_enabled()) { + return; + } + while ((bs = bdrv_next_all_states(bs))) { AioContext *aio_context = bdrv_get_aio_context(bs); @@ -1997,6 +2012,13 @@ int bdrv_flush_all(void) BlockDriverState *bs = NULL; int result = 0; + /* bdrv queue is managed by record/replay, + creating new flush request for stopping + the VM may break the determinism */ + if (replay_events_enabled()) { + return result; + } + for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { AioContext *aio_context = bdrv_get_aio_context(bs); int ret; diff --git a/cpus.c b/cpus.c index 1c741bc..d60ddf1 100644 --- a/cpus.c +++ b/cpus.c @@ -1078,7 +1078,6 @@ static int do_vm_stop(RunState state, bool send_stop) } bdrv_drain_all(); - replay_disable_events(); ret = bdrv_flush_all(); return ret; @@ -2135,7 +2134,6 @@ int vm_prepare_start(void) /* We are sending this now, but the CPUs will be resumed shortly later */ qapi_event_send_resume(); - replay_enable_events(); cpu_enable_ticks(); runstate_set(RUN_STATE_RUNNING); vm_state_notify(1, RUN_STATE_RUNNING); From patchwork Wed Oct 10 13:34:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981869 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZpt2Zcdz9sB7 for ; Thu, 11 Oct 2018 00:35:18 +1100 (AEDT) Received: from localhost ([::1]:57308 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEdv-0004BD-PO for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:35:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33763) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZg-0001lc-Pn for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEZe-0002Qx-70 for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:52 -0400 Received: from mail.ispras.ru ([83.149.199.45]:43976) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZd-0002QY-VE for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:50 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 03369540089; Wed, 10 Oct 2018 16:30:48 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:02 +0300 Message-ID: <20181010133402.24538.41243.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 05/19] replay: finish record/replay before closing the disks 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" After recent updates block devices cannot be closed on qemu exit. This happens due to the block request polling when replay is not finished. Therefore now we stop execution recording before closing the block devices. Signed-off-by: Pavel Dovgalyuk --- replay/replay.c | 2 ++ vl.c | 1 + 2 files changed, 3 insertions(+) diff --git a/replay/replay.c b/replay/replay.c index 379b51a..ceee20a 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -378,6 +378,8 @@ void replay_finish(void) g_free(replay_snapshot); replay_snapshot = NULL; + replay_mode = REPLAY_MODE_NONE; + replay_finish_events(); } diff --git a/vl.c b/vl.c index 46238d2..a3e2e47 100644 --- a/vl.c +++ b/vl.c @@ -4627,6 +4627,7 @@ int main(int argc, char **argv, char **envp) /* No more vcpu or device emulation activity beyond this point */ vm_shutdown(); + replay_finish(); job_cancel_sync_all(); bdrv_close_all(); From patchwork Wed Oct 10 13:34:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981873 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZtS4tGPz9sD3 for ; Thu, 11 Oct 2018 00:38:24 +1100 (AEDT) Received: from localhost ([::1]:57328 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEgw-0006eP-4q for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:38:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33810) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZk-0001p6-IH for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEZj-0002Tg-RV for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:56 -0400 Received: from mail.ispras.ru ([83.149.199.45]:43996) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZj-0002TL-JE for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:30:55 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 9D41E540089; Wed, 10 Oct 2018 16:30:54 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:08 +0300 Message-ID: <20181010133408.24538.77033.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 06/19] qcow2: introduce icount field for snapshots 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch introduces the icount field for saving within the snapshot. It is required for navigation between the snapshots in record/replay mode. Signed-off-by: Pavel Dovgalyuk Acked-by: Kevin Wolf --- v2: - documented format changes in docs/interop/qcow2.txt (suggested by Eric Blake) --- block/qcow2-snapshot.c | 7 +++++++ block/qcow2.h | 2 ++ docs/interop/qcow2.txt | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index bb6a5b7..d682946 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -103,6 +103,12 @@ int qcow2_read_snapshots(BlockDriverState *bs) sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; } + if (extra_data_size >= 24) { + sn->icount = be64_to_cpu(extra.icount); + } else { + sn->icount = -1ULL; + } + /* Read snapshot ID */ sn->id_str = g_malloc(id_str_size + 1); ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size); @@ -209,6 +215,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs) memset(&extra, 0, sizeof(extra)); extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size); extra.disk_size = cpu_to_be64(sn->disk_size); + extra.icount = cpu_to_be64(sn->icount); id_str_size = strlen(sn->id_str); name_size = strlen(sn->name); diff --git a/block/qcow2.h b/block/qcow2.h index ba43031..656787d 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -153,6 +153,7 @@ typedef struct QEMU_PACKED QCowSnapshotHeader { typedef struct QEMU_PACKED QCowSnapshotExtraData { uint64_t vm_state_size_large; uint64_t disk_size; + uint64_t icount; } QCowSnapshotExtraData; @@ -166,6 +167,7 @@ typedef struct QCowSnapshot { uint32_t date_sec; uint32_t date_nsec; uint64_t vm_clock_nsec; + uint64_t icount; } QCowSnapshot; struct Qcow2Cache; diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt index 845d40a..aa1101d 100644 --- a/docs/interop/qcow2.txt +++ b/docs/interop/qcow2.txt @@ -506,6 +506,10 @@ Snapshot table entry: Byte 48 - 55: Virtual disk size of the snapshot in bytes + Byte 56 - 63: icount value which corresponds to + the record/replay step when the snapshot + was taken + Version 3 images must include extra data at least up to byte 55. From patchwork Wed Oct 10 13:34:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981876 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZxy6HDZz9sCv for ; Thu, 11 Oct 2018 00:41:26 +1100 (AEDT) Received: from localhost ([::1]:57345 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEjr-0000bW-No for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:41:23 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33870) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZs-0001rd-BF for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEZp-0002WH-LS for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:04 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44028) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZp-0002Vn-7q for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:01 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 3DDCB54008A; Wed, 10 Oct 2018 16:31:00 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:14 +0300 Message-ID: <20181010133414.24538.21966.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 07/19] migration: introduce icount field for snapshots 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Saving icount as a parameters of the snapshot allows navigation between them in the execution replay scenario. This information can be used for finding a specific snapshot for rewinding the recorded execution to the specific moment of the time. E.g., 'reverse step' action needs to load the nearest snapshot which is prior to the current moment of time . Signed-off-by: Pavel Dovgalyuk --- v2: - made icount in SnapshotInfo optional (suggested by Eric Blake) v7: - added more comments for icount member (suggested by Markus Armbruster) --- block/qapi.c | 17 +++++++++++++---- block/qcow2-snapshot.c | 2 ++ blockdev.c | 10 ++++++++++ include/block/snapshot.h | 1 + migration/savevm.c | 5 +++++ qapi/block-core.json | 7 ++++++- qapi/block.json | 3 ++- 7 files changed, 39 insertions(+), 6 deletions(-) diff --git a/block/qapi.c b/block/qapi.c index c66f949..9f2ccfa 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -210,6 +210,7 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs, info->date_nsec = sn_tab[i].date_nsec; info->vm_clock_sec = sn_tab[i].vm_clock_nsec / 1000000000; info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000; + info->icount = sn_tab[i].icount; info_list = g_new0(SnapshotInfoList, 1); info_list->value = info; @@ -663,14 +664,15 @@ void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f, QEMUSnapshotInfo *sn) { char buf1[128], date_buf[128], clock_buf[128]; + char icount_buf[128] = {0}; struct tm tm; time_t ti; int64_t secs; if (!sn) { func_fprintf(f, - "%-10s%-20s%7s%20s%15s", - "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); + "%-10s%-18s%7s%20s%13s%11s", + "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT"); } else { ti = sn->date_sec; localtime_r(&ti, &tm); @@ -683,13 +685,18 @@ void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f, (int)((secs / 60) % 60), (int)(secs % 60), (int)((sn->vm_clock_nsec / 1000000) % 1000)); + if (sn->icount != -1ULL) { + snprintf(icount_buf, sizeof(icount_buf), + "%"PRId64, sn->icount); + } func_fprintf(f, - "%-10s%-20s%7s%20s%15s", + "%-10s%-18s%7s%20s%13s%11s", sn->id_str, sn->name, get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size), date_buf, - clock_buf); + clock_buf, + icount_buf); } } @@ -857,6 +864,8 @@ void bdrv_image_info_dump(fprintf_function func_fprintf, void *f, .date_nsec = elem->value->date_nsec, .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL + elem->value->vm_clock_nsec, + .icount = elem->value->has_icount ? + elem->value->icount : -1ULL, }; pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id); diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index d682946..96b57f4 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -379,6 +379,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) sn->date_sec = sn_info->date_sec; sn->date_nsec = sn_info->date_nsec; sn->vm_clock_nsec = sn_info->vm_clock_nsec; + sn->icount = sn_info->icount; /* Allocate the L1 table of the snapshot and copy the current one there. */ l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t)); @@ -698,6 +699,7 @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) sn_info->date_sec = sn->date_sec; sn_info->date_nsec = sn->date_nsec; sn_info->vm_clock_nsec = sn->vm_clock_nsec; + sn_info->icount = sn->icount; } *psn_tab = sn_tab; return s->nb_snapshots; diff --git a/blockdev.c b/blockdev.c index a8755bd..1d66380 100644 --- a/blockdev.c +++ b/blockdev.c @@ -57,6 +57,7 @@ #include "block/trace.h" #include "sysemu/arch_init.h" #include "sysemu/qtest.h" +#include "sysemu/replay.h" #include "qemu/cutils.h" #include "qemu/help_option.h" #include "qemu/throttle-options.h" @@ -1239,6 +1240,10 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device, info->vm_state_size = sn.vm_state_size; info->vm_clock_nsec = sn.vm_clock_nsec % 1000000000; info->vm_clock_sec = sn.vm_clock_nsec / 1000000000; + if (sn.icount != -1ULL) { + info->icount = sn.icount; + info->has_icount = true; + } return info; @@ -1447,6 +1452,11 @@ static void internal_snapshot_prepare(BlkActionState *common, sn->date_sec = tv.tv_sec; sn->date_nsec = tv.tv_usec * 1000; sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (replay_mode != REPLAY_MODE_NONE) { + sn->icount = replay_get_current_step(); + } else { + sn->icount = -1ULL; + } ret1 = bdrv_snapshot_create(bs, sn); if (ret1 < 0) { diff --git a/include/block/snapshot.h b/include/block/snapshot.h index f73d109..c9c8975 100644 --- a/include/block/snapshot.h +++ b/include/block/snapshot.h @@ -42,6 +42,7 @@ typedef struct QEMUSnapshotInfo { uint32_t date_sec; /* UTC date of the snapshot */ uint32_t date_nsec; uint64_t vm_clock_nsec; /* VM clock relative to boot */ + uint64_t icount; /* record/replay step */ } QEMUSnapshotInfo; int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, diff --git a/migration/savevm.c b/migration/savevm.c index 2d10e45..bdf7136 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2462,6 +2462,11 @@ int save_snapshot(const char *name, Error **errp) sn->date_sec = tv.tv_sec; sn->date_nsec = tv.tv_usec * 1000; sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (replay_mode != REPLAY_MODE_NONE) { + sn->icount = replay_get_current_step(); + } else { + sn->icount = -1ULL; + } if (name) { ret = bdrv_snapshot_find(bs, old_sn, name); diff --git a/qapi/block-core.json b/qapi/block-core.json index cfb37f8..34dc9f1 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -26,13 +26,18 @@ # # @vm-clock-nsec: fractional part in nano seconds to be used with vm-clock-sec # +# @icount: Current instruction count. Appears when execution record/replay +# is enabled. Used for "time-traveling" to match the moment +# in the recorded execution with the snapshots (since 3.1) +# # Since: 1.3 # ## { 'struct': 'SnapshotInfo', 'data': { 'id': 'str', 'name': 'str', 'vm-state-size': 'int', 'date-sec': 'int', 'date-nsec': 'int', - 'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } } + 'vm-clock-sec': 'int', 'vm-clock-nsec': 'int', + '*icount': 'int' } } ## # @ImageInfoSpecificQCow2EncryptionBase: diff --git a/qapi/block.json b/qapi/block.json index 11f01f2..a6396a9 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -176,7 +176,8 @@ # "date-sec": 1000012, # "date-nsec": 10, # "vm-clock-sec": 100, -# "vm-clock-nsec": 20 +# "vm-clock-nsec": 20, +# "icount": 220414 # } # } # From patchwork Wed Oct 10 13:34:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981870 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZt91pjNz9s8F for ; Thu, 11 Oct 2018 00:38:08 +1100 (AEDT) Received: from localhost ([::1]:57321 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEge-0006MD-9D for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:38:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33912) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZx-0001uP-4S for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEZv-0002Zg-DU for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:09 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44054) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEZv-0002Z9-50 for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:07 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id E186A540089; Wed, 10 Oct 2018 16:31:05 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:19 +0300 Message-ID: <20181010133419.24538.65437.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 08/19] replay: provide and accessor for rr filename 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds an accessor function for the name of the record/replay log file. Adding an accessor instead of making variable global, prevents accidental modification of this variable by other modules. Signed-off-by: Pavel Dovgalyuk --- include/sysemu/replay.h | 2 ++ replay/replay.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 3a7c58e..b3f593f 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -71,6 +71,8 @@ void replay_start(void); void replay_finish(void); /*! Adds replay blocker with the specified error description */ void replay_add_blocker(Error *reason); +/* Returns name of the replay log file */ +const char *replay_get_filename(void); /* Processing the instructions */ diff --git a/replay/replay.c b/replay/replay.c index ceee20a..e6b1045 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -387,3 +387,8 @@ void replay_add_blocker(Error *reason) { replay_blockers = g_slist_prepend(replay_blockers, reason); } + +const char *replay_get_filename(void) +{ + return replay_filename; +} From patchwork Wed Oct 10 13:34:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981886 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42Vb296NtFz9s8F for ; Thu, 11 Oct 2018 00:45:05 +1100 (AEDT) Received: from localhost ([::1]:57364 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEnP-0003g7-Cy for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:45:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33956) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaB-00022Z-UZ for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEa1-0002dG-4o for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:19 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44086) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEa0-0002cj-NO for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:13 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id C0838540089; Wed, 10 Oct 2018 16:31:11 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:25 +0300 Message-ID: <20181010133425.24538.54266.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 09/19] replay: introduce info hmp/qmp command 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch introduces 'info replay' monitor command and corresponding qmp request. These commands request the current record/replay mode, replay log file name, and the execution step (number or recorded/replayed instructions). User may use step number for replay_seek/replay_break commands and for controlling the execution of replay. Signed-off-by: Pavel Dovgalyuk Acked-by: Dr. David Alan Gilbert --- v2: - renamed info_replay qmp into query-replay (suggested by Eric Blake) v7: - added empty line (suggested by Markus Armbruster) --- hmp-commands-info.hx | 14 ++++++++++++++ hmp.h | 1 + qapi/misc.json | 35 +++++++++++++++++++++++++++++++++++ replay/Makefile.objs | 3 ++- replay/replay-debugging.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 replay/replay-debugging.c diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index cbee8b9..9f2f35e 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -918,6 +918,20 @@ STEXI Show SEV information. ETEXI + { + .name = "replay", + .args_type = "", + .params = "", + .help = "show parameters of the record/replay", + .cmd = hmp_info_replay, + }, + +STEXI +@item info replay +@findex info replay +Display the current record/replay mode and the currently executing step. +ETEXI + STEXI @end table ETEXI diff --git a/hmp.h b/hmp.h index 5f1addc..d792149 100644 --- a/hmp.h +++ b/hmp.h @@ -148,5 +148,6 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict); void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict); void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict); void hmp_info_sev(Monitor *mon, const QDict *qdict); +void hmp_info_replay(Monitor *mon, const QDict *qdict); #endif diff --git a/qapi/misc.json b/qapi/misc.json index ada9af5..79f6b21 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -3105,6 +3105,41 @@ 'data': [ 'none', 'record', 'play' ] } ## +# @ReplayInfo: +# +# Status of the record/replay mode. +# +# @mode: current mode. +# +# @filename: name of the record/replay log file. +# +# @step: current step number. +# +# Since: 3.1 +# +## +{ 'struct': 'ReplayInfo', + 'data': { 'mode': 'ReplayMode', '*filename': 'str', 'step': 'int' } } + +## +# @query-replay: +# +# Retrieves the status of the execution record/replay. +# +# Returns: structure with the properties of the record/replay. +# +# Since: 3.1 +# +# Example: +# +# -> { "execute": "query-replay" } +# <- { "return": { "mode": "play", "filename": "log.rr", "step": 220414 } } +# +## +{ 'command': 'query-replay', + 'returns': 'ReplayInfo' } + +## # @xen-load-devices-state: # # Load the state of all devices from file. The RAM and the block devices diff --git a/replay/Makefile.objs b/replay/Makefile.objs index cee6539..6694e3e 100644 --- a/replay/Makefile.objs +++ b/replay/Makefile.objs @@ -6,4 +6,5 @@ common-obj-y += replay-input.o common-obj-y += replay-char.o common-obj-y += replay-snapshot.o common-obj-y += replay-net.o -common-obj-y += replay-audio.o \ No newline at end of file +common-obj-y += replay-audio.o +common-obj-y += replay-debugging.o diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c new file mode 100644 index 0000000..1d7e75d --- /dev/null +++ b/replay/replay-debugging.c @@ -0,0 +1,42 @@ +/* + * replay-debugging.c + * + * Copyright (c) 2010-2018 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "sysemu/replay.h" +#include "replay-internal.h" +#include "hmp.h" +#include "monitor/monitor.h" +#include "qapi/qapi-commands-misc.h" + +void hmp_info_replay(Monitor *mon, const QDict *qdict) +{ + if (replay_mode == REPLAY_MODE_NONE) { + monitor_printf(mon, "No record/replay\n"); + } else { + monitor_printf(mon, "%s execution '%s': current step = %"PRId64"\n", + replay_mode == REPLAY_MODE_RECORD ? "Recording" : "Replaying", + replay_get_filename(), replay_get_current_step()); + } +} + +ReplayInfo *qmp_query_replay(Error **errp) +{ + ReplayInfo *retval = g_new0(ReplayInfo, 1); + + retval->mode = replay_mode; + if (replay_get_filename()) { + retval->filename = g_strdup(replay_get_filename()); + retval->has_filename = true; + } + retval->step = replay_get_current_step(); + return retval; +} From patchwork Wed Oct 10 13:34:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981867 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZpf3FjKz9sB7 for ; Thu, 11 Oct 2018 00:35:06 +1100 (AEDT) Received: from localhost ([::1]:57304 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEdj-00042R-Rp for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:35:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34017) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaO-00028g-7N for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEaK-0002m3-HC for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:35 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44114) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaI-0002gv-Ic for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:31 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 62626540089; Wed, 10 Oct 2018 16:31:17 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:31 +0300 Message-ID: <20181010133431.24538.53838.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 10/19] replay: introduce breakpoint at the specified step 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch introduces replay_break, replay_delete_break qmp and hmp commands. These commands allow stopping at the specified instruction. It may be useful for debugging when there are some known events that should be investigated. replay_break command has one argument - number of instructions executed since the start of the replay. replay_delete_break removes previously set breakpoint. Signed-off-by: Pavel Dovgalyuk --- v2: - renamed replay_break qmp command into replay-break (suggested by Eric Blake) v7: - introduces replay_delete_break command --- hmp-commands.hx | 29 ++++++++++++++++ hmp.h | 2 + qapi/misc.json | 31 +++++++++++++++++ replay/replay-debugging.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ replay/replay-internal.h | 4 ++ replay/replay.c | 17 +++++++++ 6 files changed, 167 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index db0c681..615d725 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1888,6 +1888,35 @@ Set QOM property @var{property} of object at location @var{path} to value @var{v ETEXI { + .name = "replay_break", + .args_type = "step:i", + .params = "step", + .help = "sets breakpoint on the specified step of the replay", + .cmd = hmp_replay_break, + }, + +STEXI +@item replay_break @var{step} +@findex replay_break +Set breakpoint on the specified step of the replay. +Execution stops when the specified step is reached. +ETEXI + + { + .name = "replay_delete_break", + .args_type = "", + .params = "", + .help = "removes replay breakpoint", + .cmd = hmp_replay_delete_break, + }, + +STEXI +@item replay_delete_break +@findex replay_delete_break +Removes replay breakpoint which was previously set with replay_break. +ETEXI + + { .name = "info", .args_type = "item:s?", .params = "[subcommand]", diff --git a/hmp.h b/hmp.h index d792149..c9b9b4f 100644 --- a/hmp.h +++ b/hmp.h @@ -149,5 +149,7 @@ void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict); void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict); void hmp_info_sev(Monitor *mon, const QDict *qdict); void hmp_info_replay(Monitor *mon, const QDict *qdict); +void hmp_replay_break(Monitor *mon, const QDict *qdict); +void hmp_replay_delete_break(Monitor *mon, const QDict *qdict); #endif diff --git a/qapi/misc.json b/qapi/misc.json index 79f6b21..e00a9b0 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -3140,6 +3140,37 @@ 'returns': 'ReplayInfo' } ## +# @replay-break: +# +# Set breakpoint on the specified step of the replay. +# Execution stops when the specified step is reached. +# +# @step: execution step to stop at +# +# Since: 3.1 +# +# Example: +# +# -> { "execute": "replay-break", "data": { "step": 220414 } } +# +## +{ 'command': 'replay-break', 'data': { 'step': 'int' } } + +## +# @replay-delete-break: +# +# Removes replay breakpoint. +# +# Since: 3.1 +# +# Example: +# +# -> { "execute": "replay-delete-break" } +# +## +{ 'command': 'replay-delete-break' } + +## # @xen-load-devices-state: # # Load the state of all devices from file. The RAM and the block devices diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index 1d7e75d..207d6e0 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -16,6 +16,8 @@ #include "hmp.h" #include "monitor/monitor.h" #include "qapi/qapi-commands-misc.h" +#include "qapi/qmp/qdict.h" +#include "qemu/timer.h" void hmp_info_replay(Monitor *mon, const QDict *qdict) { @@ -40,3 +42,85 @@ ReplayInfo *qmp_query_replay(Error **errp) retval->step = replay_get_current_step(); return retval; } + +static void replay_break(uint64_t step, QEMUTimerCB callback, void *opaque) +{ + assert(replay_mode == REPLAY_MODE_PLAY); + assert(replay_mutex_locked()); + assert(replay_break_step >= replay_get_current_step()); + assert(callback); + + replay_break_step = step; + + if (replay_break_timer) { + timer_del(replay_break_timer); + } else { + replay_break_timer = timer_new_ns(QEMU_CLOCK_REALTIME, callback, opaque); + } +} + +static void replay_delete_break(void) +{ + assert(replay_mode == REPLAY_MODE_PLAY); + assert(replay_mutex_locked()); + + if (replay_break_timer) { + timer_del(replay_break_timer); + timer_free(replay_break_timer); + replay_break_timer = NULL; + } + replay_break_step = -1ULL; +} + +static void replay_stop_vm(void *opaque) +{ + vm_stop(RUN_STATE_PAUSED); + replay_delete_break(); +} + +void qmp_replay_break(int64_t step, Error **errp) +{ + if (replay_mode == REPLAY_MODE_PLAY) { + if (step >= replay_get_current_step()) { + replay_break(step, replay_stop_vm, NULL); + } else { + error_setg(errp, "cannot set breakpoint at the step in the past"); + } + } else { + error_setg(errp, "setting the breakpoint is allowed only in play mode"); + } +} + +void hmp_replay_break(Monitor *mon, const QDict *qdict) +{ + int64_t step = qdict_get_try_int(qdict, "step", -1LL); + Error *err = NULL; + + qmp_replay_break(step, &err); + if (err) { + error_report_err(err); + error_free(err); + return; + } +} + +void qmp_replay_delete_break(Error **errp) +{ + if (replay_mode == REPLAY_MODE_PLAY) { + replay_delete_break(); + } else { + error_setg(errp, "replay breakpoints are allowed only in play mode"); + } +} + +void hmp_replay_delete_break(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + + qmp_replay_delete_break(&err); + if (err) { + error_report_err(err); + error_free(err); + return; + } +} diff --git a/replay/replay-internal.h b/replay/replay-internal.h index af6f4d5..94b7e9b 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -91,6 +91,10 @@ extern ReplayState replay_state; /* File for replay writing */ extern FILE *replay_file; +/* Step of the replay breakpoint */ +extern uint64_t replay_break_step; +/* Timer for the replay breakpoint callback */ +extern QEMUTimer *replay_break_timer; void replay_put_byte(uint8_t byte); void replay_put_event(uint8_t event); diff --git a/replay/replay.c b/replay/replay.c index e6b1045..c6d5de9 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -34,6 +34,10 @@ static char *replay_filename; ReplayState replay_state; static GSList *replay_blockers; +/* Replay breakpoints */ +uint64_t replay_break_step = -1ULL; +QEMUTimer *replay_break_timer; + bool replay_next_event_is(int event) { bool res = false; @@ -73,6 +77,13 @@ int replay_get_instructions(void) replay_mutex_lock(); if (replay_next_event_is(EVENT_INSTRUCTION)) { res = replay_state.instructions_count; + if (replay_break_step != -1LL) { + uint64_t current = replay_get_current_step(); + assert(replay_break_step >= current); + if (current + res > replay_break_step) { + res = replay_break_step - current; + } + } } replay_mutex_unlock(); return res; @@ -99,6 +110,12 @@ void replay_account_executed_instructions(void) will be read from the log. */ qemu_notify_event(); } + /* Execution reached the break step */ + if (replay_break_step == replay_state.current_step) { + /* Cannot make callback directly from the vCPU thread */ + timer_mod_ns(replay_break_timer, + qemu_clock_get_ns(QEMU_CLOCK_REALTIME)); + } } } } From patchwork Wed Oct 10 13:34:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981890 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42Vb504gN0z9s8F for ; Thu, 11 Oct 2018 00:47:32 +1100 (AEDT) Received: from localhost ([::1]:57390 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEpm-0005Rt-A0 for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:47:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33977) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaI-00025O-NH for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEaE-0002jn-Un for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:29 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44140) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaC-0002ii-5B for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:24 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 0670654008A; Wed, 10 Oct 2018 16:31:23 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:37 +0300 Message-ID: <20181010133436.24538.61872.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 11/19] replay: implement replay-seek command to proceed to the desired step 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds hmp/qmp commands replay_seek/replay-seek that proceed the execution to the specified step. The commands automatically loads nearest snapshot and replay the execution to find the desired step. Signed-off-by: Pavel Dovgalyuk --- v2: - renamed replay_seek qmp command into replay-seek (suggested by Eric Blake) v7: - small fixes related to Markus Armbruster's review --- hmp-commands.hx | 15 +++++++ hmp.h | 1 qapi/misc.json | 11 +++++ replay/replay-debugging.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 615d725..1988b2b 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1917,6 +1917,21 @@ Removes replay breakpoint which was previously set with replay_break. ETEXI { + .name = "replay_seek", + .args_type = "step:i", + .params = "step", + .help = "rewinds replay to the specified step", + .cmd = hmp_replay_seek, + }, + +STEXI +@item replay_seek @var{step} +@findex replay_seek +Automatically proceeds to the specified step, when replaying +the execution. +ETEXI + + { .name = "info", .args_type = "item:s?", .params = "[subcommand]", diff --git a/hmp.h b/hmp.h index c9b9b4f..d6e1d7e 100644 --- a/hmp.h +++ b/hmp.h @@ -151,5 +151,6 @@ void hmp_info_sev(Monitor *mon, const QDict *qdict); void hmp_info_replay(Monitor *mon, const QDict *qdict); void hmp_replay_break(Monitor *mon, const QDict *qdict); void hmp_replay_delete_break(Monitor *mon, const QDict *qdict); +void hmp_replay_seek(Monitor *mon, const QDict *qdict); #endif diff --git a/qapi/misc.json b/qapi/misc.json index e00a9b0..869c5fa 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -3171,6 +3171,17 @@ { 'command': 'replay-delete-break' } ## +# @replay-seek: +# +# Automatically proceeds to the specified step when replaying +# the execution. +# +# @step: destination execution step +# -> { "execute": "replay-seek", "data": { "step": 220414 } } +## +{ 'command': 'replay-seek', 'data': { 'step': 'int' } } + +## # @xen-load-devices-state: # # Load the state of all devices from file. The RAM and the block devices diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index 207d6e0..d744106 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -18,6 +18,8 @@ #include "qapi/qapi-commands-misc.h" #include "qapi/qmp/qdict.h" #include "qemu/timer.h" +#include "block/snapshot.h" +#include "migration/snapshot.h" void hmp_info_replay(Monitor *mon, const QDict *qdict) { @@ -124,3 +126,92 @@ void hmp_replay_delete_break(Monitor *mon, const QDict *qdict) return; } } + +static char *replay_find_nearest_snapshot(int64_t step, int64_t* snapshot_step) +{ + BlockDriverState *bs; + QEMUSnapshotInfo *sn_tab; + QEMUSnapshotInfo *nearest = NULL; + char *ret = NULL; + int nb_sns, i; + AioContext *aio_context; + + *snapshot_step = -1; + + bs = bdrv_all_find_vmstate_bs(); + if (!bs) { + goto fail; + } + aio_context = bdrv_get_aio_context(bs); + + aio_context_acquire(aio_context); + nb_sns = bdrv_snapshot_list(bs, &sn_tab); + aio_context_release(aio_context); + + for (i = 0; i < nb_sns; i++) { + if (bdrv_all_find_snapshot(sn_tab[i].name, &bs) == 0) { + if (sn_tab[i].icount != -1ULL + && sn_tab[i].icount <= step + && (!nearest || nearest->icount < sn_tab[i].icount)) { + nearest = &sn_tab[i]; + } + } + } + if (nearest) { + ret = g_strdup(nearest->name); + *snapshot_step = nearest->icount; + } + g_free(sn_tab); + +fail: + return ret; +} + +static void replay_seek(int64_t step, QEMUTimerCB callback, Error **errp) +{ + char *snapshot = NULL; + int64_t snapshot_step; + + if (replay_mode != REPLAY_MODE_PLAY) { + error_setg(errp, "replay must be enabled to seek"); + return; + } + if (!replay_snapshot) { + error_setg(errp, "snapshotting is disabled"); + return; + } + + snapshot = replay_find_nearest_snapshot(step, &snapshot_step); + if (snapshot) { + if (step < replay_get_current_step() + || replay_get_current_step() < snapshot_step) { + vm_stop(RUN_STATE_RESTORE_VM); + load_snapshot(snapshot, errp); + } + g_free(snapshot); + } + if (replay_get_current_step() <= step) { + replay_break(step, callback, NULL); + vm_start(); + } else { + error_setg(errp, "cannot seek to the specified step"); + } +} + +void qmp_replay_seek(int64_t step, Error **errp) +{ + replay_seek(step, replay_stop_vm, errp); +} + +void hmp_replay_seek(Monitor *mon, const QDict *qdict) +{ + int64_t step = qdict_get_try_int(qdict, "step", -1LL); + Error *err = NULL; + + qmp_replay_seek(step, &err); + if (err) { + error_report_err(err); + error_free(err); + return; + } +} From patchwork Wed Oct 10 13:34:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981871 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZtF0WDKz9sCv for ; Thu, 11 Oct 2018 00:38:12 +1100 (AEDT) Received: from localhost ([::1]:57325 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEgk-0006S6-2w for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:38:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34016) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaO-00028e-7V for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEaM-0002ml-H9 for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:35 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44166) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaK-0002kc-G2 for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:34 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 98D3C54008B; Wed, 10 Oct 2018 16:31:28 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:42 +0300 Message-ID: <20181010133442.24538.3050.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 12/19] replay: refine replay-time module 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch removes refactoring artifacts from the replay/replay-time.c Signed-off-by: Pavel Dovgalyuk --- replay/replay-time.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/replay/replay-time.c b/replay/replay-time.c index 17caf35..8986054 100644 --- a/replay/replay-time.c +++ b/replay/replay-time.c @@ -17,16 +17,15 @@ int64_t replay_save_clock(ReplayClockKind kind, int64_t clock, int64_t raw_icount) { - if (replay_file) { - g_assert(replay_mutex_locked()); + g_assert(replay_file); + g_assert(replay_mutex_locked()); - /* Due to the caller's locking requirements we get the icount from it instead - * of using replay_save_instructions(). - */ - replay_advance_current_step(raw_icount); - replay_put_event(EVENT_CLOCK + kind); - replay_put_qword(clock); - } + /* Due to the caller's locking requirements we get the icount from it instead + * of using replay_save_instructions(). + */ + replay_advance_current_step(raw_icount); + replay_put_event(EVENT_CLOCK + kind); + replay_put_qword(clock); return clock; } @@ -48,20 +47,15 @@ void replay_read_next_clock(ReplayClockKind kind) /*! Reads next clock event from the input. */ int64_t replay_read_clock(ReplayClockKind kind) { + int64_t ret; g_assert(replay_file && replay_mutex_locked()); replay_account_executed_instructions(); - if (replay_file) { - int64_t ret; - if (replay_next_event_is(EVENT_CLOCK + kind)) { - replay_read_next_clock(kind); - } - ret = replay_state.cached_clock[kind]; - - return ret; + if (replay_next_event_is(EVENT_CLOCK + kind)) { + replay_read_next_clock(kind); } + ret = replay_state.cached_clock[kind]; - error_report("REPLAY INTERNAL ERROR %d", __LINE__); - exit(1); + return ret; } From patchwork Wed Oct 10 13:34:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981875 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZxj4fJbz9sDC for ; Thu, 11 Oct 2018 00:41:13 +1100 (AEDT) Received: from localhost ([::1]:57342 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEje-0000Rk-7e for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:41:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34060) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaP-00029q-IR for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEaO-0002oC-Lq for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:37 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44196) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaO-0002mu-BW for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:36 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 3764A540089; Wed, 10 Oct 2018 16:31:34 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:48 +0300 Message-ID: <20181010133448.24538.20925.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 13/19] replay: flush rr queue before loading the vmstate 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Non-empty record/replay queue prevents saving and loading the VM state, because it includes pending bottom halves and block coroutines. But when the new VM state is loaded, we don't have to preserve the consistency of the current state anymore. Therefore this patch just flushes the queue allowing the coroutines to finish. Signed-off-by: Pavel Dovgalyuk --- include/sysemu/replay.h | 2 ++ migration/savevm.c | 10 ++++------ replay/replay-internal.h | 2 -- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index b3f593f..cc5e9b0 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -140,6 +140,8 @@ void replay_disable_events(void); void replay_enable_events(void); /*! Returns true when saving events is enabled */ bool replay_events_enabled(void); +/* Flushes events queue */ +void replay_flush_events(void); /*! Adds bottom half event to the queue */ void replay_bh_schedule_event(QEMUBH *bh); /*! Adds input event to the queue */ diff --git a/migration/savevm.c b/migration/savevm.c index bdf7136..57a297c 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2615,12 +2615,6 @@ int load_snapshot(const char *name, Error **errp) AioContext *aio_context; MigrationIncomingState *mis = migration_incoming_get_current(); - if (!replay_can_snapshot()) { - error_report("Record/replay does not allow loading snapshot " - "right now. Try once more later."); - return -EINVAL; - } - if (!bdrv_all_can_snapshot(&bs)) { error_setg(errp, "Device '%s' is writable but does not support snapshots", @@ -2654,6 +2648,10 @@ int load_snapshot(const char *name, Error **errp) return -EINVAL; } + /* Flush the record/replay queue. Now the VM state is going + to change. Therefore we don't need to preserve its consistency */ + replay_flush_events(); + /* Flush all IO requests so they don't interfere with the new state. */ bdrv_drain_all_begin(); diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 94b7e9b..e37b201 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -146,8 +146,6 @@ void replay_read_next_clock(unsigned int kind); void replay_init_events(void); /*! Clears internal data structures for events handling */ void replay_finish_events(void); -/*! Flushes events queue */ -void replay_flush_events(void); /*! Returns true if there are any unsaved events in the queue */ bool replay_has_events(void); /*! Saves events from queue into the file */ From patchwork Wed Oct 10 13:34:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981877 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZyJ5ZfZz9sCv for ; Thu, 11 Oct 2018 00:41:43 +1100 (AEDT) Received: from localhost ([::1]:57346 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEk8-0000r4-Kx for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:41:40 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34155) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaV-0002FF-QD for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEaT-0002sW-4u for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:43 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44216) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaS-0002rp-OY for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:41 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id CCB6A540089; Wed, 10 Oct 2018 16:31:39 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:54 +0300 Message-ID: <20181010133454.24538.66846.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 14/19] gdbstub: add reverse step support in replay mode 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" GDB remote protocol supports two reverse debugging commands: reverse step and reverse continue. This patch adds support of the first one to the gdbstub. Reverse step is intended to step one instruction in the backwards direction. This is not possible in regular execution. But replayed execution is deterministic, therefore we can load one of the prior snapshots and proceed to the desired step. It is equivalent to stepping one instruction back. There should be at least one snapshot preceding the debugged part of the replay log. Signed-off-by: Pavel Dovgalyuk --- accel/tcg/translator.c | 1 + cpus.c | 14 +++++++++++--- exec.c | 5 +++++ gdbstub.c | 42 +++++++++++++++++++++++++++++++++++++++--- include/sysemu/replay.h | 7 +++++++ replay/replay-debugging.c | 33 +++++++++++++++++++++++++++++++++ stubs/replay.c | 5 +++++ 7 files changed, 101 insertions(+), 6 deletions(-) diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index afd0a49..33a543e 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -17,6 +17,7 @@ #include "exec/gen-icount.h" #include "exec/log.h" #include "exec/translator.h" +#include "sysemu/replay.h" /* Pairs with tcg_clear_temp_count. To be called by #TranslatorOps.{translate_insn,tb_stop} if diff --git a/cpus.c b/cpus.c index d60ddf1..5189a7e 100644 --- a/cpus.c +++ b/cpus.c @@ -1104,9 +1104,17 @@ static bool cpu_can_run(CPUState *cpu) static void cpu_handle_guest_debug(CPUState *cpu) { - gdb_set_stop_cpu(cpu); - qemu_system_debug_request(); - cpu->stopped = true; + if (!replay_running_debug()) { + gdb_set_stop_cpu(cpu); + qemu_system_debug_request(); + cpu->stopped = true; + } else { + if (!cpu->singlestep_enabled) { + cpu_single_step(cpu, SSTEP_ENABLE); + } else { + cpu_single_step(cpu, 0); + } + } } #ifdef CONFIG_LINUX diff --git a/exec.c b/exec.c index d0821e6..7e794cb 100644 --- a/exec.c +++ b/exec.c @@ -2738,6 +2738,11 @@ static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags) QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) { if (cpu_watchpoint_address_matches(wp, vaddr, len) && (wp->flags & flags)) { + if (replay_running_debug()) { + /* Don't process the watchpoints when we are + in a reverse debugging operation. */ + return; + } if (flags == BP_MEM_READ) { wp->flags |= BP_WATCHPOINT_HIT_READ; } else { diff --git a/gdbstub.c b/gdbstub.c index c8478de..6af98998 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -39,6 +39,7 @@ #include "sysemu/kvm.h" #include "exec/semihost.h" #include "exec/exec-all.h" +#include "sysemu/replay.h" #ifdef CONFIG_USER_ONLY #define GDB_ATTACHED "0" @@ -334,6 +335,19 @@ typedef struct GDBState { */ static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER; +/* Retrieves flags for single step mode. */ +static int get_sstep_flags(void) +{ + /* In replay mode all events written into the log should be replayed. + * That is why NOIRQ flag is removed in this mode. + */ + if (replay_mode != REPLAY_MODE_NONE) { + return SSTEP_ENABLE; + } else { + return sstep_flags; + } +} + static GDBState *gdbserver_state; bool gdb_has_xml; @@ -424,7 +438,7 @@ static int gdb_continue_partial(GDBState *s, char *newstates) CPU_FOREACH(cpu) { if (newstates[cpu->cpu_index] == 's') { trace_gdbstub_op_stepping(cpu->cpu_index); - cpu_single_step(cpu, sstep_flags); + cpu_single_step(cpu, get_sstep_flags()); } } s->running_state = 1; @@ -443,7 +457,7 @@ static int gdb_continue_partial(GDBState *s, char *newstates) break; /* nothing to do here */ case 's': trace_gdbstub_op_stepping(cpu->cpu_index); - cpu_single_step(cpu, sstep_flags); + cpu_single_step(cpu, get_sstep_flags()); cpu_resume(cpu); flag = 1; break; @@ -1082,9 +1096,28 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) addr = strtoull(p, (char **)&p, 16); gdb_set_cpu_pc(s, addr); } - cpu_single_step(s->c_cpu, sstep_flags); + cpu_single_step(s->c_cpu, get_sstep_flags()); gdb_continue(s); return RS_IDLE; + case 'b': + /* Backward debugging commands */ + if (replay_mode == REPLAY_MODE_PLAY) { + switch (*p) { + case 's': + if (replay_reverse_step()) { + gdb_continue(s); + return RS_IDLE; + } else { + put_packet(s, "E14"); + break; + } + default: + goto unknown_command; + } + } else { + put_packet(s, "E22"); + } + goto unknown_command; case 'F': { target_ulong ret; @@ -1347,6 +1380,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (cc->gdb_core_xml_file != NULL) { pstrcat(buf, sizeof(buf), ";qXfer:features:read+"); } + if (replay_mode == REPLAY_MODE_PLAY) { + pstrcat(buf, sizeof(buf), ";ReverseStep+"); + } put_packet(s, buf); break; } diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index cc5e9b0..73bf5fc 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -73,6 +73,13 @@ void replay_finish(void); void replay_add_blocker(Error *reason); /* Returns name of the replay log file */ const char *replay_get_filename(void); +/* Start making one step in backward direction. + Used by gdbstub for backwards debugging. + Returns true on success. */ +bool replay_reverse_step(void); +/* Returns true if replay module is processing + reverse_continue or reverse_step request */ +bool replay_running_debug(void); /* Processing the instructions */ diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index d744106..6334d82 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -21,6 +21,13 @@ #include "block/snapshot.h" #include "migration/snapshot.h" +static bool replay_is_debugging; + +bool replay_running_debug(void) +{ + return replay_is_debugging; +} + void hmp_info_replay(Monitor *mon, const QDict *qdict) { if (replay_mode == REPLAY_MODE_NONE) { @@ -215,3 +222,29 @@ void hmp_replay_seek(Monitor *mon, const QDict *qdict) return; } } + +static void replay_stop_vm_debug(void *opaque) +{ + replay_is_debugging = false; + vm_stop(RUN_STATE_DEBUG); + replay_break(-1LL, NULL, NULL); +} + +bool replay_reverse_step(void) +{ + Error *err = NULL; + + assert(replay_mode == REPLAY_MODE_PLAY); + + if (replay_get_current_step() != 0) { + replay_seek(replay_get_current_step() - 1, replay_stop_vm_debug, &err); + if (err) { + error_free(err); + return false; + } + replay_is_debugging = true; + return true; + } + + return false; +} diff --git a/stubs/replay.c b/stubs/replay.c index 4ac6078..521552f 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -80,3 +80,8 @@ void replay_mutex_lock(void) void replay_mutex_unlock(void) { } + +bool replay_reverse_step(void) +{ + return false; +} From patchwork Wed Oct 10 13:34:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981872 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZtG105fz9sD3 for ; Thu, 11 Oct 2018 00:38:13 +1100 (AEDT) Received: from localhost ([::1]:57326 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEgl-0006To-56 for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:38:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34194) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaa-0002I6-Qq for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEaY-0002vg-Oj for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:48 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44236) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaY-0002vM-CW for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:46 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 6EEAF540089; Wed, 10 Oct 2018 16:31:45 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:34:59 +0300 Message-ID: <20181010133459.24538.37756.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 15/19] gdbstub: add reverse continue support in replay mode 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds support of the reverse continue operation for gdbstub. Reverse continue finds the last breakpoint that would happen in normal execution from the beginning to the current moment. Implementation of the reverse continue replays the execution twice: to find the breakpoints that were hit and to seek to the last breakpoint. Reverse continue loads the previous snapshot and tries to find the breakpoint since that moment. If there are no such breakpoints, it proceeds to the earlier snapshot, and so on. When no breakpoints or watchpoints were hit at all, execution stops at the beginning of the replay log. Signed-off-by: Pavel Dovgalyuk --- cpus.c | 3 ++ exec.c | 1 + gdbstub.c | 10 ++++++- include/sysemu/replay.h | 6 ++++ replay/replay-debugging.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ stubs/replay.c | 5 +++ 6 files changed, 93 insertions(+), 1 deletion(-) diff --git a/cpus.c b/cpus.c index 5189a7e..8c0d7c4 100644 --- a/cpus.c +++ b/cpus.c @@ -1110,6 +1110,9 @@ static void cpu_handle_guest_debug(CPUState *cpu) cpu->stopped = true; } else { if (!cpu->singlestep_enabled) { + /* Report about the breakpoint and + make a single step to skip it */ + replay_breakpoint(); cpu_single_step(cpu, SSTEP_ENABLE); } else { cpu_single_step(cpu, 0); diff --git a/exec.c b/exec.c index 7e794cb..879b51b 100644 --- a/exec.c +++ b/exec.c @@ -2741,6 +2741,7 @@ static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags) if (replay_running_debug()) { /* Don't process the watchpoints when we are in a reverse debugging operation. */ + replay_breakpoint(); return; } if (flags == BP_MEM_READ) { diff --git a/gdbstub.c b/gdbstub.c index 6af98998..b17bbe5 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1111,6 +1111,14 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) put_packet(s, "E14"); break; } + case 'c': + if (replay_reverse_continue()) { + gdb_continue(s); + return RS_IDLE; + } else { + put_packet(s, "E14"); + break; + } default: goto unknown_command; } @@ -1381,7 +1389,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) pstrcat(buf, sizeof(buf), ";qXfer:features:read+"); } if (replay_mode == REPLAY_MODE_PLAY) { - pstrcat(buf, sizeof(buf), ";ReverseStep+"); + pstrcat(buf, sizeof(buf), ";ReverseStep+;ReverseContinue+"); } put_packet(s, buf); break; diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 73bf5fc..05cb40a 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -77,9 +77,15 @@ const char *replay_get_filename(void); Used by gdbstub for backwards debugging. Returns true on success. */ bool replay_reverse_step(void); +/* Start searching the last breakpoint/watchpoint. + Used by gdbstub for backwards debugging. + Returns true if the process successfully started. */ +bool replay_reverse_continue(void); /* Returns true if replay module is processing reverse_continue or reverse_step request */ bool replay_running_debug(void); +/* Called in reverse debugging mode to collect breakpoint information */ +void replay_breakpoint(void); /* Processing the instructions */ diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index 6334d82..b43a008 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -22,6 +22,8 @@ #include "migration/snapshot.h" static bool replay_is_debugging; +static int64_t replay_last_breakpoint; +static int64_t replay_last_snapshot; bool replay_running_debug(void) { @@ -248,3 +250,70 @@ bool replay_reverse_step(void) return false; } + +static void replay_continue_end(void) +{ + replay_is_debugging = false; + vm_stop(RUN_STATE_DEBUG); + replay_break(-1LL, NULL, NULL); +} + +static void replay_continue_stop(void *opaque) +{ + Error *err = NULL; + if (replay_last_breakpoint != -1LL) { + replay_seek(replay_last_breakpoint, replay_stop_vm_debug, &err); + if (err) { + error_free(err); + replay_continue_end(); + } + return; + } + /* No breakpoints since the last snapshot. + Find previous snapshot and try again. */ + if (replay_last_snapshot != 0) { + replay_seek(replay_last_snapshot - 1, replay_continue_stop, &err); + if (err) { + error_free(err); + replay_continue_end(); + } + replay_last_snapshot = replay_get_current_step(); + return; + } else { + /* Seek to the very first step */ + replay_seek(0, replay_stop_vm_debug, &err); + if (err) { + error_free(err); + replay_continue_end(); + } + return; + } + replay_continue_end(); +} + +bool replay_reverse_continue(void) +{ + Error *err = NULL; + + assert(replay_mode == REPLAY_MODE_PLAY); + + if (replay_get_current_step() != 0) { + replay_seek(replay_get_current_step() - 1, replay_continue_stop, &err); + if (err) { + error_free(err); + return false; + } + replay_last_breakpoint = -1LL; + replay_is_debugging = true; + replay_last_snapshot = replay_get_current_step(); + return true; + } + + return false; +} + +void replay_breakpoint(void) +{ + assert(replay_mode == REPLAY_MODE_PLAY); + replay_last_breakpoint = replay_get_current_step(); +} diff --git a/stubs/replay.c b/stubs/replay.c index 521552f..ee64972 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -85,3 +85,8 @@ bool replay_reverse_step(void) { return false; } + +bool replay_reverse_continue(void) +{ + return false; +} From patchwork Wed Oct 10 13:35:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981891 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42Vb7X1D1Kz9s8F for ; Thu, 11 Oct 2018 00:49:43 +1100 (AEDT) Received: from localhost ([::1]:57401 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAErs-00077q-Am for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:49:40 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34235) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEah-0002Q0-4G for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEae-00030l-BN for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:55 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44274) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEae-00030U-2z for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:52 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 127DF540089; Wed, 10 Oct 2018 16:31:51 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:35:05 +0300 Message-ID: <20181010133505.24538.78905.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 16/19] replay: describe reverse debugging in docs/replay.txt 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch updates the documentation and describes usage of the reverse debugging in QEMU+GDB. Signed-off-by: Pavel Dovgalyuk --- docs/replay.txt | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/replay.txt b/docs/replay.txt index 2c2c5f6..8447fdd 100644 --- a/docs/replay.txt +++ b/docs/replay.txt @@ -293,6 +293,39 @@ for recording and replaying must contain identical number of ports in record and replay modes, but their backends may differ. E.g., '-serial stdio' in record mode, and '-serial null' in replay mode. +Reverse debugging +----------------- + +Reverse debugging allows "executing" the program in reverse direction. +GDB remote protocol supports "reverse step" and "reverse continue" +commands. The first one steps single instruction backwards in time, +and the second one finds the last breakpoint in the past. + +Recorded executions may be used to enable reverse debugging. QEMU can't +execute the code in backwards direction, but can load a snapshot and +replay forward to find the desired position or breakpoint. + +The following GDB commands are supported: + - reverse-stepi (or rsi) - step one instruction backwards + - reverse-continue (or rc) - find last breakpoint in the past + +Reverse step loads the nearest snapshot and replays the execution until +the required instruction is met. + +Reverse continue may include several passes of examining the execution +between the snapshots. Each of the passes include the following steps: + 1. loading the snapshot + 2. replaying to examine the breakpoints + 3. if breakpoint or watchpoint was met + - loading the snaphot again + - replaying to the required breakpoint + 4. else + - proceeding to the p.1 with the earlier snapshot + +Therefore usage of the reverse debugging requires at least one snapshot +created in advance. See the "Snapshotting" section to learn about running +record/replay and creating the snapshot in these modes. + Replay log format ----------------- From patchwork Wed Oct 10 13:35:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981882 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42Vb124knyz9sB7 for ; Thu, 11 Oct 2018 00:44:06 +1100 (AEDT) Received: from localhost ([::1]:57354 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEmQ-0002nN-F7 for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:44:02 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34294) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEam-0002Sl-7q for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:32:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEaj-000343-Vq for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:32:00 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44298) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaj-00033Z-IA for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:31:57 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 9C81D540089; Wed, 10 Oct 2018 16:31:56 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:35:11 +0300 Message-ID: <20181010133511.24538.70006.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 17/19] replay: add BH oneshot event for block layer 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Replay is capable of recording normal BH events, but sometimes there are single use callbacks scheduled with aio_bh_schedule_oneshot function. This patch enables recording and replaying such callbacks. Block layer uses these events for calling the completion function. Replaying these calls makes the execution deterministic. Signed-off-by: Pavel Dovgalyuk --- v6: - moved stub function to the separate file for fixing linux-user build --- block/block-backend.c | 3 ++- include/sysemu/replay.h | 3 +++ replay/replay-events.c | 16 ++++++++++++++++ replay/replay-internal.h | 1 + replay/replay.c | 2 +- stubs/Makefile.objs | 1 + stubs/replay-user.c | 9 +++++++++ 7 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 stubs/replay-user.c diff --git a/block/block-backend.c b/block/block-backend.c index dc0cd57..04f5554 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -17,6 +17,7 @@ #include "block/throttle-groups.h" #include "sysemu/blockdev.h" #include "sysemu/sysemu.h" +#include "sysemu/replay.h" #include "qapi/error.h" #include "qapi/qapi-events-block.h" #include "qemu/id.h" @@ -1379,7 +1380,7 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes, acb->has_returned = true; if (acb->rwco.ret != NOT_DONE) { - aio_bh_schedule_oneshot(blk_get_aio_context(blk), + replay_bh_schedule_oneshot_event(blk_get_aio_context(blk), blk_aio_complete_bh, acb); } diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 05cb40a..5c71858 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -157,6 +157,9 @@ bool replay_events_enabled(void); void replay_flush_events(void); /*! Adds bottom half event to the queue */ void replay_bh_schedule_event(QEMUBH *bh); +/* Adds oneshot bottom half event to the queue */ +void replay_bh_schedule_oneshot_event(AioContext *ctx, + QEMUBHFunc *cb, void *opaque); /*! Adds input event to the queue */ void replay_input_event(QemuConsole *src, InputEvent *evt); /*! Adds input sync event to the queue */ diff --git a/replay/replay-events.c b/replay/replay-events.c index 0964a82..83a7d81 100644 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -37,6 +37,9 @@ static void replay_run_event(Event *event) case REPLAY_ASYNC_EVENT_BH: aio_bh_call(event->opaque); break; + case REPLAY_ASYNC_EVENT_BH_ONESHOT: + ((QEMUBHFunc*)event->opaque)(event->opaque2); + break; case REPLAY_ASYNC_EVENT_INPUT: qemu_input_event_send_impl(NULL, (InputEvent *)event->opaque); qapi_free_InputEvent((InputEvent *)event->opaque); @@ -132,6 +135,17 @@ void replay_bh_schedule_event(QEMUBH *bh) } } +void replay_bh_schedule_oneshot_event(AioContext *ctx, + QEMUBHFunc *cb, void *opaque) +{ + if (events_enabled) { + uint64_t id = replay_get_current_step(); + replay_add_event(REPLAY_ASYNC_EVENT_BH_ONESHOT, cb, opaque, id); + } else { + aio_bh_schedule_oneshot(ctx, cb, opaque); + } +} + void replay_add_input_event(struct InputEvent *event) { replay_add_event(REPLAY_ASYNC_EVENT_INPUT, event, NULL, 0); @@ -162,6 +176,7 @@ static void replay_save_event(Event *event, int checkpoint) /* save event-specific data */ switch (event->event_kind) { case REPLAY_ASYNC_EVENT_BH: + case REPLAY_ASYNC_EVENT_BH_ONESHOT: replay_put_qword(event->id); break; case REPLAY_ASYNC_EVENT_INPUT: @@ -216,6 +231,7 @@ static Event *replay_read_event(int checkpoint) /* Events that has not to be in the queue */ switch (replay_state.read_event_kind) { case REPLAY_ASYNC_EVENT_BH: + case REPLAY_ASYNC_EVENT_BH_ONESHOT: if (replay_state.read_event_id == -1) { replay_state.read_event_id = replay_get_qword(); } diff --git a/replay/replay-internal.h b/replay/replay-internal.h index e37b201..af2b941 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -51,6 +51,7 @@ enum ReplayEvents { enum ReplayAsyncEventKind { REPLAY_ASYNC_EVENT_BH, + REPLAY_ASYNC_EVENT_BH_ONESHOT, REPLAY_ASYNC_EVENT_INPUT, REPLAY_ASYNC_EVENT_INPUT_SYNC, REPLAY_ASYNC_EVENT_CHAR_READ, diff --git a/replay/replay.c b/replay/replay.c index c6d5de9..93d2573 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 0xe02007 +#define REPLAY_VERSION 0xe02008 /* Size of replay log header */ #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t)) diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 53d3f32..2acbac3 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -24,6 +24,7 @@ stub-obj-y += monitor.o stub-obj-y += notify-event.o stub-obj-y += qtest.o stub-obj-y += replay.o +stub-obj-y += replay-user.o stub-obj-y += runstate-check.o stub-obj-y += set-fd-handler.o stub-obj-y += slirp.o diff --git a/stubs/replay-user.c b/stubs/replay-user.c new file mode 100644 index 0000000..2ad9e27 --- /dev/null +++ b/stubs/replay-user.c @@ -0,0 +1,9 @@ +#include "qemu/osdep.h" +#include "sysemu/replay.h" +#include "sysemu/sysemu.h" + +void replay_bh_schedule_oneshot_event(AioContext *ctx, + QEMUBHFunc *cb, void *opaque) +{ + aio_bh_schedule_oneshot(ctx, cb, opaque); +} From patchwork Wed Oct 10 13:35:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981884 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42Vb1R1vJbz9sB7 for ; Thu, 11 Oct 2018 00:44:27 +1100 (AEDT) Received: from localhost ([::1]:57362 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEml-0003Cb-VV for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:44:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34327) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEaq-0002VJ-Rp for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:32:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEaq-00036p-2x for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:32:04 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44330) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEap-00036T-Ou for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:32:03 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 3B806540089; Wed, 10 Oct 2018 16:32:02 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:35:16 +0300 Message-ID: <20181010133516.24538.63822.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 18/19] replay: init rtc after enabling the replay 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch postpones the call of 'configure_rtc' function. This call uses host clock to configure the rtc, but host clock access should be recorded when using icount record/replay mode. Therefore now rtc is configured after switching record/replay mode on. Signed-off-by: Pavel Dovgalyuk --- vl.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/vl.c b/vl.c index a3e2e47..f910072 100644 --- a/vl.c +++ b/vl.c @@ -2932,6 +2932,7 @@ int main(int argc, char **argv, char **envp) DisplayState *ds; QemuOpts *opts, *machine_opts; QemuOpts *icount_opts = NULL, *accel_opts = NULL; + QemuOpts *rtc_opts = NULL; QemuOptsList *olist; int optind; const char *optarg; @@ -3738,12 +3739,11 @@ int main(int argc, char **argv, char **envp) warn_report("This option is ignored and will be removed soon"); break; case QEMU_OPTION_rtc: - opts = qemu_opts_parse_noisily(qemu_find_opts("rtc"), optarg, - false); - if (!opts) { + rtc_opts = qemu_opts_parse_noisily(qemu_find_opts("rtc"), + optarg, false); + if (!rtc_opts) { exit(1); } - configure_rtc(opts); break; case QEMU_OPTION_tb_size: #ifndef CONFIG_TCG @@ -3954,6 +3954,9 @@ int main(int argc, char **argv, char **envp) loc_set_none(); replay_configure(icount_opts); + if (rtc_opts) { + configure_rtc(rtc_opts); + } if (incoming && !preconfig_exit_requested) { error_report("'preconfig' and 'incoming' options are " From patchwork Wed Oct 10 13:35:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 981874 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ispras.ru Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VZxm47zfz9sCv for ; Thu, 11 Oct 2018 00:41:16 +1100 (AEDT) Received: from localhost ([::1]:57343 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEjh-0000Tj-V6 for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 09:41:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34342) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEay-0002bg-8U for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:32:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAEav-00038h-KN for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:32:12 -0400 Received: from mail.ispras.ru ([83.149.199.45]:44358) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAEav-00038O-CD for qemu-devel@nongnu.org; Wed, 10 Oct 2018 09:32:09 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 6CCB4540089; Wed, 10 Oct 2018 16:32:08 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 10 Oct 2018 16:35:22 +0300 Message-ID: <20181010133522.24538.48800.stgit@pasha-VirtualBox> In-Reply-To: <20181010133333.24538.53169.stgit@pasha-VirtualBox> References: <20181010133333.24538.53169.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v7 19/19] replay: document development rules 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: peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, zuban32s@gmail.com, kraxel@redhat.com, thomas.dullien@googlemail.com, artem.k.pisarenko@gmail.com, quintela@redhat.com, ciro.santilli@gmail.com, armbru@redhat.com, dovgaluk@ispras.ru, dgilbert@redhat.com, boost.lists@gmail.com, alex.bennee@linaro.org, rth@twiddle.net, kwolf@redhat.com, crosthwaite.peter@gmail.com, mreitz@redhat.com, maria.klimushenkova@ispras.ru, pbonzini@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch introduces docs/devel/replay.txt which describes the rules that should be followed to make virtual devices usable in record/replay mode. Signed-off-by: Pavel Dovgalyuk --- docs/devel/replay.txt | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 docs/devel/replay.txt diff --git a/docs/devel/replay.txt b/docs/devel/replay.txt new file mode 100644 index 0000000..61dac1b --- /dev/null +++ b/docs/devel/replay.txt @@ -0,0 +1,45 @@ +Record/replay mechanism, that could be enabled through icount mode, expects +the virtual devices to satisfy the following requirements. + +The main idea behind this document is that everything that affects +the guest state during execution in icount mode should be deterministic. + +Timers +====== + +All virtual devices should use virtual clock for timers that change the guest +state. Virtual clock is deterministic, therefore such timers are deterministic +too. + +Virtual devices can also use realtime clock for the events that do not change +the guest state directly. When the clock ticking should depend on VM execution +speed, use virtual ext clock. It is not deterministic, but its speed depends +on the guest execution. This clock is used by the virtual devices (e.g., +slirp routing device) that lie outside the replayed guest. + +Bottom halves +============= + +Bottom half callbacks, that affect the guest state, should be invoked through +replay_bh_schedule_event or replay_bh_schedule_oneshot_event functions. +Their invocations are saved in record mode and synchronized with the existing +log in replay mode. + +Saving/restoring the VM state +============================= + +All fields in the device state structure (including virtual timers) +should be restored by loadvm to the same values they had before savevm. + +Avoid accessing other devices' state, because the order of saving/restoring +is not defined. It means that you should not call functions like +'update_irq' in post_load callback. Save everything explicitly to avoid +the dependencies that may make restoring the VM state non-deterministic. + +Stopping the VM +=============== + +Stopping the guest should not interfere with its state (with the exception +of the network connections, that could be broken by the remote timeouts). +VM can be stopped at any moment of replay by the user. Restarting the VM +after that stop should not break the replay by the unneeded guest state change.