From nobody Sat May 4 02:01:43 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 149154817313673.21088395039817; Thu, 6 Apr 2017 23:56:13 -0700 (PDT) Received: from localhost ([::1]:49257 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNoY-0000Uw-SD for importer@patchew.org; Fri, 07 Apr 2017 02:56:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45954) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNn8-0007oY-HS for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:54:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cwNn7-0004QZ-Oa for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:54:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44564) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cwNn3-0004Ol-9s; Fri, 07 Apr 2017 02:54:37 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3A0A764080; Fri, 7 Apr 2017 06:54:36 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-27.pek2.redhat.com [10.72.8.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 77AFD8579E; Fri, 7 Apr 2017 06:54:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 3A0A764080 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=famz@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 3A0A764080 From: Fam Zheng To: qemu-devel@nongnu.org Date: Fri, 7 Apr 2017 14:54:09 +0800 Message-Id: <20170407065414.9143-2-famz@redhat.com> In-Reply-To: <20170407065414.9143-1-famz@redhat.com> References: <20170407065414.9143-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 07 Apr 2017 06:54:36 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 1/6] block: Fix unpaired aio_disable_external in external snapshot X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Max Reitz , Ed Swierk , Stefan Hajnoczi , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" bdrv_replace_child_noperm tries to hand over the quiesce_counter state from old bs to the new one, but if they are not on the same aio context this causes unbalance. Fix this by setting the correct aio context before calling bdrv_append(). Reported-by: Ed Swierk Reviewed-by: Eric Blake Signed-off-by: Fam Zheng Reviewed-by: Stefan Hajnoczi --- blockdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blockdev.c b/blockdev.c index 040c152..4927914 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1772,6 +1772,8 @@ static void external_snapshot_prepare(BlkActionState = *common, return; } =20 + bdrv_set_aio_context(state->new_bs, state->aio_context); + /* This removes our old bs and adds the new bs. This is an operation t= hat * can fail, so we need to do it in .prepare; undoing it for abort is * always possible. */ @@ -1789,8 +1791,6 @@ static void external_snapshot_commit(BlkActionState *= common) ExternalSnapshotState *state =3D DO_UPCAST(ExternalSnapshotState, common, comm= on); =20 - bdrv_set_aio_context(state->new_bs, state->aio_context); - /* We don't need (or want) to use the transactional * bdrv_reopen_multiple() across all the entries at once, because we * don't want to abort all of them if one of them fails the reopen */ --=20 2.9.3 From nobody Sat May 4 02:01:43 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1491548192569917.1515686907554; Thu, 6 Apr 2017 23:56:32 -0700 (PDT) Received: from localhost ([::1]:49258 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNot-0000om-G8 for importer@patchew.org; Fri, 07 Apr 2017 02:56:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46039) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNnK-0007yo-59 for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:54:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cwNnJ-0004Uk-FJ for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:54:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34384) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cwNnC-0004SP-Pl; Fri, 07 Apr 2017 02:54:46 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B11D0C0524EF; Fri, 7 Apr 2017 06:54:45 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-27.pek2.redhat.com [10.72.8.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 17C8C85796; Fri, 7 Apr 2017 06:54:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B11D0C0524EF Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=famz@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com B11D0C0524EF From: Fam Zheng To: qemu-devel@nongnu.org Date: Fri, 7 Apr 2017 14:54:10 +0800 Message-Id: <20170407065414.9143-3-famz@redhat.com> In-Reply-To: <20170407065414.9143-1-famz@redhat.com> References: <20170407065414.9143-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Fri, 07 Apr 2017 06:54:45 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 2/6] block: Assert attached child node has right aio context X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Max Reitz , Ed Swierk , Stefan Hajnoczi , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Suggested-by: Kevin Wolf Signed-off-by: Fam Zheng Reviewed-by: Stefan Hajnoczi --- block.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/block.c b/block.c index 927ba89..b8a3011 100644 --- a/block.c +++ b/block.c @@ -1752,6 +1752,9 @@ static void bdrv_replace_child_noperm(BdrvChild *chil= d, { BlockDriverState *old_bs =3D child->bs; =20 + if (old_bs && new_bs) { + assert(bdrv_get_aio_context(old_bs) =3D=3D bdrv_get_aio_context(ne= w_bs)); + } if (old_bs) { if (old_bs->quiesce_counter && child->role->drained_end) { child->role->drained_end(child); @@ -1852,6 +1855,7 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent= _bs, bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm); =20 assert(parent_bs->drv); + assert(bdrv_get_aio_context(parent_bs) =3D=3D bdrv_get_aio_context(chi= ld_bs)); parent_bs->drv->bdrv_child_perm(parent_bs, NULL, child_role, perm, shared_perm, &perm, &shared_perm= ); =20 --=20 2.9.3 From nobody Sat May 4 02:01:43 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1491548283853875.1467628815269; Thu, 6 Apr 2017 23:58:03 -0700 (PDT) Received: from localhost ([::1]:49269 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNqM-0002Hl-Mk for importer@patchew.org; Fri, 07 Apr 2017 02:58:02 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46056) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNnL-00080U-VW for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:54:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cwNnL-0004VT-6c for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:54:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:32926) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cwNnJ-0004UM-2J; Fri, 07 Apr 2017 02:54:53 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EF78B3D954; Fri, 7 Apr 2017 06:54:51 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-27.pek2.redhat.com [10.72.8.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9443118983; Fri, 7 Apr 2017 06:54:46 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com EF78B3D954 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=famz@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com EF78B3D954 From: Fam Zheng To: qemu-devel@nongnu.org Date: Fri, 7 Apr 2017 14:54:11 +0800 Message-Id: <20170407065414.9143-4-famz@redhat.com> In-Reply-To: <20170407065414.9143-1-famz@redhat.com> References: <20170407065414.9143-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 07 Apr 2017 06:54:52 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 3/6] mirror: Fix aio context of mirror_top_bs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Max Reitz , Ed Swierk , Stefan Hajnoczi , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" It should be moved to the same context as source, before inserting to the graph. Reviewed-by: Eric Blake Reviewed-by: Kevin Wolf Signed-off-by: Fam Zheng Reviewed-by: Stefan Hajnoczi --- block/mirror.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/mirror.c b/block/mirror.c index 9e2fecc..e904fef 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1148,6 +1148,7 @@ static void mirror_start_job(const char *job_id, Bloc= kDriverState *bs, return; } mirror_top_bs->total_sectors =3D bs->total_sectors; + bdrv_set_aio_context(mirror_top_bs, bdrv_get_aio_context(bs)); =20 /* bdrv_append takes ownership of the mirror_top_bs reference, need to= keep * it alive until block_job_create() even if bs has no parent. */ --=20 2.9.3 From nobody Sat May 4 02:01:43 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1491548206739274.37250012481263; Thu, 6 Apr 2017 23:56:46 -0700 (PDT) Received: from localhost ([::1]:49259 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNp7-0000zz-Hj for importer@patchew.org; Fri, 07 Apr 2017 02:56:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46103) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNnV-00088P-KZ for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:55:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cwNnU-0004bv-Oy for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:55:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54460) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cwNnQ-0004We-8m; Fri, 07 Apr 2017 02:55:00 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2B29A61D22; Fri, 7 Apr 2017 06:54:59 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-27.pek2.redhat.com [10.72.8.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id D790618983; Fri, 7 Apr 2017 06:54:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2B29A61D22 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=famz@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 2B29A61D22 From: Fam Zheng To: qemu-devel@nongnu.org Date: Fri, 7 Apr 2017 14:54:12 +0800 Message-Id: <20170407065414.9143-5-famz@redhat.com> In-Reply-To: <20170407065414.9143-1-famz@redhat.com> References: <20170407065414.9143-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 07 Apr 2017 06:54:59 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 4/6] block: Quiesce old aio context during bdrv_set_aio_context X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Max Reitz , Ed Swierk , Stefan Hajnoczi , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The fact that the bs->aio_context is changing can confuse the dataplane iothread, because of the now fine granularity aio context lock. bdrv_drain should rather be a bdrv_drained_begin/end pair, but since bs->aio_context is changing, we can just use aio_disable_external and block_job_pause. Reported-by: Ed Swierk Reviewed-by: Eric Blake Signed-off-by: Fam Zheng --- block.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index b8a3011..512515a 100644 --- a/block.c +++ b/block.c @@ -4396,11 +4396,14 @@ void bdrv_attach_aio_context(BlockDriverState *bs, =20 void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context) { - AioContext *ctx; + AioContext *ctx =3D bdrv_get_aio_context(bs); =20 + aio_disable_external(ctx); + if (bs->job) { + block_job_pause(bs->job); + } bdrv_drain(bs); /* ensure there are no in-flight requests */ =20 - ctx =3D bdrv_get_aio_context(bs); while (aio_poll(ctx, false)) { /* wait for all bottom halves to execute */ } @@ -4413,6 +4416,10 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioC= ontext *new_context) aio_context_acquire(new_context); bdrv_attach_aio_context(bs, new_context); aio_context_release(new_context); + if (bs->job) { + block_job_resume(bs->job); + } + aio_enable_external(ctx); } =20 void bdrv_add_aio_context_notifier(BlockDriverState *bs, --=20 2.9.3 From nobody Sat May 4 02:01:43 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1491548428105642.5986261027979; Fri, 7 Apr 2017 00:00:28 -0700 (PDT) Received: from localhost ([::1]:49284 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNsg-0004LM-Vm for importer@patchew.org; Fri, 07 Apr 2017 03:00:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46361) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNo7-0000Kt-N1 for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:55:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cwNo4-0004uf-O6 for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:55:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45972) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cwNnx-0004s9-HQ; Fri, 07 Apr 2017 02:55:33 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5350466CB6; Fri, 7 Apr 2017 06:55:32 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-27.pek2.redhat.com [10.72.8.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2442518983; Fri, 7 Apr 2017 06:54:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 5350466CB6 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=famz@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 5350466CB6 From: Fam Zheng To: qemu-devel@nongnu.org Date: Fri, 7 Apr 2017 14:54:13 +0800 Message-Id: <20170407065414.9143-6-famz@redhat.com> In-Reply-To: <20170407065414.9143-1-famz@redhat.com> References: <20170407065414.9143-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 07 Apr 2017 06:55:32 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 5/6] coroutine: Explicitly specify AioContext when entering coroutine X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Max Reitz , Ed Swierk , Stefan Hajnoczi , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Coroutine in block layer should always be waken up in bs->aio_context rather than the "current" context where it is entered. They differ when the main loop is doing QMP tasks. Race conditions happen without this patch, because the wrong context is acquired in co_schedule_bh_cb, while the entered coroutine works on a different one: main loop iothread ----------------------------------------------------------------------- blockdev_snapshot aio_context_acquire(bs->ctx) bdrv_flush(bs) bdrv_co_flush(bs) ... qemu_coroutine_yield(co) BDRV_POLL_WHILE() aio_context_release(bs->ctx) aio_context_acquire(bs->ctx) ... aio_co_wake(co) aio_poll(qemu_aio_context) ... co_schedule_bh_cb() ... qemu_coroutine_enter(co) ... /* (A) bdrv_co_flush(bs) /* (B) I/O on bs */ continues... */ aio_context_release(bs->ctx) Both (A) and (B) can access resources protected by bs->ctx, but (A) is not thread-safe. Make the block layer explicitly specify a desired context for the entered coroutine. For the rest callers, stick to the old behavior, qemu_get_aio_context() or qemu_get_current_aio_context(). Signed-off-by: Fam Zheng --- block.c | 15 +++++++++++++-- block/blkdebug.c | 4 ++-- block/blkverify.c | 8 ++++---- block/block-backend.c | 4 ++-- block/io.c | 14 +++++++------- block/mirror.c | 2 +- block/quorum.c | 16 ++++++++-------- block/sheepdog.c | 4 ++-- blockjob.c | 4 ++-- hw/9pfs/9p.c | 4 ++-- hw/9pfs/coth.c | 4 ++-- include/block/block.h | 11 +++++++++++ include/qemu/coroutine.h | 11 ++++++----- include/qemu/main-loop.h | 2 +- migration/colo.c | 3 ++- migration/migration.c | 2 +- nbd/server.c | 5 +++-- qemu-img.c | 4 ++-- qemu-io-cmds.c | 2 +- tests/test-coroutine.c | 41 +++++++++++++++++++++-------------------- tests/test-thread-pool.c | 2 +- util/async.c | 4 ++-- util/qemu-coroutine-io.c | 3 ++- util/qemu-coroutine-lock.c | 6 ++++-- util/qemu-coroutine.c | 10 +++++----- util/trace-events | 2 +- 26 files changed, 108 insertions(+), 79 deletions(-) diff --git a/block.c b/block.c index 512515a..6513484 100644 --- a/block.c +++ b/block.c @@ -357,10 +357,11 @@ int bdrv_create(BlockDriver *drv, const char* filenam= e, /* Fast-path if already in coroutine context */ bdrv_create_co_entry(&cco); } else { + AioContext *ctx =3D qemu_get_aio_context(); co =3D qemu_coroutine_create(bdrv_create_co_entry, &cco); - qemu_coroutine_enter(co); + qemu_coroutine_enter(ctx, co); while (cco.ret =3D=3D NOT_DONE) { - aio_poll(qemu_get_aio_context(), true); + aio_poll(ctx, true); } } =20 @@ -4324,6 +4325,16 @@ AioContext *bdrv_get_aio_context(BlockDriverState *b= s) return bs->aio_context; } =20 +void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *coroutine) +{ + qemu_coroutine_enter(bdrv_get_aio_context(bs), coroutine); +} + +void bdrv_coroutine_enter_if_inactive(BlockDriverState *bs, Coroutine *co) +{ + qemu_coroutine_enter_if_inactive(bdrv_get_aio_context(bs), co); +} + static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban) { QLIST_REMOVE(ban, list); diff --git a/block/blkdebug.c b/block/blkdebug.c index 67e8024..2370f73 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -610,7 +610,7 @@ static int blkdebug_debug_resume(BlockDriverState *bs, = const char *tag) =20 QLIST_FOREACH_SAFE(r, &s->suspended_reqs, next, next) { if (!strcmp(r->tag, tag)) { - qemu_coroutine_enter(r->co); + bdrv_coroutine_enter(bs, r->co); return 0; } } @@ -636,7 +636,7 @@ static int blkdebug_debug_remove_breakpoint(BlockDriver= State *bs, } QLIST_FOREACH_SAFE(r, &s->suspended_reqs, next, r_next) { if (!strcmp(r->tag, tag)) { - qemu_coroutine_enter(r->co); + bdrv_coroutine_enter(bs, r->co); ret =3D 0; } } diff --git a/block/blkverify.c b/block/blkverify.c index 9a1e21c..c11a636 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -172,7 +172,7 @@ static void coroutine_fn blkverify_do_test_req(void *op= aque) r->ret =3D r->request_fn(s->test_file, r->offset, r->bytes, r->qiov, r->flags); r->done++; - qemu_coroutine_enter_if_inactive(r->co); + bdrv_coroutine_enter_if_inactive(r->bs, r->co); } =20 static void coroutine_fn blkverify_do_raw_req(void *opaque) @@ -182,7 +182,7 @@ static void coroutine_fn blkverify_do_raw_req(void *opa= que) r->raw_ret =3D r->request_fn(r->bs->file, r->offset, r->bytes, r->raw_= qiov, r->flags); r->done++; - qemu_coroutine_enter_if_inactive(r->co); + bdrv_coroutine_enter_if_inactive(r->bs, r->co); } =20 static int coroutine_fn @@ -207,8 +207,8 @@ blkverify_co_prwv(BlockDriverState *bs, BlkverifyReques= t *r, uint64_t offset, co_a =3D qemu_coroutine_create(blkverify_do_test_req, r); co_b =3D qemu_coroutine_create(blkverify_do_raw_req, r); =20 - qemu_coroutine_enter(co_a); - qemu_coroutine_enter(co_b); + bdrv_coroutine_enter(bs, co_a); + bdrv_coroutine_enter(bs, co_b); =20 while (r->done < 2) { qemu_coroutine_yield(); diff --git a/block/block-backend.c b/block/block-backend.c index 0b63773..5eeaad1 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1007,7 +1007,7 @@ static int blk_prw(BlockBackend *blk, int64_t offset,= uint8_t *buf, co_entry(&rwco); } else { Coroutine *co =3D qemu_coroutine_create(co_entry, &rwco); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(blk_bs(blk), co); BDRV_POLL_WHILE(blk_bs(blk), rwco.ret =3D=3D NOT_DONE); } =20 @@ -1114,7 +1114,7 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, in= t64_t offset, int bytes, acb->has_returned =3D false; =20 co =3D qemu_coroutine_create(co_entry, acb); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(blk_bs(blk), co); =20 acb->has_returned =3D true; if (acb->rwco.ret !=3D NOT_DONE) { diff --git a/block/io.c b/block/io.c index 2709a70..30083a7 100644 --- a/block/io.c +++ b/block/io.c @@ -616,7 +616,7 @@ static int bdrv_prwv_co(BdrvChild *child, int64_t offse= t, bdrv_rw_co_entry(&rwco); } else { co =3D qemu_coroutine_create(bdrv_rw_co_entry, &rwco); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(child->bs, co); BDRV_POLL_WHILE(child->bs, rwco.ret =3D=3D NOT_DONE); } return rwco.ret; @@ -1873,7 +1873,7 @@ int64_t bdrv_get_block_status_above(BlockDriverState = *bs, } else { co =3D qemu_coroutine_create(bdrv_get_block_status_above_co_entry, &data); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(bs, co); BDRV_POLL_WHILE(bs, !data.done); } return data.ret; @@ -1999,7 +1999,7 @@ bdrv_rw_vmstate(BlockDriverState *bs, QEMUIOVector *q= iov, int64_t pos, }; Coroutine *co =3D qemu_coroutine_create(bdrv_co_rw_vmstate_entry, = &data); =20 - qemu_coroutine_enter(co); + bdrv_coroutine_enter(bs, co); while (data.ret =3D=3D -EINPROGRESS) { aio_poll(bdrv_get_aio_context(bs), true); } @@ -2216,7 +2216,7 @@ static BlockAIOCB *bdrv_co_aio_prw_vector(BdrvChild *= child, acb->is_write =3D is_write; =20 co =3D qemu_coroutine_create(bdrv_co_do_rw, acb); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(child->bs, co); =20 bdrv_co_maybe_schedule_bh(acb); return &acb->common; @@ -2247,7 +2247,7 @@ BlockAIOCB *bdrv_aio_flush(BlockDriverState *bs, acb->req.error =3D -EINPROGRESS; =20 co =3D qemu_coroutine_create(bdrv_aio_flush_co_entry, acb); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(bs, co); =20 bdrv_co_maybe_schedule_bh(acb); return &acb->common; @@ -2380,7 +2380,7 @@ int bdrv_flush(BlockDriverState *bs) bdrv_flush_co_entry(&flush_co); } else { co =3D qemu_coroutine_create(bdrv_flush_co_entry, &flush_co); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(bs, co); BDRV_POLL_WHILE(bs, flush_co.ret =3D=3D NOT_DONE); } =20 @@ -2527,7 +2527,7 @@ int bdrv_pdiscard(BlockDriverState *bs, int64_t offse= t, int count) bdrv_pdiscard_co_entry(&rwco); } else { co =3D qemu_coroutine_create(bdrv_pdiscard_co_entry, &rwco); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(bs, co); BDRV_POLL_WHILE(bs, rwco.ret =3D=3D NOT_DONE); } =20 diff --git a/block/mirror.c b/block/mirror.c index e904fef..a68855c 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -130,7 +130,7 @@ static void mirror_iteration_done(MirrorOp *op, int ret) g_free(op); =20 if (s->waiting_for_io) { - qemu_coroutine_enter(s->common.co); + bdrv_coroutine_enter(s->source, s->common.co); } } =20 diff --git a/block/quorum.c b/block/quorum.c index 40205fb..4d42e4a 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -270,16 +270,16 @@ static void quorum_rewrite_entry(void *opaque) QuorumCo *co =3D opaque; QuorumAIOCB *acb =3D co->acb; BDRVQuorumState *s =3D acb->bs->opaque; + BdrvChild *child =3D s->children[co->idx]; =20 /* Ignore any errors, it's just a correction attempt for already * corrupted data. */ - bdrv_co_pwritev(s->children[co->idx], acb->offset, acb->bytes, - acb->qiov, 0); + bdrv_co_pwritev(child, acb->offset, acb->bytes, acb->qiov, 0); =20 /* Wake up the caller after the last rewrite */ acb->rewrite_count--; if (!acb->rewrite_count) { - qemu_coroutine_enter_if_inactive(acb->co); + bdrv_coroutine_enter_if_inactive(child->bs, acb->co); } } =20 @@ -318,7 +318,7 @@ static bool quorum_rewrite_bad_versions(QuorumAIOCB *ac= b, }; =20 co =3D qemu_coroutine_create(quorum_rewrite_entry, &data); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(acb->bs, co); } } =20 @@ -602,7 +602,7 @@ static void read_quorum_children_entry(void *opaque) =20 /* Wake up the caller after the last read */ if (acb->count =3D=3D s->num_children) { - qemu_coroutine_enter_if_inactive(acb->co); + bdrv_coroutine_enter_if_inactive(sacb->bs, acb->co); } } =20 @@ -626,7 +626,7 @@ static int read_quorum_children(QuorumAIOCB *acb) }; =20 co =3D qemu_coroutine_create(read_quorum_children_entry, &data); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(acb->bs, co); } =20 while (acb->count < s->num_children) { @@ -712,7 +712,7 @@ static void write_quorum_entry(void *opaque) =20 /* Wake up the caller after the last write */ if (acb->count =3D=3D s->num_children) { - qemu_coroutine_enter_if_inactive(acb->co); + bdrv_coroutine_enter_if_inactive(sacb->bs, acb->co); } } =20 @@ -731,7 +731,7 @@ static int quorum_co_pwritev(BlockDriverState *bs, uint= 64_t offset, }; =20 co =3D qemu_coroutine_create(write_quorum_entry, &data); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(bs, co); } =20 while (acb->count < s->num_children) { diff --git a/block/sheepdog.c b/block/sheepdog.c index 1b71fc8..ac6d32a 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -736,10 +736,10 @@ static int do_req(int sockfd, BlockDriverState *bs, S= heepdogReq *hdr, } else { co =3D qemu_coroutine_create(do_co_req, &srco); if (bs) { - qemu_coroutine_enter(co); + bdrv_coroutine_enter(bs, co); BDRV_POLL_WHILE(bs, !srco.finished); } else { - qemu_coroutine_enter(co); + bdrv_coroutine_enter(bs, co); while (!srco.finished) { aio_poll(qemu_get_aio_context(), true); } diff --git a/blockjob.c b/blockjob.c index 9b619f385..6e48932 100644 --- a/blockjob.c +++ b/blockjob.c @@ -290,7 +290,7 @@ void block_job_start(BlockJob *job) job->pause_count--; job->busy =3D true; job->paused =3D false; - qemu_coroutine_enter(job->co); + bdrv_coroutine_enter(blk_bs(job->blk), job->co); } =20 void block_job_ref(BlockJob *job) @@ -532,7 +532,7 @@ void block_job_user_resume(BlockJob *job) void block_job_enter(BlockJob *job) { if (job->co && !job->busy) { - qemu_coroutine_enter(job->co); + bdrv_coroutine_enter(blk_bs(job->blk), job->co); } } =20 diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index c80ba67..af4acb4 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -3463,7 +3463,7 @@ void pdu_submit(V9fsPDU *pdu) handler =3D v9fs_fs_ro; } co =3D qemu_coroutine_create(handler, pdu); - qemu_coroutine_enter(co); + qemu_coroutine_enter(qemu_get_aio_context(), co); } =20 /* Returns 0 on success, 1 on failure. */ @@ -3596,7 +3596,7 @@ void v9fs_reset(V9fsState *s) } =20 co =3D qemu_coroutine_create(virtfs_co_reset, &data); - qemu_coroutine_enter(co); + qemu_coroutine_enter(qemu_get_aio_context(), co); =20 while (!data.done) { aio_poll(qemu_get_aio_context(), true); diff --git a/hw/9pfs/coth.c b/hw/9pfs/coth.c index 89018de..70e2667 100644 --- a/hw/9pfs/coth.c +++ b/hw/9pfs/coth.c @@ -22,14 +22,14 @@ static void coroutine_enter_cb(void *opaque, int ret) { Coroutine *co =3D opaque; - qemu_coroutine_enter(co); + qemu_coroutine_enter(qemu_get_aio_context(), co); } =20 /* Called from worker thread. */ static int coroutine_enter_func(void *arg) { Coroutine *co =3D arg; - qemu_coroutine_enter(co); + qemu_coroutine_enter(qemu_get_aio_context(), co); return 0; } =20 diff --git a/include/block/block.h b/include/block/block.h index 5149260..00db53f 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -556,6 +556,17 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, con= st char *tag); AioContext *bdrv_get_aio_context(BlockDriverState *bs); =20 /** + * Transfer control to @co in the aio context of @bs + */ +void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co); + +/** + * Transfer control to @co in the aio context of @bs if it's not active (i= .e. + * part of the call stack of the running coroutine). Otherwise, do nothing. + */ +void bdrv_coroutine_enter_if_inactive(BlockDriverState *bs, Coroutine *co); + +/** * bdrv_set_aio_context: * * Changes the #AioContext used for fd handlers, timers, and BHs by this diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index e60beaf..77f2de1 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -66,15 +66,16 @@ typedef void coroutine_fn CoroutineEntry(void *opaque); Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque); =20 /** - * Transfer control to a coroutine + * Transfer control to a coroutine and associate it to @ctx */ -void qemu_coroutine_enter(Coroutine *coroutine); +void qemu_coroutine_enter(AioContext *ctx, Coroutine *coroutine); =20 /** - * Transfer control to a coroutine if it's not active (i.e. part of the ca= ll - * stack of the running coroutine). Otherwise, do nothing. + * Transfer control to a coroutine and associate it to @ctx, if it's not a= ctive + * (i.e. part of the call stack of the running coroutine). Otherwise, do + * nothing. */ -void qemu_coroutine_enter_if_inactive(Coroutine *co); +void qemu_coroutine_enter_if_inactive(AioContext *ctx, Coroutine *co); =20 /** * Transfer control back to a coroutine's caller diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index d7e24af..8a19e10 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -64,7 +64,7 @@ int qemu_init_main_loop(Error **errp); * * void enter_co_bh(void *opaque) { * QEMUCoroutine *co =3D opaque; - * qemu_coroutine_enter(co); + * qemu_coroutine_enter(ctx, co); * } * * ... diff --git a/migration/colo.c b/migration/colo.c index c19eb3f..7167ce7 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -100,7 +100,8 @@ static void secondary_vm_do_failover(void) qemu_sem_post(&mis->colo_incoming_sem); /* For Secondary VM, jump to incoming co */ if (mis->migration_incoming_co) { - qemu_coroutine_enter(mis->migration_incoming_co); + qemu_coroutine_enter(qemu_get_aio_context(), + mis->migration_incoming_co); } } =20 diff --git a/migration/migration.c b/migration/migration.c index 54060f7..82ed7e4 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -449,7 +449,7 @@ void migration_fd_process_incoming(QEMUFile *f) =20 migrate_decompress_threads_create(); qemu_file_set_blocking(f, false); - qemu_coroutine_enter(co); + qemu_coroutine_enter(qemu_get_aio_context(), co); } =20 =20 diff --git a/nbd/server.c b/nbd/server.c index 924a1fe..a2635d2 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -108,7 +108,7 @@ static gboolean nbd_negotiate_continue(QIOChannel *ioc, GIOCondition condition, void *opaque) { - qemu_coroutine_enter(opaque); + qemu_coroutine_enter(ioc->ctx, opaque); return TRUE; } =20 @@ -1418,5 +1418,6 @@ void nbd_client_new(NBDExport *exp, =20 data->client =3D client; data->co =3D qemu_coroutine_create(nbd_co_client_start, data); - qemu_coroutine_enter(data->co); + qemu_coroutine_enter(exp ? exp->ctx : qemu_get_aio_context(), + data->co); } diff --git a/qemu-img.c b/qemu-img.c index b220cf7..ffb09f7 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1830,7 +1830,7 @@ static void coroutine_fn convert_co_do_copy(void *opa= que) * s->wait_sector_num[i] =3D=3D -1 during A -> B. The= refore * B will never enter A during this time window. */ - qemu_coroutine_enter(s->co[i]); + qemu_coroutine_enter(qemu_get_aio_context(), s->co[i]); break; } } @@ -1896,7 +1896,7 @@ static int convert_do_copy(ImgConvertState *s) for (i =3D 0; i < s->num_coroutines; i++) { s->co[i] =3D qemu_coroutine_create(convert_co_do_copy, s); s->wait_sector_num[i] =3D -1; - qemu_coroutine_enter(s->co[i]); + qemu_coroutine_enter(qemu_get_aio_context(), s->co[i]); } =20 while (s->ret =3D=3D -EINPROGRESS) { diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 883f53b..312fc6d 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -521,7 +521,7 @@ static int do_co_pwrite_zeroes(BlockBackend *blk, int64= _t offset, } =20 co =3D qemu_coroutine_create(co_pwrite_zeroes_entry, &data); - qemu_coroutine_enter(co); + bdrv_coroutine_enter(blk_bs(blk), co); while (!data.done) { aio_poll(blk_get_aio_context(blk), true); } diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c index abd97c2..64f2563 100644 --- a/tests/test-coroutine.c +++ b/tests/test-coroutine.c @@ -14,6 +14,7 @@ #include "qemu/osdep.h" #include "qemu/coroutine.h" #include "qemu/coroutine_int.h" +#include "qemu/main-loop.h" =20 /* * Check that qemu_in_coroutine() works @@ -31,7 +32,7 @@ static void test_in_coroutine(void) g_assert(!qemu_in_coroutine()); =20 coroutine =3D qemu_coroutine_create(verify_in_coroutine, NULL); - qemu_coroutine_enter(coroutine); + qemu_coroutine_enter(qemu_get_aio_context(), coroutine); } =20 /* @@ -49,7 +50,7 @@ static void test_self(void) Coroutine *coroutine; =20 coroutine =3D qemu_coroutine_create(verify_self, &coroutine); - qemu_coroutine_enter(coroutine); + qemu_coroutine_enter(qemu_get_aio_context(), coroutine); } =20 /* @@ -79,9 +80,9 @@ static void coroutine_fn verify_entered_step_1(void *opaq= ue) =20 coroutine =3D qemu_coroutine_create(verify_entered_step_2, self); g_assert(!qemu_coroutine_entered(coroutine)); - qemu_coroutine_enter(coroutine); + qemu_coroutine_enter(qemu_get_aio_context(), coroutine); g_assert(!qemu_coroutine_entered(coroutine)); - qemu_coroutine_enter(coroutine); + qemu_coroutine_enter(qemu_get_aio_context(), coroutine); } =20 static void test_entered(void) @@ -90,7 +91,7 @@ static void test_entered(void) =20 coroutine =3D qemu_coroutine_create(verify_entered_step_1, NULL); g_assert(!qemu_coroutine_entered(coroutine)); - qemu_coroutine_enter(coroutine); + qemu_coroutine_enter(qemu_get_aio_context(), coroutine); } =20 /* @@ -113,7 +114,7 @@ static void coroutine_fn nest(void *opaque) Coroutine *child; =20 child =3D qemu_coroutine_create(nest, nd); - qemu_coroutine_enter(child); + qemu_coroutine_enter(qemu_get_aio_context(), child); } =20 nd->n_return++; @@ -129,7 +130,7 @@ static void test_nesting(void) }; =20 root =3D qemu_coroutine_create(nest, &nd); - qemu_coroutine_enter(root); + qemu_coroutine_enter(qemu_get_aio_context(), root); =20 /* Must enter and return from max nesting level */ g_assert_cmpint(nd.n_enter, =3D=3D, nd.max); @@ -159,7 +160,7 @@ static void test_yield(void) =20 coroutine =3D qemu_coroutine_create(yield_5_times, &done); while (!done) { - qemu_coroutine_enter(coroutine); + qemu_coroutine_enter(qemu_get_aio_context(), coroutine); i++; } g_assert_cmpint(i, =3D=3D, 5); /* coroutine must yield 5 times */ @@ -173,7 +174,7 @@ static void coroutine_fn c2_fn(void *opaque) static void coroutine_fn c1_fn(void *opaque) { Coroutine *c2 =3D opaque; - qemu_coroutine_enter(c2); + qemu_coroutine_enter(qemu_get_aio_context(), c2); } =20 static void test_co_queue(void) @@ -185,12 +186,12 @@ static void test_co_queue(void) c2 =3D qemu_coroutine_create(c2_fn, NULL); c1 =3D qemu_coroutine_create(c1_fn, c2); =20 - qemu_coroutine_enter(c1); + qemu_coroutine_enter(qemu_get_aio_context(), c1); =20 /* c1 shouldn't be used any more now; make sure we segfault if it is */ tmp =3D *c1; memset(c1, 0xff, sizeof(Coroutine)); - qemu_coroutine_enter(c2); + qemu_coroutine_enter(qemu_get_aio_context(), c2); =20 /* Must restore the coroutine now to avoid corrupted pool */ *c1 =3D tmp; @@ -214,13 +215,13 @@ static void test_lifecycle(void) =20 /* Create, enter, and return from coroutine */ coroutine =3D qemu_coroutine_create(set_and_exit, &done); - qemu_coroutine_enter(coroutine); + qemu_coroutine_enter(qemu_get_aio_context(), coroutine); g_assert(done); /* expect done to be true (first time) */ =20 /* Repeat to check that no state affects this test */ done =3D false; coroutine =3D qemu_coroutine_create(set_and_exit, &done); - qemu_coroutine_enter(coroutine); + qemu_coroutine_enter(qemu_get_aio_context(), coroutine); g_assert(done); /* expect done to be true (second time) */ } =20 @@ -256,10 +257,10 @@ static void do_order_test(void) =20 co =3D qemu_coroutine_create(co_order_test, NULL); record_push(1, 1); - qemu_coroutine_enter(co); + qemu_coroutine_enter(qemu_get_aio_context(), co); record_push(1, 2); g_assert(!qemu_in_coroutine()); - qemu_coroutine_enter(co); + qemu_coroutine_enter(qemu_get_aio_context(), co); record_push(1, 3); g_assert(!qemu_in_coroutine()); } @@ -297,7 +298,7 @@ static void perf_lifecycle(void) g_test_timer_start(); for (i =3D 0; i < max; i++) { coroutine =3D qemu_coroutine_create(empty_coroutine, NULL); - qemu_coroutine_enter(coroutine); + qemu_coroutine_enter(qemu_get_aio_context(), coroutine); } duration =3D g_test_timer_elapsed(); =20 @@ -321,7 +322,7 @@ static void perf_nesting(void) .max =3D maxnesting, }; root =3D qemu_coroutine_create(nest, &nd); - qemu_coroutine_enter(root); + qemu_coroutine_enter(qemu_get_aio_context(), root); } duration =3D g_test_timer_elapsed(); =20 @@ -354,7 +355,7 @@ static void perf_yield(void) =20 g_test_timer_start(); while (i > 0) { - qemu_coroutine_enter(coroutine); + qemu_coroutine_enter(qemu_get_aio_context(), coroutine); } duration =3D g_test_timer_elapsed(); =20 @@ -401,8 +402,8 @@ static void perf_cost(void) g_test_timer_start(); while (i++ < maxcycles) { co =3D qemu_coroutine_create(perf_cost_func, &i); - qemu_coroutine_enter(co); - qemu_coroutine_enter(co); + qemu_coroutine_enter(qemu_get_aio_context(), co); + qemu_coroutine_enter(qemu_get_aio_context(), co); } duration =3D g_test_timer_elapsed(); ops =3D (long)(maxcycles / (duration * 1000)); diff --git a/tests/test-thread-pool.c b/tests/test-thread-pool.c index 91b4ec5..ba4fee4 100644 --- a/tests/test-thread-pool.c +++ b/tests/test-thread-pool.c @@ -94,7 +94,7 @@ static void test_submit_co(void) WorkerTestData data; Coroutine *co =3D qemu_coroutine_create(co_test_cb, &data); =20 - qemu_coroutine_enter(co); + qemu_coroutine_enter(qemu_get_aio_context(), co); =20 /* Back here once the worker has started. */ =20 diff --git a/util/async.c b/util/async.c index 663e297..3289a36 100644 --- a/util/async.c +++ b/util/async.c @@ -388,7 +388,7 @@ static void co_schedule_bh_cb(void *opaque) QSLIST_REMOVE_HEAD(&straight, co_scheduled_next); trace_aio_co_schedule_bh_cb(ctx, co); aio_context_acquire(ctx); - qemu_coroutine_enter(co); + qemu_coroutine_enter(ctx, co); aio_context_release(ctx); } } @@ -464,7 +464,7 @@ void aio_co_wake(struct Coroutine *co) QSIMPLEQ_INSERT_TAIL(&self->co_queue_wakeup, co, co_queue_next); } else { aio_context_acquire(ctx); - qemu_coroutine_enter(co); + qemu_coroutine_enter(ctx, co); aio_context_release(ctx); } } diff --git a/util/qemu-coroutine-io.c b/util/qemu-coroutine-io.c index 44a8969..26818af 100644 --- a/util/qemu-coroutine-io.c +++ b/util/qemu-coroutine-io.c @@ -75,7 +75,8 @@ static void fd_coroutine_enter(void *opaque) { FDYieldUntilData *data =3D opaque; qemu_set_fd_handler(data->fd, NULL, NULL, NULL); - qemu_coroutine_enter(data->co); + /* XXX: do we need an explicit ctx? */ + qemu_coroutine_enter(qemu_get_current_aio_context(), data->co); } =20 void coroutine_fn yield_until_fd_readable(int fd) diff --git a/util/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c index 6328eed..42c18d8 100644 --- a/util/qemu-coroutine-lock.c +++ b/util/qemu-coroutine-lock.c @@ -81,7 +81,8 @@ void qemu_co_queue_run_restart(Coroutine *co) trace_qemu_co_queue_run_restart(co); while ((next =3D QSIMPLEQ_FIRST(&co->co_queue_wakeup))) { QSIMPLEQ_REMOVE_HEAD(&co->co_queue_wakeup, co_queue_next); - qemu_coroutine_enter(next); + assert(next->ctx); + qemu_coroutine_enter(next->ctx, next); } } =20 @@ -125,7 +126,8 @@ bool qemu_co_enter_next(CoQueue *queue) } =20 QSIMPLEQ_REMOVE_HEAD(&queue->entries, co_queue_next); - qemu_coroutine_enter(next); + assert(next->ctx); + qemu_coroutine_enter(next->ctx, next); return true; } =20 diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c index 72412e5..47329a0 100644 --- a/util/qemu-coroutine.c +++ b/util/qemu-coroutine.c @@ -102,12 +102,12 @@ static void coroutine_delete(Coroutine *co) qemu_coroutine_delete(co); } =20 -void qemu_coroutine_enter(Coroutine *co) +void qemu_coroutine_enter(AioContext *ctx, Coroutine *co) { Coroutine *self =3D qemu_coroutine_self(); CoroutineAction ret; =20 - trace_qemu_coroutine_enter(self, co, co->entry_arg); + trace_qemu_coroutine_enter(self, ctx, co, co->entry_arg); =20 if (co->caller) { fprintf(stderr, "Co-routine re-entered recursively\n"); @@ -115,7 +115,7 @@ void qemu_coroutine_enter(Coroutine *co) } =20 co->caller =3D self; - co->ctx =3D qemu_get_current_aio_context(); + co->ctx =3D ctx; =20 /* Store co->ctx before anything that stores co. Matches * barrier in aio_co_wake and qemu_co_mutex_wake. @@ -139,10 +139,10 @@ void qemu_coroutine_enter(Coroutine *co) } } =20 -void qemu_coroutine_enter_if_inactive(Coroutine *co) +void qemu_coroutine_enter_if_inactive(AioContext *ctx, Coroutine *co) { if (!qemu_coroutine_entered(co)) { - qemu_coroutine_enter(co); + qemu_coroutine_enter(ctx, co); } } =20 diff --git a/util/trace-events b/util/trace-events index ac27d94..d3c39a6 100644 --- a/util/trace-events +++ b/util/trace-events @@ -22,7 +22,7 @@ buffer_move(const char *buf, size_t len, const char *from= ) "%s: %zd bytes from % buffer_free(const char *buf, size_t len) "%s: capacity %zd" =20 # util/qemu-coroutine.c -qemu_coroutine_enter(void *from, void *to, void *opaque) "from %p to %p op= aque %p" +qemu_coroutine_enter(void *ctx, void *from, void *to, void *opaque) "ctx %= p from %p to %p opaque %p" qemu_coroutine_yield(void *from, void *to) "from %p to %p" qemu_coroutine_terminate(void *co) "self %p" =20 --=20 2.9.3 From nobody Sat May 4 02:01:43 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1491548323020439.1961608317613; Thu, 6 Apr 2017 23:58:43 -0700 (PDT) Received: from localhost ([::1]:49270 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNqz-0002r6-T3 for importer@patchew.org; Fri, 07 Apr 2017 02:58:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46411) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwNoD-0000SJ-Pi for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:55:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cwNoC-0004x6-Js for qemu-devel@nongnu.org; Fri, 07 Apr 2017 02:55:49 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42280) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cwNoA-0004w2-25; Fri, 07 Apr 2017 02:55:46 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E4190C059751; Fri, 7 Apr 2017 06:55:44 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-27.pek2.redhat.com [10.72.8.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id BE42918983; Fri, 7 Apr 2017 06:55:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com E4190C059751 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=famz@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com E4190C059751 From: Fam Zheng To: qemu-devel@nongnu.org Date: Fri, 7 Apr 2017 14:54:14 +0800 Message-Id: <20170407065414.9143-7-famz@redhat.com> In-Reply-To: <20170407065414.9143-1-famz@redhat.com> References: <20170407065414.9143-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 07 Apr 2017 06:55:45 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 6/6] tests/block-job-txn: Don't start block job before adding to txn X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Max Reitz , Ed Swierk , Stefan Hajnoczi , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Previously, before test_block_job_start returns, the job can already complete, as a result, the transactional state of other jobs added to the same txn later cannot be handled correctly. Move the block_job_start() calls to callers after block_job_txn_add_job() calls. Signed-off-by: Fam Zheng --- tests/test-blockjob-txn.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c index 4ccbda1..0f80194 100644 --- a/tests/test-blockjob-txn.c +++ b/tests/test-blockjob-txn.c @@ -110,7 +110,6 @@ static BlockJob *test_block_job_start(unsigned int iter= ations, s->result =3D result; data->job =3D s; data->result =3D result; - block_job_start(&s->common); return &s->common; } =20 @@ -123,6 +122,7 @@ static void test_single_job(int expected) txn =3D block_job_txn_new(); job =3D test_block_job_start(1, true, expected, &result); block_job_txn_add_job(txn, job); + block_job_start(job); =20 if (expected =3D=3D -ECANCELED) { block_job_cancel(job); @@ -164,6 +164,8 @@ static void test_pair_jobs(int expected1, int expected2) block_job_txn_add_job(txn, job1); job2 =3D test_block_job_start(2, true, expected2, &result2); block_job_txn_add_job(txn, job2); + block_job_start(job1); + block_job_start(job2); =20 if (expected1 =3D=3D -ECANCELED) { block_job_cancel(job1); @@ -223,6 +225,8 @@ static void test_pair_jobs_fail_cancel_race(void) block_job_txn_add_job(txn, job1); job2 =3D test_block_job_start(2, false, 0, &result2); block_job_txn_add_job(txn, job2); + block_job_start(job1); + block_job_start(job2); =20 block_job_cancel(job1); =20 --=20 2.9.3