From patchwork Fri Jun 21 08:20:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120045 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXfs65Qqz9sND for ; Fri, 21 Jun 2019 18:59:01 +1000 (AEST) Received: from localhost ([::1]:55636 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFNr-0005jz-TQ for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:58:59 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58773) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzk-0004Ud-Qm for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:34:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEmr-0008Dc-8E for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:20:46 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41240) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEmr-0008DL-1T for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:20:45 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 3307D540082; Fri, 21 Jun 2019 11:20:44 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:20:43 +0300 Message-ID: <156110524358.25431.14663615410203260527.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 01/24] replay: add missing fix for internal function X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: pbonzini@redhat.com This is a fix which was missed by patch 74c0b816adfc6aa1b01b4426fdf385e32e35cbac, which added current_step parameter to the replay_advance_current_step function. Signed-off-by: Pavel Dovgalyuk --- replay/replay-internal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replay/replay-internal.c b/replay/replay-internal.c index 9e41ed1dcf..979f3a0b39 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -228,7 +228,7 @@ void replay_mutex_unlock(void) void replay_advance_current_step(uint64_t current_step) { - int diff = (int)(replay_get_current_step() - replay_state.current_step); + int diff = (int)(current_step - replay_state.current_step); /* Time can only go forward */ assert(diff >= 0); From patchwork Fri Jun 21 08:20:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120043 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXbQ4wThz9s3l for ; Fri, 21 Jun 2019 18:56:02 +1000 (AEST) Received: from localhost ([::1]:55610 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFKy-0001rO-OZ for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:56:00 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58773) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzi-0004Ud-EI for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:34:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEmw-0008JG-Ql for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:20:51 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41260) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEmw-0008Ie-KQ for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:20:50 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id C3FFC540089; Fri, 21 Jun 2019 11:20:49 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:20:49 +0300 Message-ID: <156110524960.25431.2828322789153003520.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 02/24] block: implement bdrv_snapshot_goto for blkreplay X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch enables making snapshots with blkreplay used in block devices. This function is required to make bdrv_snapshot_goto without calling .bdrv_open which is not implemented. Signed-off-by: Pavel Dovgalyuk Acked-by: Kevin Wolf --- block/blkreplay.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/block/blkreplay.c b/block/blkreplay.c index 2b7931b940..c96ac8f4bc 100644 --- a/block/blkreplay.c +++ b/block/blkreplay.c @@ -126,6 +126,12 @@ static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs) return ret; } +static int blkreplay_snapshot_goto(BlockDriverState *bs, + const char *snapshot_id) +{ + return bdrv_snapshot_goto(bs->file->bs, snapshot_id, NULL); +} + static BlockDriver bdrv_blkreplay = { .format_name = "blkreplay", .instance_size = 0, @@ -140,6 +146,8 @@ static BlockDriver bdrv_blkreplay = { .bdrv_co_pwrite_zeroes = blkreplay_co_pwrite_zeroes, .bdrv_co_pdiscard = blkreplay_co_pdiscard, .bdrv_co_flush = blkreplay_co_flush, + + .bdrv_snapshot_goto = blkreplay_snapshot_goto, }; static void bdrv_blkreplay_init(void) From patchwork Fri Jun 21 08:20:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120061 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VY966L14z9s4V for ; Fri, 21 Jun 2019 19:21:46 +1000 (AEST) Received: from localhost ([::1]:56490 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFjr-0001pm-RL for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 05:21:43 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58240) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEze-0004B9-5Y for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEn2-0008PV-IL for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:20:57 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41278) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEn2-0008P7-Bk for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:20:56 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 70F0D54008A; Fri, 21 Jun 2019 11:20:55 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:20:55 +0300 Message-ID: <156110525518.25431.4178984201371684282.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 03/24] replay: disable default snapshot for record/replay X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net 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 Acked-by: Kevin Wolf --- vl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/vl.c b/vl.c index 99a56b5556..8fcfd905ee 100644 --- a/vl.c +++ b/vl.c @@ -1208,7 +1208,7 @@ static void configure_blockdev(BlockdevOptionsQueue *bdo_queue, 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); } @@ -3128,7 +3128,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"), From patchwork Fri Jun 21 08:21:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120051 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXsK0DMlz9s3l for ; Fri, 21 Jun 2019 19:08:05 +1000 (AEST) Received: from localhost ([::1]:55732 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFWd-0006xq-3k for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 05:08:03 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58042) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzd-00044x-Uq for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEn8-00007p-5V for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:03 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41296) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEn7-00006F-VI for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:02 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 1A47554008B; Fri, 21 Jun 2019 11:21:01 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:00 +0300 Message-ID: <156110526089.25431.13065025960739413137.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 04/24] replay: update docs for record/replay with block devices X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 ee6aee9861..ce97c3f72f 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 Fri Jun 21 08:21:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120039 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXWH4pclz9sND for ; Fri, 21 Jun 2019 18:52:27 +1000 (AEST) Received: from localhost ([::1]:55586 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFHU-0005tr-0f for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:52:25 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58714) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzd-0004U0-SI for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEnD-0000EA-RU for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:08 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41318) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEnD-0000Du-HP for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:07 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id AD9DE54008C; Fri, 21 Jun 2019 11:21:06 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:06 +0300 Message-ID: <156110526652.25431.1704646168245762049.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 05/24] replay: don't drain/flush bdrv queue while RR is working X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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. Stopping the machine when the IO requests are not finished is needed for the debugging. E.g., breakpoint may be set at the specified step, and forcing the IO requests to finish may break the determinism of the execution. Signed-off-by: Pavel Dovgalyuk Acked-by: Kevin Wolf --- block/io.c | 28 ++++++++++++++++++++++++++++ cpus.c | 2 -- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/block/io.c b/block/io.c index 9ba1bada36..607abc04b0 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 */ @@ -539,6 +540,15 @@ 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()); @@ -567,6 +577,15 @@ 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); @@ -1934,6 +1953,15 @@ 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 dde3b7b981..0a44253523 100644 --- a/cpus.c +++ b/cpus.c @@ -1083,7 +1083,6 @@ static int do_vm_stop(RunState state, bool send_stop) } bdrv_drain_all(); - replay_disable_events(); ret = bdrv_flush_all(); return ret; @@ -2163,7 +2162,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 Fri Jun 21 08:21:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120049 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXpw4gByz9s3l for ; Fri, 21 Jun 2019 19:06:00 +1000 (AEST) Received: from localhost ([::1]:55700 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFUc-0004ST-81 for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 05:05:58 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58774) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzd-0004Ue-PM for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEnJ-0000Hj-Mn for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:14 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41336) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEnJ-0000HL-FR for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:13 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 50B31540093; Fri, 21 Jun 2019 11:21:12 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:12 +0300 Message-ID: <156110527210.25431.7121967728273636187.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 06/24] replay: finish record/replay before closing the disks X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 8b172b2d1b..b75820a1c1 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -385,6 +385,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 8fcfd905ee..4543fdab25 100644 --- a/vl.c +++ b/vl.c @@ -4562,6 +4562,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 Fri Jun 21 08:21:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120057 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VY5H2sPHz9s4V for ; Fri, 21 Jun 2019 19:18:26 +1000 (AEST) Received: from localhost ([::1]:56414 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFge-0007XP-33 for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 05:18:24 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58236) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzd-0004B8-DT for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEnP-0000M8-By for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:20 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41368) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEnP-0000LU-5b for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:19 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 4B7C8540082; Fri, 21 Jun 2019 11:21:18 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:18 +0300 Message-ID: <156110527803.25431.5528726255017654012.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 07/24] qcow2: introduce icount field for snapshots X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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) v10: - updated the documentation --- 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 d0e7fa9311..2c2e9bd8da 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -102,6 +102,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); @@ -208,6 +214,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 fc1b0d3c1e..a1d1118200 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -165,6 +165,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; @@ -178,6 +179,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 af5711e533..aa9d447cda 100644 --- a/docs/interop/qcow2.txt +++ b/docs/interop/qcow2.txt @@ -584,6 +584,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 instruction count + when the snapshot was taken + Version 3 images must include extra data at least up to byte 55. From patchwork Fri Jun 21 08:21:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120055 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VY1g1tGNz9s4V for ; Fri, 21 Jun 2019 19:15:19 +1000 (AEST) Received: from localhost ([::1]:55968 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFdd-0005Ww-1u for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 05:15:17 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58372) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzc-0004CE-KA for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEnV-0000OY-4H for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:26 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41388) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEnU-0000NY-Q5 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:25 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id EC7CF540089; Fri, 21 Jun 2019 11:21:23 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:23 +0300 Message-ID: <156110528374.25431.4241574362538931217.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 08/24] migration: introduce icount field for snapshots X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 proceeding the recorded execution to the specific moment of the time. E.g., 'reverse step' action (introduced in one of the following patches) needs to load the nearest snapshot which is prior to the current moment of time . Signed-off-by: Pavel Dovgalyuk Acked-by: Markus Armbruster --- v2: - made icount in SnapshotInfo optional (suggested by Eric Blake) v7: - added more comments for icount member (suggested by Markus Armbruster) v9: - updated icount comment v10: - updated icount comment again --- block/qapi.c | 18 ++++++++++++++---- 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, 40 insertions(+), 6 deletions(-) diff --git a/block/qapi.c b/block/qapi.c index 917435f022..60295abf09 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -214,6 +214,8 @@ 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->has_icount = sn_tab[i].icount != -1ULL; info_list = g_new0(SnapshotInfoList, 1); info_list->value = info; @@ -635,14 +637,15 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes, void bdrv_snapshot_dump(QEMUSnapshotInfo *sn) { char date_buf[128], clock_buf[128]; + char icount_buf[128] = {0}; struct tm tm; time_t ti; int64_t secs; char *sizing = NULL; if (!sn) { - qemu_printf("%-10s%-20s%7s%20s%15s", - "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); + qemu_printf("%-10s%-18s%7s%20s%13s%11s", + "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT"); } else { ti = sn->date_sec; localtime_r(&ti, &tm); @@ -656,11 +659,16 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn) (int)(secs % 60), (int)((sn->vm_clock_nsec / 1000000) % 1000)); sizing = size_to_str(sn->vm_state_size); - qemu_printf("%-10s%-20s%7s%20s%15s", + if (sn->icount != -1ULL) { + snprintf(icount_buf, sizeof(icount_buf), + "%"PRId64, sn->icount); + } + qemu_printf("%-10s%-18s%7s%20s%13s%11s", sn->id_str, sn->name, sizing, date_buf, - clock_buf); + clock_buf, + icount_buf); } g_free(sizing); } @@ -822,6 +830,8 @@ void bdrv_image_info_dump(ImageInfo *info) .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 2c2e9bd8da..7a3f4fc4f7 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -377,6 +377,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)); @@ -708,6 +709,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 5d6a13dea9..7bd6930eed 100644 --- a/blockdev.c +++ b/blockdev.c @@ -58,6 +58,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" @@ -1241,6 +1242,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; @@ -1448,6 +1453,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 b5d5084a12..deeb24c22c 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 c0e557b4c2..a113cc187d 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2601,6 +2601,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 0d43d4f37c..2c23214505 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 4.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 145c268bb6..f389bb6f1a 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 Fri Jun 21 08:21:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120048 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXlN2bYpz9sND for ; Fri, 21 Jun 2019 19:02:56 +1000 (AEST) Received: from localhost ([::1]:55684 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFRe-0001ZH-C5 for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 05:02:54 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58773) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzc-0004Ud-Bz for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEnb-0000UL-Bv for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:33 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41414) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEnb-0000TO-5E for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:31 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 8FEEE540094; Fri, 21 Jun 2019 11:21:29 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:29 +0300 Message-ID: <156110528936.25431.18200323929081559117.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 09/24] replay: provide an accessor for rr filename X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 3a7c58e423..b3f593f2f0 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 b75820a1c1..aa534116b5 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -394,3 +394,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 Fri Jun 21 08:21:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120050 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXqS3zZFz9s3l for ; Fri, 21 Jun 2019 19:06:28 +1000 (AEST) Received: from localhost ([::1]:55712 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFV4-00054X-Jj for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 05:06:26 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58774) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzc-0004Ue-8P for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEni-0000X5-Bo for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:41 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41438) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEnh-0000WN-64 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:38 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 2FC0E5400A7; Fri, 21 Jun 2019 11:21:35 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:35 +0300 Message-ID: <156110529498.25431.8092482831115514702.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 10/24] qapi: introduce replay.json for record/replay-related stuff X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch adds replay.json file. It will be used for adding record/replay-related data structures and commands. Signed-off-by: Pavel Dovgalyuk Reviewed-by: Markus Armbruster --- v10: - minor changes v13: - rebased to the new QAPI files --- MAINTAINERS | 1 + include/sysemu/replay.h | 2 +- qapi/Makefile.objs | 2 +- qapi/misc.json | 18 ------------------ qapi/qapi-schema.json | 1 + qapi/replay.json | 26 ++++++++++++++++++++++++++ 6 files changed, 30 insertions(+), 20 deletions(-) create mode 100644 qapi/replay.json diff --git a/MAINTAINERS b/MAINTAINERS index d32c5c2313..1a3b518ee8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2234,6 +2234,7 @@ F: net/filter-replay.c F: include/sysemu/replay.h F: docs/replay.txt F: stubs/replay.c +F: qapi/replay.json IOVA Tree M: Peter Xu diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index b3f593f2f0..3fe14b5f57 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -13,7 +13,7 @@ */ #include "sysemu.h" -#include "qapi/qapi-types-misc.h" +#include "qapi/qapi-types-replay.h" #include "qapi/qapi-types-ui.h" /* replay clock kinds */ diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs index 729e5185c5..ee77aac9b9 100644 --- a/qapi/Makefile.objs +++ b/qapi/Makefile.objs @@ -6,7 +6,7 @@ util-obj-y += qmp-event.o util-obj-y += qapi-util.o QAPI_COMMON_MODULES = audio authz block-core block char common crypto -QAPI_COMMON_MODULES += introspect job migration misc net rdma rocker +QAPI_COMMON_MODULES += introspect job migration misc net rdma replay rocker QAPI_COMMON_MODULES += run-state sockets tpm trace transaction ui QAPI_TARGET_MODULES = target QAPI_MODULES = $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES) diff --git a/qapi/misc.json b/qapi/misc.json index dc4cf9da20..9230c45832 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -2872,24 +2872,6 @@ { 'event': 'ACPI_DEVICE_OST', 'data': { 'info': 'ACPIOSTInfo' } } -## -# @ReplayMode: -# -# Mode of the replay subsystem. -# -# @none: normal execution mode. Replay or record are not enabled. -# -# @record: record mode. All non-deterministic data is written into the -# replay log. -# -# @play: replay mode. Non-deterministic data required for system execution -# is read from the log. -# -# Since: 2.5 -## -{ 'enum': 'ReplayMode', - 'data': [ 'none', 'record', 'play' ] } - ## # @xen-load-devices-state: # diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index 4bd1223637..3bd5bc1320 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -97,6 +97,7 @@ { 'include': 'transaction.json' } { 'include': 'trace.json' } { 'include': 'introspect.json' } +{ 'include': 'replay.json' } { 'include': 'misc.json' } { 'include': 'target.json' } { 'include': 'audio.json' } diff --git a/qapi/replay.json b/qapi/replay.json new file mode 100644 index 0000000000..9e13551d20 --- /dev/null +++ b/qapi/replay.json @@ -0,0 +1,26 @@ +# -*- Mode: Python -*- +# + +## +# = Record/replay +## + +{ 'include': 'common.json' } + +## +# @ReplayMode: +# +# Mode of the replay subsystem. +# +# @none: normal execution mode. Replay or record are not enabled. +# +# @record: record mode. All non-deterministic data is written into the +# replay log. +# +# @play: replay mode. Non-deterministic data required for system execution +# is read from the log. +# +# Since: 2.5 +## +{ 'enum': 'ReplayMode', + 'data': [ 'none', 'record', 'play' ] } From patchwork Fri Jun 21 08:21:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120054 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXyZ0WFjz9s3l for ; Fri, 21 Jun 2019 19:12:35 +1000 (AEST) Received: from localhost ([::1]:55814 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFau-0001uv-MD for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 05:12:28 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58308) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzc-0004Ba-70 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEnm-0000Yb-69 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:43 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41462) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEnl-0000YC-QF for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:42 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id C69805400A8; Fri, 21 Jun 2019 11:21:40 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:40 +0300 Message-ID: <156110530060.25431.15168713525023490860.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 11/24] replay: introduce info hmp/qmp command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 instruction count (number of recorded/replayed instructions). The instruction count can be used with the replay_seek/replay_break commands added in the next two patches. Signed-off-by: Pavel Dovgalyuk Acked-by: Dr. David Alan Gilbert Acked-by: Markus Armbruster --- v2: - renamed info_replay qmp into query-replay (suggested by Eric Blake) v7: - added empty line (suggested by Markus Armbruster) v9: - changed 'step' parameter name to 'icount' - moved json stuff to replay.json and updated the descriptions (suggested by Markus Armbruster) v10: - updated descriptions and messages for rr stuff --- hmp-commands-info.hx | 14 ++++++++++++++ hmp.h | 1 + qapi/block-core.json | 3 ++- qapi/replay.json | 39 +++++++++++++++++++++++++++++++++++++++ replay/Makefile.objs | 3 ++- replay/replay-debugging.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 replay/replay-debugging.c diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index c59444c461..0b3b7aff95 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -930,6 +930,20 @@ STEXI @item info sev @findex info sev Show SEV information. +ETEXI + + { + .name = "replay", + .args_type = "", + .params = "", + .help = "show record/replay information", + .cmd = hmp_info_replay, + }, + +STEXI +@item info replay +@findex info replay +Display the record/replay information: mode and the current icount. ETEXI STEXI diff --git a/hmp.h b/hmp.h index 1d095d5837..717b01d951 100644 --- a/hmp.h +++ b/hmp.h @@ -149,5 +149,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/block-core.json b/qapi/block-core.json index 2c23214505..d78594f73f 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -28,7 +28,8 @@ # # @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 4.1) +# in the recorded execution with the snapshots. This counter may +# be obtained through @query-replay command (since 4.1) # # Since: 1.3 # diff --git a/qapi/replay.json b/qapi/replay.json index 9e13551d20..3f29c3c1fe 100644 --- a/qapi/replay.json +++ b/qapi/replay.json @@ -24,3 +24,42 @@ ## { 'enum': 'ReplayMode', 'data': [ 'none', 'record', 'play' ] } + +## +# @ReplayInfo: +# +# Record/replay information. +# +# @mode: current mode. +# +# @filename: name of the record/replay log file. +# It is present only in record or replay modes, when the log +# is recorded or replayed. +# +# @icount: current number of executed instructions. +# +# Since: 4.1 +# +## +{ 'struct': 'ReplayInfo', + 'data': { 'mode': 'ReplayMode', '*filename': 'str', 'icount': 'int' } } + +## +# @query-replay: +# +# Retrieve the record/replay information. +# It includes current instruction count which may be used for +# @replay-break and @replay-seek commands. +# +# Returns: record/replay information. +# +# Since: 4.1 +# +# Example: +# +# -> { "execute": "query-replay" } +# <- { "return": { "mode": "play", "filename": "log.rr", "icount": 220414 } } +# +## +{ 'command': 'query-replay', + 'returns': 'ReplayInfo' } diff --git a/replay/Makefile.objs b/replay/Makefile.objs index cee6539a23..6694e3e2a2 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 0000000000..51f1c4d82d --- /dev/null +++ b/replay/replay-debugging.c @@ -0,0 +1,43 @@ +/* + * 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-replay.h" + +void hmp_info_replay(Monitor *mon, const QDict *qdict) +{ + if (replay_mode == REPLAY_MODE_NONE) { + monitor_printf(mon, "Record/replay is not active\n"); + } else { + monitor_printf(mon, + "%s execution '%s': instruction count = %"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->icount = replay_get_current_step(); + return retval; +} From patchwork Fri Jun 21 08:21:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120012 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXJc40gDz9sPP for ; Fri, 21 Jun 2019 18:43:12 +1000 (AEST) Received: from localhost ([::1]:55558 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heF8Y-0001fx-F4 for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:43:10 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58240) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzc-0004B9-75 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEnr-0000aS-TW for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:49 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41490) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEnr-0000aM-Hn for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:47 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 726445400A9; Fri, 21 Jun 2019 11:21:46 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:46 +0300 Message-ID: <156110530622.25431.335577612189834194.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 12/24] replay: introduce breakpoint at the specified step X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 Acked-by: Markus Armbruster --- v2: - renamed replay_break qmp command into replay-break (suggested by Eric Blake) v7: - introduces replay_delete_break command v9: - changed 'step' parameter name to 'icount' - moved json stuff to replay.json and updated the description (suggested by Markus Armbruster) v10: - updated descriptions (suggested by Markus Armbruster) --- hmp-commands.hx | 34 ++++++++++++++++++ hmp.h | 2 + qapi/replay.json | 36 +++++++++++++++++++ replay/replay-debugging.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ replay/replay-internal.h | 4 ++ replay/replay.c | 17 +++++++++ 6 files changed, 179 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 8b7aec3e8d..96f89a13c2 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1926,6 +1926,40 @@ ETEXI STEXI @item qom-set @var{path} @var{property} @var{value} Set QOM property @var{property} of object at location @var{path} to value @var{value} +ETEXI + + { + .name = "replay_break", + .args_type = "icount:i", + .params = "icount", + .help = "set breakpoint at the specified instruction count", + .cmd = hmp_replay_break, + }, + +STEXI +@item replay_break @var{icount} +@findex replay_break +Set replay breakpoint at instruction count @var{icount}. +Execution stops when the specified instruction is reached. +There can be at most one breakpoint. When breakpoint is set, any prior +one is removed. The breakpoint may be set only in replay mode and only +"in the future", i.e. at instruction counts greater than the current one. +The current instruction count can be observed with 'info replay'. +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 +Remove replay breakpoint which was previously set with replay_break. +The command is ignored when there are no replay breakpoints. ETEXI { diff --git a/hmp.h b/hmp.h index 717b01d951..80967f5bd6 100644 --- a/hmp.h +++ b/hmp.h @@ -150,5 +150,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/replay.json b/qapi/replay.json index 3f29c3c1fe..425e053e4d 100644 --- a/qapi/replay.json +++ b/qapi/replay.json @@ -63,3 +63,39 @@ ## { 'command': 'query-replay', 'returns': 'ReplayInfo' } + +## +# @replay-break: +# +# Set replay breakpoint at instruction count @icount. +# Execution stops when the specified instruction is reached. +# There can be at most one breakpoint. When breakpoint is set, any prior +# one is removed. The breakpoint may be set only in replay mode and only +# "in the future", i.e. at instruction counts greater than the current one. +# The current instruction count can be observed with @query-replay. +# +# @icount: instruction count to stop at +# +# Since: 4.1 +# +# Example: +# +# -> { "execute": "replay-break", "data": { "icount": 220414 } } +# +## +{ 'command': 'replay-break', 'data': { 'icount': 'int' } } + +## +# @replay-delete-break: +# +# Remove replay breakpoint which was set with @replay-break. +# The command is ignored when there are no replay breakpoints. +# +# Since: 4.1 +# +# Example: +# +# -> { "execute": "replay-delete-break" } +# +## +{ 'command': 'replay-delete-break' } diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index 51f1c4d82d..a94685e437 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-replay.h" +#include "qapi/qmp/qdict.h" +#include "qemu/timer.h" void hmp_info_replay(Monitor *mon, const QDict *qdict) { @@ -41,3 +43,87 @@ ReplayInfo *qmp_query_replay(Error **errp) retval->icount = replay_get_current_step(); return retval; } + +static void replay_break(uint64_t icount, QEMUTimerCB callback, void *opaque) +{ + assert(replay_mode == REPLAY_MODE_PLAY); + assert(replay_mutex_locked()); + assert(replay_break_icount >= replay_get_current_step()); + assert(callback); + + replay_break_icount = icount; + + 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_icount = -1ULL; +} + +static void replay_stop_vm(void *opaque) +{ + vm_stop(RUN_STATE_PAUSED); + replay_delete_break(); +} + +void qmp_replay_break(int64_t icount, Error **errp) +{ + if (replay_mode == REPLAY_MODE_PLAY) { + if (icount >= replay_get_current_step()) { + replay_break(icount, replay_stop_vm, NULL); + } else { + error_setg(errp, + "cannot set breakpoint at the instruction 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 icount = qdict_get_try_int(qdict, "icount", -1LL); + Error *err = NULL; + + qmp_replay_break(icount, &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 af6f4d55d4..8c15a41350 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; +/* Instruction count of the replay breakpoint */ +extern uint64_t replay_break_icount; +/* 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 aa534116b5..1be34aa824 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_icount = -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_icount != -1LL) { + uint64_t current = replay_get_current_step(); + assert(replay_break_icount >= current); + if (current + res > replay_break_icount) { + res = replay_break_icount - 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_icount == 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 Fri Jun 21 08:21:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120052 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXsj58CKz9s3l for ; Fri, 21 Jun 2019 19:08:25 +1000 (AEST) Received: from localhost ([::1]:55736 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFWx-0007DS-PV for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 05:08:23 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58714) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzc-0004U0-68 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEo0-0000lG-Ex for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:58 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41526) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEnx-0000hR-KW for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:21:54 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 4E16A54006B; Fri, 21 Jun 2019 11:21:52 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:52 +0300 Message-ID: <156110531211.25431.13446532508590348128.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 13/24] replay: implement replay-seek command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch adds hmp/qmp commands replay_seek/replay-seek that proceed the execution to the specified instruction count. The command automatically loads nearest snapshot and replays the execution to find the desired instruction count. Signed-off-by: Pavel Dovgalyuk Acked-by: Markus Armbruster --- v2: - renamed replay_seek qmp command into replay-seek (suggested by Eric Blake) v7: - small fixes related to Markus Armbruster's review v9: - changed 'step' parameter name to 'icount' - moved json stuff to replay.json and updated the description (suggested by Markus Armbruster) v10: - updated the descriptions --- hmp-commands.hx | 19 +++++++++ hmp.h | 1 qapi/replay.json | 20 ++++++++++ replay/replay-debugging.c | 92 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 96f89a13c2..d812bb290f 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1960,6 +1960,25 @@ STEXI @findex replay_delete_break Remove replay breakpoint which was previously set with replay_break. The command is ignored when there are no replay breakpoints. +ETEXI + + { + .name = "replay_seek", + .args_type = "icount:i", + .params = "icount", + .help = "replay execution to the specified instruction count", + .cmd = hmp_replay_seek, + }, + +STEXI +@item replay_seek @var{icount} +@findex replay_seek +Automatically proceed to the instruction count @var{icount}, when +replaying the execution. The command automatically loads nearest +snapshot and replays the execution to find the desired instruction. +When there is no preceding snapshot or the execution is not replayed, +then the command fails. +icount for the reference may be observed with 'info replay' command. ETEXI { diff --git a/hmp.h b/hmp.h index 80967f5bd6..e03fb41ac3 100644 --- a/hmp.h +++ b/hmp.h @@ -152,5 +152,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/replay.json b/qapi/replay.json index 425e053e4d..aa768d496c 100644 --- a/qapi/replay.json +++ b/qapi/replay.json @@ -99,3 +99,23 @@ # ## { 'command': 'replay-delete-break' } + +## +# @replay-seek: +# +# Automatically proceed to the instruction count @icount, when +# replaying the execution. The command automatically loads nearest +# snapshot and replays the execution to find the desired instruction. +# When there is no preceding snapshot or the execution is not replayed, +# then the command fails. +# icount for the reference may be obtained with @query-replay command. +# +# @icount: target instruction count +# +# Since: 4.1 +# +# Example: +# +# -> { "execute": "replay-seek", "data": { "icount": 220414 } } +## +{ 'command': 'replay-seek', 'data': { 'icount': 'int' } } diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index a94685e437..e3821ab1ba 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -18,6 +18,8 @@ #include "qapi/qapi-commands-replay.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) { @@ -127,3 +129,93 @@ void hmp_replay_delete_break(Monitor *mon, const QDict *qdict) return; } } + +static char *replay_find_nearest_snapshot(int64_t icount, + int64_t *snapshot_icount) +{ + BlockDriverState *bs; + QEMUSnapshotInfo *sn_tab; + QEMUSnapshotInfo *nearest = NULL; + char *ret = NULL; + int nb_sns, i; + AioContext *aio_context; + + *snapshot_icount = -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 <= icount + && (!nearest || nearest->icount < sn_tab[i].icount)) { + nearest = &sn_tab[i]; + } + } + } + if (nearest) { + ret = g_strdup(nearest->name); + *snapshot_icount = nearest->icount; + } + g_free(sn_tab); + +fail: + return ret; +} + +static void replay_seek(int64_t icount, QEMUTimerCB callback, Error **errp) +{ + char *snapshot = NULL; + int64_t snapshot_icount; + + 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(icount, &snapshot_icount); + if (snapshot) { + if (icount < replay_get_current_step() + || replay_get_current_step() < snapshot_icount) { + vm_stop(RUN_STATE_RESTORE_VM); + load_snapshot(snapshot, errp); + } + g_free(snapshot); + } + if (replay_get_current_step() <= icount) { + replay_break(icount, callback, NULL); + vm_start(); + } else { + error_setg(errp, "cannot seek to the specified instruction count"); + } +} + +void qmp_replay_seek(int64_t icount, Error **errp) +{ + replay_seek(icount, replay_stop_vm, errp); +} + +void hmp_replay_seek(Monitor *mon, const QDict *qdict) +{ + int64_t icount = qdict_get_try_int(qdict, "icount", -1LL); + Error *err = NULL; + + qmp_replay_seek(icount, &err); + if (err) { + error_report_err(err); + error_free(err); + return; + } +} From patchwork Fri Jun 21 08:21:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120044 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXfp2KjCz9sNR for ; Fri, 21 Jun 2019 18:58:57 +1000 (AEST) Received: from localhost ([::1]:55630 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFNn-0005YU-6P for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:58:55 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58236) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzc-0004B8-5b for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEo6-0000qv-89 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:04 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41546) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEo4-0000ni-9z for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:01 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id DA02054006B; Fri, 21 Jun 2019 11:21:57 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:21:57 +0300 Message-ID: <156110531770.25431.1723541151762958457.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 14/24] replay: refine replay-time module X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch removes refactoring artifacts from the replay/replay-time.c Signed-off-by: Pavel Dovgalyuk --- replay/replay-time.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/replay/replay-time.c b/replay/replay-time.c index 5154cb0ce9..49c9e5d8b2 100644 --- a/replay/replay-time.c +++ b/replay/replay-time.c @@ -14,18 +14,19 @@ #include "replay-internal.h" #include "qemu/error-report.h" -int64_t replay_save_clock(ReplayClockKind kind, int64_t clock, int64_t raw_icount) +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; } @@ -47,20 +48,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 Fri Jun 21 08:22:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120037 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXVQ6xd7z9s3l for ; Fri, 21 Jun 2019 18:51:42 +1000 (AEST) Received: from localhost ([::1]:55580 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFGl-0005gF-3q for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:51:41 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58774) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEza-0004Ue-SB for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEoC-0000wq-4C for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:09 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41570) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEoA-0000sM-45 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:06 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 76A6154006B; Fri, 21 Jun 2019 11:22:03 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:22:03 +0300 Message-ID: <156110532327.25431.17706154271325991738.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 15/24] replay: flush rr queue before loading the vmstate X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 | 6 ++++++ replay/replay-internal.h | 2 -- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 3fe14b5f57..d7e859d915 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 a113cc187d..053f470eea 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2793,6 +2793,12 @@ 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 8c15a41350..945802361b 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 Fri Jun 21 08:22:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120042 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXb24svGz9s3l for ; Fri, 21 Jun 2019 18:55:42 +1000 (AEST) Received: from localhost ([::1]:55608 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFKe-0001jL-OX for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:55:40 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58372) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEza-0004CE-S3 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEoE-00010x-B0 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:11 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41600) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEoD-00010J-V7 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:10 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 17A7E54006B; Fri, 21 Jun 2019 11:22:09 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:22:08 +0300 Message-ID: <156110532889.25431.10442246764810242357.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 16/24] gdbstub: add reverse step support in replay mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 | 7 ++++++ gdbstub.c | 56 +++++++++++++++++++++++++++++++++++++++++++-- include/sysemu/replay.h | 11 +++++++++ replay/replay-debugging.c | 33 +++++++++++++++++++++++++++ stubs/replay.c | 5 ++++ 7 files changed, 121 insertions(+), 6 deletions(-) diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index 9226a348a3..708bbedd43 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -16,6 +16,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 0a44253523..c2356f9836 100644 --- a/cpus.c +++ b/cpus.c @@ -1109,9 +1109,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 e7622d1956..ee21e6de34 100644 --- a/exec.c +++ b/exec.c @@ -2816,6 +2816,13 @@ 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 8618e34311..2fe718d0b7 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -43,6 +43,7 @@ #include "sysemu/kvm.h" #include "hw/semihosting/semihost.h" #include "exec/exec-all.h" +#include "sysemu/replay.h" #ifdef CONFIG_USER_ONLY #define GDB_ATTACHED "0" @@ -364,6 +365,20 @@ 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; @@ -454,7 +469,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; @@ -473,7 +488,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; @@ -1826,10 +1841,31 @@ static void handle_step(GdbCmdContext *gdb_ctx, void *user_ctx) gdb_set_cpu_pc(gdb_ctx->s, (target_ulong)gdb_ctx->params[0].val_ull); } - cpu_single_step(gdb_ctx->s->c_cpu, sstep_flags); + cpu_single_step(gdb_ctx->s->c_cpu, get_sstep_flags()); gdb_continue(gdb_ctx->s); } +static void handle_backward(GdbCmdContext *gdb_ctx, void *user_ctx) +{ + if (replay_mode != REPLAY_MODE_PLAY) { + put_packet(gdb_ctx->s, "E22"); + } + if (gdb_ctx->num_params == 1) { + switch (gdb_ctx->params[0].opcode) { + case 's': + if (replay_reverse_step()) { + gdb_continue(gdb_ctx->s); + } else { + put_packet(gdb_ctx->s, "E14"); + } + return; + } + } + + /* Default invalid command */ + put_packet(gdb_ctx->s, ""); +} + static void handle_v_cont_query(GdbCmdContext *gdb_ctx, void *user_ctx) { put_packet(gdb_ctx->s, "vCont;c;C;s;S"); @@ -2084,6 +2120,9 @@ static void handle_query_supported(GdbCmdContext *gdb_ctx, void *user_ctx) pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";qXfer:features:read+"); } + if (replay_mode == REPLAY_MODE_PLAY) { + pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";ReverseStep+"); + } if (gdb_ctx->num_params && strstr(gdb_ctx->params[0].data, "multiprocess+")) { @@ -2423,6 +2462,17 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) cmd_parser = &step_cmd_desc; } break; + case 'b': + { + static const GdbCmdParseEntry backward_cmd_desc = { + .handler = handle_backward, + .cmd = "b", + .cmd_startswith = 1, + .schema = "o0" + }; + cmd_parser = &backward_cmd_desc; + } + break; case 'F': { static const GdbCmdParseEntry file_io_cmd_desc = { diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index d7e859d915..533003f2b0 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -73,6 +73,17 @@ 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 e3821ab1ba..3d94859b8f 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) { @@ -219,3 +226,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_delete_break(); +} + +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 4ac607895d..521552fa83 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 Fri Jun 21 08:22:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120010 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXBC4z8lz9s3l for ; Fri, 21 Jun 2019 18:37:39 +1000 (AEST) Received: from localhost ([::1]:55532 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heF3B-0005Sf-No for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:37:37 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58773) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEza-0004Ud-Re for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEoJ-0001A2-Rj for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:17 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41622) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEoJ-00019Z-Hh for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:15 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id ADC5754006B; Fri, 21 Jun 2019 11:22:14 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:22:14 +0300 Message-ID: <156110533452.25431.5472128681314713978.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 17/24] gdbstub: add reverse continue support in replay mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 | 5 +++ exec.c | 1 + gdbstub.c | 9 +++++- include/sysemu/replay.h | 8 +++++ replay/replay-debugging.c | 71 +++++++++++++++++++++++++++++++++++++++++++++ stubs/replay.c | 5 +++ 6 files changed, 98 insertions(+), 1 deletion(-) diff --git a/cpus.c b/cpus.c index c2356f9836..e0e61abe64 100644 --- a/cpus.c +++ b/cpus.c @@ -1115,6 +1115,11 @@ 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 ee21e6de34..b3c70f8c9a 100644 --- a/exec.c +++ b/exec.c @@ -2821,6 +2821,7 @@ static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags) * 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 2fe718d0b7..8d4cd3cf6e 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1859,6 +1859,13 @@ static void handle_backward(GdbCmdContext *gdb_ctx, void *user_ctx) put_packet(gdb_ctx->s, "E14"); } return; + case 'c': + if (replay_reverse_continue()) { + gdb_continue(gdb_ctx->s); + } else { + put_packet(gdb_ctx->s, "E14"); + } + return; } } @@ -2121,7 +2128,7 @@ static void handle_query_supported(GdbCmdContext *gdb_ctx, void *user_ctx) ";qXfer:features:read+"); } if (replay_mode == REPLAY_MODE_PLAY) { - pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";ReverseStep+"); + pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";ReverseStep+;ReverseContinue+"); } if (gdb_ctx->num_params && diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 533003f2b0..1d18c9b6ea 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -79,11 +79,19 @@ const char *replay_get_filename(void); * 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 3d94859b8f..abb5fe687f 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) { @@ -252,3 +254,72 @@ bool replay_reverse_step(void) return false; } + +static void replay_continue_end(void) +{ + replay_is_debugging = false; + vm_stop(RUN_STATE_DEBUG); + replay_delete_break(); +} + +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 521552fa83..ee649726f4 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 Fri Jun 21 08:22:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120013 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXJc1pc0z9sNf for ; Fri, 21 Jun 2019 18:43:12 +1000 (AEST) Received: from localhost ([::1]:55556 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heF8Y-0001fU-98 for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:43:10 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58236) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEza-0004B8-5M for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEoP-0001FQ-CI for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:22 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41636) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEoP-0001EU-5v for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:21 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 4BBC7540082; Fri, 21 Jun 2019 11:22:20 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:22:20 +0300 Message-ID: <156110534010.25431.470716625287653564.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 18/24] replay: describe reverse debugging in docs/replay.txt X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 ce97c3f72f..47b4f2d9f8 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 Fri Jun 21 08:22:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120041 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXZm6CSDz9s3l for ; Fri, 21 Jun 2019 18:55:28 +1000 (AEST) Received: from localhost ([::1]:55602 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFKQ-0001Zk-MT for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:55:26 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58714) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzZ-0004U0-40 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEoV-0001LZ-86 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:28 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41678) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEoU-0001Kn-Pr for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:27 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id E684654006B; Fri, 21 Jun 2019 11:22:25 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:22:25 +0300 Message-ID: <156110534575.25431.11422229329017810805.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 19/24] replay: add BH oneshot event for block layer X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 Acked-by: Kevin Wolf --- v6: - moved stub function to the separate file for fixing linux-user build v10: - replaced all block layer aio_bh_schedule_oneshot calls --- block/block-backend.c | 8 +++++--- block/io.c | 4 ++-- block/iscsi.c | 5 +++-- block/nfs.c | 5 +++-- block/null.c | 4 +++- block/nvme.c | 6 ++++-- block/rbd.c | 5 +++-- block/vxhs.c | 5 +++-- 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 +++++++++ 14 files changed, 57 insertions(+), 17 deletions(-) create mode 100644 stubs/replay-user.c diff --git a/block/block-backend.c b/block/block-backend.c index a8d160fd5d..2cd1b0e761 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" @@ -1296,7 +1297,8 @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk, acb->blk = blk; acb->ret = ret; - aio_bh_schedule_oneshot(blk_get_aio_context(blk), error_callback_bh, acb); + replay_bh_schedule_oneshot_event(blk_get_aio_context(blk), + error_callback_bh, acb); return &acb->common; } @@ -1352,8 +1354,8 @@ 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), - blk_aio_complete_bh, acb); + replay_bh_schedule_oneshot_event(blk_get_aio_context(blk), + blk_aio_complete_bh, acb); } return &acb->common; diff --git a/block/io.c b/block/io.c index 607abc04b0..5ec1e33cb5 100644 --- a/block/io.c +++ b/block/io.c @@ -340,8 +340,8 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, if (bs) { bdrv_inc_in_flight(bs); } - aio_bh_schedule_oneshot(bdrv_get_aio_context(bs), - bdrv_co_drain_bh_cb, &data); + replay_bh_schedule_oneshot_event(bdrv_get_aio_context(bs), + bdrv_co_drain_bh_cb, &data); qemu_coroutine_yield(); /* If we are resumed from some other event (such as an aio completion or a diff --git a/block/iscsi.c b/block/iscsi.c index 267f160bf6..a6645f04b5 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -40,6 +40,7 @@ #include "qemu/module.h" #include "qemu/option.h" #include "qemu/uuid.h" +#include "sysemu/replay.h" #include "qapi/error.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qmp/qdict.h" @@ -281,8 +282,8 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status, out: if (iTask->co) { - aio_bh_schedule_oneshot(iTask->iscsilun->aio_context, - iscsi_co_generic_bh_cb, iTask); + replay_bh_schedule_oneshot_event(iTask->iscsilun->aio_context, + iscsi_co_generic_bh_cb, iTask); } else { iTask->complete = 1; } diff --git a/block/nfs.c b/block/nfs.c index d93241b3bb..cfd6c956b3 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -37,6 +37,7 @@ #include "qemu/uri.h" #include "qemu/cutils.h" #include "sysemu/sysemu.h" +#include "sysemu/replay.h" #include "qapi/qapi-visit-block-core.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qstring.h" @@ -257,8 +258,8 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data, if (task->ret < 0) { error_report("NFS Error: %s", nfs_get_error(nfs)); } - aio_bh_schedule_oneshot(task->client->aio_context, - nfs_co_generic_bh_cb, task); + replay_bh_schedule_oneshot_event(task->client->aio_context, + nfs_co_generic_bh_cb, task); } static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, uint64_t offset, diff --git a/block/null.c b/block/null.c index 699aa295cb..15e1d56746 100644 --- a/block/null.c +++ b/block/null.c @@ -17,6 +17,7 @@ #include "qemu/module.h" #include "qemu/option.h" #include "block/block_int.h" +#include "sysemu/replay.h" #define NULL_OPT_LATENCY "latency-ns" #define NULL_OPT_ZEROES "read-zeroes" @@ -179,7 +180,8 @@ static inline BlockAIOCB *null_aio_common(BlockDriverState *bs, timer_mod_ns(&acb->timer, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + s->latency_ns); } else { - aio_bh_schedule_oneshot(bdrv_get_aio_context(bs), null_bh_cb, acb); + replay_bh_schedule_oneshot_event(bdrv_get_aio_context(bs), + null_bh_cb, acb); } return &acb->common; } diff --git a/block/nvme.c b/block/nvme.c index 73ed5fa75f..6607cac024 100644 --- a/block/nvme.c +++ b/block/nvme.c @@ -22,6 +22,7 @@ #include "qemu/option.h" #include "qemu/vfio-helpers.h" #include "block/block_int.h" +#include "sysemu/replay.h" #include "trace.h" #include "block/nvme.h" @@ -350,7 +351,8 @@ static bool nvme_process_completion(BDRVNVMeState *s, NVMeQueuePair *q) smp_mb_release(); *q->cq.doorbell = cpu_to_le32(q->cq.head); if (!qemu_co_queue_empty(&q->free_req_queue)) { - aio_bh_schedule_oneshot(s->aio_context, nvme_free_req_queue_cb, q); + replay_bh_schedule_oneshot_event(s->aio_context, + nvme_free_req_queue_cb, q); } } q->busy = false; @@ -904,7 +906,7 @@ static void nvme_rw_cb(void *opaque, int ret) /* The rw coroutine hasn't yielded, don't try to enter. */ return; } - aio_bh_schedule_oneshot(data->ctx, nvme_rw_cb_bh, data); + replay_bh_schedule_oneshot_event(data->ctx, nvme_rw_cb_bh, data); } static coroutine_fn int nvme_co_prw_aligned(BlockDriverState *bs, diff --git a/block/rbd.c b/block/rbd.c index f2ac2c06f4..c764b42034 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -22,6 +22,7 @@ #include "block/qdict.h" #include "crypto/secret.h" #include "qemu/cutils.h" +#include "sysemu/replay.h" #include "qapi/qmp/qstring.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qjson.h" @@ -859,8 +860,8 @@ static void rbd_finish_aiocb(rbd_completion_t c, RADOSCB *rcb) rcb->ret = rbd_aio_get_return_value(c); rbd_aio_release(c); - aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs), - rbd_finish_bh, rcb); + replay_bh_schedule_oneshot_event(bdrv_get_aio_context(acb->common.bs), + rbd_finish_bh, rcb); } static int rbd_aio_discard_wrapper(rbd_image_t image, diff --git a/block/vxhs.c b/block/vxhs.c index 77fd5eb20d..d79fc97df6 100644 --- a/block/vxhs.c +++ b/block/vxhs.c @@ -22,6 +22,7 @@ #include "qapi/error.h" #include "qemu/uuid.h" #include "crypto/tlscredsx509.h" +#include "sysemu/replay.h" #define VXHS_OPT_FILENAME "filename" #define VXHS_OPT_VDISK_ID "vdisk-id" @@ -105,8 +106,8 @@ static void vxhs_iio_callback(void *ctx, uint32_t opcode, uint32_t error) trace_vxhs_iio_callback(error); } - aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs), - vxhs_complete_aio_bh, acb); + replay_bh_schedule_oneshot_event(bdrv_get_aio_context(acb->common.bs), + vxhs_complete_aio_bh, acb); break; default: diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 1d18c9b6ea..b7394a1f5c 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -163,6 +163,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 60d17f6edb..e5bf1bc2e6 100644 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -36,6 +36,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); @@ -131,6 +134,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); @@ -161,6 +175,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 945802361b..e9786b2377 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 1be34aa824..e578958659 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 9c7393b08c..4a50e95ec3 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -20,6 +20,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 += sysbus.o diff --git a/stubs/replay-user.c b/stubs/replay-user.c new file mode 100644 index 0000000000..2ad9e27203 --- /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 Fri Jun 21 08:22:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120038 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXW33bWGz9s3l for ; Fri, 21 Jun 2019 18:52:15 +1000 (AEST) Received: from localhost ([::1]:55584 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFHJ-0005pL-Hb for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:52:13 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58240) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzZ-0004B9-1Z for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEoa-0001QR-HV for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:33 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41704) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEoa-0001Pr-Ax for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:32 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 80FDE540082; Fri, 21 Jun 2019 11:22:31 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:22:31 +0300 Message-ID: <156110535134.25431.18355326480887591547.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 20/24] replay: document development rules X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 --- v9: fixed external virtual clock description (reported by Artem Pisarenko) --- docs/devel/replay.txt | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 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 0000000000..e641c35add --- /dev/null +++ b/docs/devel/replay.txt @@ -0,0 +1,46 @@ +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 clock with EXTERNAL attribute. 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. From patchwork Fri Jun 21 08:22:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120009 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXB565pmz9s3l for ; Fri, 21 Jun 2019 18:37:33 +1000 (AEST) Received: from localhost ([::1]:55526 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heF35-0005Rf-Qj for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:37:31 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58372) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzY-0004CE-7N for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEog-0001Y8-8Z for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:39 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41726) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEof-0001XV-UQ for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:38 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 1652F54006B; Fri, 21 Jun 2019 11:22:37 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:22:36 +0300 Message-ID: <156110535689.25431.9016521530452304411.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 21/24] util/qemu-timer: refactor deadline calculation for external timers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk icount-based record/replay uses qemu_clock_deadline_ns_all to measure the period until vCPU may be interrupted. This function takes in account the virtual timers, because they belong to the virtual devices that may generate interrupt request or affect the virtual machine state. However, there are a subset of virtual timers, that are marked with 'external' flag. These do not change the virtual machine state and only based on virtual clock. Calculating the deadling using the external timers breaks the determinism, because they do not belong to the replayed part of the virtual machine. This patch fixes the deadline calculation for this case. Signed-off-by: Pavel Dovgalyuk --- v15 changes: - fixed misprint in the test --- cpus.c | 9 ++++----- include/qemu/timer.h | 7 +++---- qtest.c | 2 +- tests/ptimer-test-stubs.c | 4 ++-- tests/ptimer-test.c | 4 ++-- util/qemu-timer.c | 41 +++++++++++++++++++++++++++++++++-------- 6 files changed, 45 insertions(+), 22 deletions(-) diff --git a/cpus.c b/cpus.c index e0e61abe64..e8d0c08212 100644 --- a/cpus.c +++ b/cpus.c @@ -555,7 +555,7 @@ void qtest_clock_warp(int64_t dest) assert(qtest_enabled()); aio_context = qemu_get_aio_context(); while (clock < dest) { - int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); + int64_t deadline = virtual_clock_deadline_ns(); int64_t warp = qemu_soonest_timeout(dest - clock, deadline); seqlock_write_lock(&timers_state.vm_clock_seqlock, @@ -615,7 +615,7 @@ void qemu_start_warp_timer(void) /* We want to use the earliest deadline from ALL vm_clocks */ clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); - deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); + deadline = virtual_clock_deadline_ns(); if (deadline < 0) { static bool notified; if (!icount_sleep && !notified) { @@ -1363,7 +1363,7 @@ static int64_t tcg_get_icount_limit(void) int64_t deadline; if (replay_mode != REPLAY_MODE_PLAY) { - deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); + deadline = virtual_clock_deadline_ns(); /* Maintain prior (possibly buggy) behaviour where if no deadline * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than @@ -1384,8 +1384,7 @@ static void handle_icount_deadline(void) { assert(qemu_in_vcpu_thread()); if (use_icount) { - int64_t deadline = - qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); + int64_t deadline = virtual_clock_deadline_ns(); if (deadline == 0) { /* Wake up other AioContexts. */ diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 5d978e1634..9df45fbaeb 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -175,16 +175,15 @@ bool qemu_clock_expired(QEMUClockType type); bool qemu_clock_use_for_deadline(QEMUClockType type); /** - * qemu_clock_deadline_ns_all: - * @type: the clock type + * virtual_clock_deadline_ns: * * Calculate the deadline across all timer lists associated - * with a clock (as opposed to just the default one) + * with virtual clock (excluding external timers) * in nanoseconds, or -1 if no timer is set to expire. * * Returns: time until expiry in nanoseconds or -1 */ -int64_t qemu_clock_deadline_ns_all(QEMUClockType type); +int64_t virtual_clock_deadline_ns(void); /** * qemu_clock_get_main_loop_timerlist: diff --git a/qtest.c b/qtest.c index 15e27e911f..825bf558d1 100644 --- a/qtest.c +++ b/qtest.c @@ -655,7 +655,7 @@ static void qtest_process_command(CharBackend *chr, gchar **words) int ret = qemu_strtoi64(words[1], NULL, 0, &ns); g_assert(ret == 0); } else { - ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); + ns = virtual_clock_deadline_ns(); } qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns); qtest_send_prefix(chr); diff --git a/tests/ptimer-test-stubs.c b/tests/ptimer-test-stubs.c index 54b3fd26f6..49acfed76f 100644 --- a/tests/ptimer-test-stubs.c +++ b/tests/ptimer-test-stubs.c @@ -88,9 +88,9 @@ int64_t qemu_clock_get_ns(QEMUClockType type) return ptimer_test_time_ns; } -int64_t qemu_clock_deadline_ns_all(QEMUClockType type) +int64_t virtual_clock_deadline_ns(void) { - QEMUTimerList *timer_list = main_loop_tlg.tl[type]; + QEMUTimerList *timer_list = main_loop_tlg.tl[QEMU_CLOCK_VIRTUAL]; QEMUTimer *t = timer_list->active_timers.next; int64_t deadline = -1; diff --git a/tests/ptimer-test.c b/tests/ptimer-test.c index b30aad0737..338a4e0c10 100644 --- a/tests/ptimer-test.c +++ b/tests/ptimer-test.c @@ -50,13 +50,13 @@ static void ptimer_test_set_qemu_time_ns(int64_t ns) static void qemu_clock_step(uint64_t ns) { - int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); + int64_t deadline = virtual_clock_deadline_ns(); int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns; while (deadline != -1 && deadline <= advanced_time) { ptimer_test_set_qemu_time_ns(deadline); ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL); - deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); + deadline = virtual_clock_deadline_ns(); } ptimer_test_set_qemu_time_ns(advanced_time); diff --git a/util/qemu-timer.c b/util/qemu-timer.c index 1cc1b2f2c3..88fbf04469 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -236,6 +236,7 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list) qemu_mutex_unlock(&timer_list->active_timers_lock); return -1; } + expire_time = timer_list->active_timers->expire_time; qemu_mutex_unlock(&timer_list->active_timers_lock); @@ -248,19 +249,43 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list) return delta; } -/* Calculate the soonest deadline across all timerlists attached - * to the clock. This is used for the icount timeout so we - * ignore whether or not the clock should be used in deadline - * calculations. +/* + * Calculate the soonest deadline across all timerlists attached + * to the virtual clock (excluding the external timers that do not affect + * the replayed guest state. */ -int64_t qemu_clock_deadline_ns_all(QEMUClockType type) +int64_t virtual_clock_deadline_ns(void) { int64_t deadline = -1; + int64_t delta; + int64_t expire_time; + QEMUTimer *ts; QEMUTimerList *timer_list; - QEMUClock *clock = qemu_clock_ptr(type); + QEMUClock *clock = qemu_clock_ptr(QEMU_CLOCK_VIRTUAL); + + if (!clock->enabled) { + return -1; + } + QLIST_FOREACH(timer_list, &clock->timerlists, list) { - deadline = qemu_soonest_timeout(deadline, - timerlist_deadline_ns(timer_list)); + qemu_mutex_lock(&timer_list->active_timers_lock); + ts = timer_list->active_timers; + /* Skip all external timers */ + while (ts && (ts->attributes & QEMU_TIMER_ATTR_EXTERNAL)) { + ts = ts->next; + } + if (!ts) { + qemu_mutex_unlock(&timer_list->active_timers_lock); + continue; + } + expire_time = ts->expire_time; + qemu_mutex_unlock(&timer_list->active_timers_lock); + + delta = expire_time - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (delta <= 0) { + delta = 0; + } + deadline = qemu_soonest_timeout(deadline, delta); } return deadline; } From patchwork Fri Jun 21 08:22:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120020 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXQh21rMz9s3l for ; Fri, 21 Jun 2019 18:48:26 +1000 (AEST) Received: from localhost ([::1]:55574 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFDb-0004lL-6p for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:48:23 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58042) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzW-00044x-2m for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEol-0001et-NQ for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:44 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41756) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEol-0001eH-Gp for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:43 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id A7D60540082; Fri, 21 Jun 2019 11:22:42 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:22:42 +0300 Message-ID: <156110536250.25431.1992075984834231844.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 22/24] replay: fix replay shutdown X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch fixes shutdown of the replay process, which is terminated with the assert when shutdown event is read from the log. replay_finish_event reads new data_kind and therefore the value of data_kind should be preserved to be valid at qemu_system_shutdown_request call. Signed-off-by: Pavel Dovgalyuk --- replay/replay.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/replay/replay.c b/replay/replay.c index e578958659..8f2e17c8cb 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -49,14 +49,14 @@ bool replay_next_event_is(int event) } while (true) { - if (event == replay_state.data_kind) { + unsigned int data_kind = replay_state.data_kind; + if (event == data_kind) { res = true; } - switch (replay_state.data_kind) { + switch (data_kind) { case EVENT_SHUTDOWN ... EVENT_SHUTDOWN_LAST: replay_finish_event(); - qemu_system_shutdown_request(replay_state.data_kind - - EVENT_SHUTDOWN); + qemu_system_shutdown_request(data_kind - EVENT_SHUTDOWN); break; default: /* clock, time_t, checkpoint and other events */ From patchwork Fri Jun 21 08:22:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120011 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXJH5Zh6z9sND for ; Fri, 21 Jun 2019 18:42:53 +1000 (AEST) Received: from localhost ([::1]:55550 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heF8C-0001VJ-GV for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:42:50 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58236) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzW-0004B8-0S for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEor-0001ig-Hl for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:51 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41778) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEor-0001iP-4E for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:49 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 435F2540089; Fri, 21 Jun 2019 11:22:48 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:22:48 +0300 Message-ID: <156110536808.25431.15394774219482379684.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 23/24] replay: rename step-related variables and functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch renames replay_get_current_step() and related variables to make these names consistent with hmp/qmp commands. Signed-off-by: Pavel Dovgalyuk --- blockdev.c | 2 +- include/sysemu/replay.h | 2 +- migration/savevm.c | 2 +- replay/replay-debugging.c | 30 ++++++++++++++++-------------- replay/replay-events.c | 4 ++-- replay/replay-internal.c | 10 +++++----- replay/replay-internal.h | 10 +++++----- replay/replay-snapshot.c | 6 +++--- replay/replay-time.c | 2 +- replay/replay.c | 26 +++++++++++++------------- 10 files changed, 48 insertions(+), 46 deletions(-) diff --git a/blockdev.c b/blockdev.c index 7bd6930eed..d7853d0688 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1454,7 +1454,7 @@ static void internal_snapshot_prepare(BlkActionState *common, 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(); + sn->icount = replay_get_current_icount(); } else { sn->icount = -1ULL; } diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index b7394a1f5c..057a458463 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -96,7 +96,7 @@ void replay_breakpoint(void); /* Processing the instructions */ /*! Returns number of executed instructions. */ -uint64_t replay_get_current_step(void); +uint64_t replay_get_current_icount(void); /*! Returns number of instructions to execute in replay mode. */ int replay_get_instructions(void); /*! Updates instructions counter in replay mode. */ diff --git a/migration/savevm.c b/migration/savevm.c index 053f470eea..3cfc63ade1 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2602,7 +2602,7 @@ int save_snapshot(const char *name, Error **errp) 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(); + sn->icount = replay_get_current_icount(); } else { sn->icount = -1ULL; } diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index abb5fe687f..b2275612c7 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -38,7 +38,7 @@ void hmp_info_replay(Monitor *mon, const QDict *qdict) monitor_printf(mon, "%s execution '%s': instruction count = %"PRId64"\n", replay_mode == REPLAY_MODE_RECORD ? "Recording" : "Replaying", - replay_get_filename(), replay_get_current_step()); + replay_get_filename(), replay_get_current_icount()); } } @@ -51,7 +51,7 @@ ReplayInfo *qmp_query_replay(Error **errp) retval->filename = g_strdup(replay_get_filename()); retval->has_filename = true; } - retval->icount = replay_get_current_step(); + retval->icount = replay_get_current_icount(); return retval; } @@ -59,7 +59,7 @@ static void replay_break(uint64_t icount, QEMUTimerCB callback, void *opaque) { assert(replay_mode == REPLAY_MODE_PLAY); assert(replay_mutex_locked()); - assert(replay_break_icount >= replay_get_current_step()); + assert(replay_break_icount >= replay_get_current_icount()); assert(callback); replay_break_icount = icount; @@ -94,7 +94,7 @@ static void replay_stop_vm(void *opaque) void qmp_replay_break(int64_t icount, Error **errp) { if (replay_mode == REPLAY_MODE_PLAY) { - if (icount >= replay_get_current_step()) { + if (icount >= replay_get_current_icount()) { replay_break(icount, replay_stop_vm, NULL); } else { error_setg(errp, @@ -196,14 +196,14 @@ static void replay_seek(int64_t icount, QEMUTimerCB callback, Error **errp) snapshot = replay_find_nearest_snapshot(icount, &snapshot_icount); if (snapshot) { - if (icount < replay_get_current_step() - || replay_get_current_step() < snapshot_icount) { + if (icount < replay_get_current_icount() + || replay_get_current_icount() < snapshot_icount) { vm_stop(RUN_STATE_RESTORE_VM); load_snapshot(snapshot, errp); } g_free(snapshot); } - if (replay_get_current_step() <= icount) { + if (replay_get_current_icount() <= icount) { replay_break(icount, callback, NULL); vm_start(); } else { @@ -242,8 +242,9 @@ bool replay_reverse_step(void) 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 (replay_get_current_icount() != 0) { + replay_seek(replay_get_current_icount() - 1, + replay_stop_vm_debug, &err); if (err) { error_free(err); return false; @@ -283,7 +284,7 @@ static void replay_continue_stop(void *opaque) error_free(err); replay_continue_end(); } - replay_last_snapshot = replay_get_current_step(); + replay_last_snapshot = replay_get_current_icount(); return; } else { /* Seek to the very first step */ @@ -303,15 +304,16 @@ bool replay_reverse_continue(void) assert(replay_mode == REPLAY_MODE_PLAY); - if (replay_get_current_step() != 0) { - replay_seek(replay_get_current_step() - 1, replay_continue_stop, &err); + if (replay_get_current_icount() != 0) { + replay_seek(replay_get_current_icount() - 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(); + replay_last_snapshot = replay_get_current_icount(); return true; } @@ -321,5 +323,5 @@ bool replay_reverse_continue(void) void replay_breakpoint(void) { assert(replay_mode == REPLAY_MODE_PLAY); - replay_last_breakpoint = replay_get_current_step(); + replay_last_breakpoint = replay_get_current_icount(); } diff --git a/replay/replay-events.c b/replay/replay-events.c index e5bf1bc2e6..302b84043a 100644 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -127,7 +127,7 @@ void replay_add_event(ReplayAsyncEventKind event_kind, void replay_bh_schedule_event(QEMUBH *bh) { if (events_enabled) { - uint64_t id = replay_get_current_step(); + uint64_t id = replay_get_current_icount(); replay_add_event(REPLAY_ASYNC_EVENT_BH, bh, NULL, id); } else { qemu_bh_schedule(bh); @@ -138,7 +138,7 @@ void replay_bh_schedule_oneshot_event(AioContext *ctx, QEMUBHFunc *cb, void *opaque) { if (events_enabled) { - uint64_t id = replay_get_current_step(); + uint64_t id = replay_get_current_icount(); replay_add_event(REPLAY_ASYNC_EVENT_BH_ONESHOT, cb, opaque, id); } else { aio_bh_schedule_oneshot(ctx, cb, opaque); diff --git a/replay/replay-internal.c b/replay/replay-internal.c index 979f3a0b39..ac6c9017fc 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -172,7 +172,7 @@ void replay_fetch_data_kind(void) if (!replay_state.has_unread_data) { replay_state.data_kind = replay_get_byte(); if (replay_state.data_kind == EVENT_INSTRUCTION) { - replay_state.instructions_count = replay_get_dword(); + replay_state.instruction_count = replay_get_dword(); } replay_check_error(); replay_state.has_unread_data = 1; @@ -226,9 +226,9 @@ void replay_mutex_unlock(void) } } -void replay_advance_current_step(uint64_t current_step) +void replay_advance_current_icount(uint64_t current_icount) { - int diff = (int)(current_step - replay_state.current_step); + int diff = (int)(current_icount - replay_state.current_icount); /* Time can only go forward */ assert(diff >= 0); @@ -236,7 +236,7 @@ void replay_advance_current_step(uint64_t current_step) if (diff > 0) { replay_put_event(EVENT_INSTRUCTION); replay_put_dword(diff); - replay_state.current_step += diff; + replay_state.current_icount += diff; } } @@ -245,6 +245,6 @@ void replay_save_instructions(void) { if (replay_file && replay_mode == REPLAY_MODE_RECORD) { g_assert(replay_mutex_locked()); - replay_advance_current_step(replay_get_current_step()); + replay_advance_current_icount(replay_get_current_icount()); } } diff --git a/replay/replay-internal.h b/replay/replay-internal.h index e9786b2377..ba9f374374 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -65,10 +65,10 @@ typedef enum ReplayAsyncEventKind ReplayAsyncEventKind; typedef struct ReplayState { /*! Cached clock values. */ int64_t cached_clock[REPLAY_CLOCK_COUNT]; - /*! Current step - number of processed instructions and timer events. */ - uint64_t current_step; + /*! Current icount - number of processed instructions. */ + uint64_t current_icount; /*! Number of instructions to be executed before other events happen. */ - int instructions_count; + int instruction_count; /*! Type of the currently executed event. */ unsigned int data_kind; /*! Flag which indicates that event is not processed yet. */ @@ -127,8 +127,8 @@ void replay_finish_event(void); data_kind variable. */ void replay_fetch_data_kind(void); -/*! Advance replay_state.current_step to the specified value. */ -void replay_advance_current_step(uint64_t current_step); +/*! Advance replay_state.current_icount to the specified value. */ +void replay_advance_current_icount(uint64_t current_icount); /*! Saves queued events (like instructions and sound). */ void replay_save_instructions(void); diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c index 756f48bc02..97d026af30 100644 --- a/replay/replay-snapshot.c +++ b/replay/replay-snapshot.c @@ -41,7 +41,7 @@ static int replay_post_load(void *opaque, int version_id) } else if (replay_mode == REPLAY_MODE_RECORD) { /* This is only useful for loading the initial state. Therefore reset all the counters. */ - state->instructions_count = 0; + state->instruction_count = 0; state->block_request_id = 0; } @@ -56,8 +56,8 @@ static const VMStateDescription vmstate_replay = { .post_load = replay_post_load, .fields = (VMStateField[]) { VMSTATE_INT64_ARRAY(cached_clock, ReplayState, REPLAY_CLOCK_COUNT), - VMSTATE_UINT64(current_step, ReplayState), - VMSTATE_INT32(instructions_count, ReplayState), + VMSTATE_UINT64(current_icount, ReplayState), + VMSTATE_INT32(instruction_count, ReplayState), VMSTATE_UINT32(data_kind, ReplayState), VMSTATE_UINT32(has_unread_data, ReplayState), VMSTATE_UINT64(file_offset, ReplayState), diff --git a/replay/replay-time.c b/replay/replay-time.c index 49c9e5d8b2..43357c9f24 100644 --- a/replay/replay-time.c +++ b/replay/replay-time.c @@ -24,7 +24,7 @@ int64_t replay_save_clock(ReplayClockKind kind, int64_t 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_advance_current_icount(raw_icount); replay_put_event(EVENT_CLOCK + kind); replay_put_qword(clock); diff --git a/replay/replay.c b/replay/replay.c index 8f2e17c8cb..11b9c12eb6 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -43,7 +43,7 @@ bool replay_next_event_is(int event) bool res = false; /* nothing to skip - not all instructions used */ - if (replay_state.instructions_count != 0) { + if (replay_state.instruction_count != 0) { assert(replay_state.data_kind == EVENT_INSTRUCTION); return event == EVENT_INSTRUCTION; } @@ -66,7 +66,7 @@ bool replay_next_event_is(int event) return res; } -uint64_t replay_get_current_step(void) +uint64_t replay_get_current_icount(void) { return cpu_get_icount_raw(); } @@ -76,9 +76,9 @@ int replay_get_instructions(void) int res = 0; replay_mutex_lock(); if (replay_next_event_is(EVENT_INSTRUCTION)) { - res = replay_state.instructions_count; + res = replay_state.instruction_count; if (replay_break_icount != -1LL) { - uint64_t current = replay_get_current_step(); + uint64_t current = replay_get_current_icount(); assert(replay_break_icount >= current); if (current + res > replay_break_icount) { res = replay_break_icount - current; @@ -93,16 +93,16 @@ void replay_account_executed_instructions(void) { if (replay_mode == REPLAY_MODE_PLAY) { g_assert(replay_mutex_locked()); - if (replay_state.instructions_count > 0) { - int count = (int)(replay_get_current_step() - - replay_state.current_step); + if (replay_state.instruction_count > 0) { + int count = (int)(replay_get_current_icount() + - replay_state.current_icount); /* Time can only go forward */ assert(count >= 0); - replay_state.instructions_count -= count; - replay_state.current_step += count; - if (replay_state.instructions_count == 0) { + replay_state.instruction_count -= count; + replay_state.current_icount += count; + if (replay_state.instruction_count == 0) { assert(replay_state.data_kind == EVENT_INSTRUCTION); replay_finish_event(); /* Wake up iothread. This is required because @@ -111,7 +111,7 @@ void replay_account_executed_instructions(void) qemu_notify_event(); } /* Execution reached the break step */ - if (replay_break_icount == replay_state.current_step) { + if (replay_break_icount == replay_state.current_icount) { /* Cannot make callback directly from the vCPU thread */ timer_mod_ns(replay_break_timer, qemu_clock_get_ns(QEMU_CLOCK_REALTIME)); @@ -290,8 +290,8 @@ static void replay_enable(const char *fname, int mode) replay_mutex_init(); replay_state.data_kind = -1; - replay_state.instructions_count = 0; - replay_state.current_step = 0; + replay_state.instruction_count = 0; + replay_state.current_icount = 0; replay_state.has_unread_data = 0; /* skip file header for RECORD and check it for PLAY */ From patchwork Fri Jun 21 08:22:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 1120040 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=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45VXYf4vZrz9s3l for ; Fri, 21 Jun 2019 18:54:30 +1000 (AEST) Received: from localhost ([::1]:55598 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heFJU-0000on-OK for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2019 04:54:28 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58308) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1heEzV-0004Ba-W4 for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:33:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1heEow-0001ky-VA for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:55 -0400 Received: from mail.ispras.ru ([83.149.199.45]:41794) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1heEow-0001kl-OG for qemu-devel@nongnu.org; Fri, 21 Jun 2019 04:22:54 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id DBBF454006B; Fri, 21 Jun 2019 11:22:53 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 21 Jun 2019 11:22:53 +0300 Message-ID: <156110537370.25431.15604146322775530877.stgit@pasha-Precision-3630-Tower> In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> References: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower> 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 for-4.1 24/24] icount: clean up cpu_can_io before jumping to the next block X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk Most of IO instructions can be executed only at the end of the block in icount mode. Therefore translator can set cpu_can_io flag when translating the last instruction. But when the blocks are chained, then this flag is not reset and may remain set at the beginning of the next block. This patch resets the flag before "chaining" the translation blocks. Signed-off-by: Pavel Dovgalyuk --- accel/tcg/tcg-runtime.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c index 8a1e408e31..fe6b83d0fc 100644 --- a/accel/tcg/tcg-runtime.c +++ b/accel/tcg/tcg-runtime.c @@ -151,6 +151,8 @@ void *HELPER(lookup_tb_ptr)(CPUArchState *env) target_ulong cs_base, pc; uint32_t flags; + /* We are going to jump to the next block. can_do_io should be reset */ + cpu->can_do_io = !use_icount; tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, curr_cflags()); if (tb == NULL) { return tcg_ctx->code_gen_epilogue;