From nobody Thu May 2 16:06:33 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 1491488835345622.053546664152; Thu, 6 Apr 2017 07:27:15 -0700 (PDT) Received: from localhost ([::1]:46175 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cw8NU-0006Jc-Uw for importer@patchew.org; Thu, 06 Apr 2017 10:27:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45957) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cw8MD-0005S4-T7 for qemu-devel@nongnu.org; Thu, 06 Apr 2017 10:25:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cw8MD-0001eu-62 for qemu-devel@nongnu.org; Thu, 06 Apr 2017 10:25:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33748) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cw8MA-0001aF-LM; Thu, 06 Apr 2017 10:25:50 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AE0627F7DD; Thu, 6 Apr 2017 14:25:49 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-70.pek2.redhat.com [10.72.8.70]) by smtp.corp.redhat.com (Postfix) with ESMTP id E1D019B54F; Thu, 6 Apr 2017 14:25:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com AE0627F7DD Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=famz@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com AE0627F7DD From: Fam Zheng To: qemu-devel@nongnu.org Date: Thu, 6 Apr 2017 22:25:23 +0800 Message-Id: <20170406142527.25835-2-famz@redhat.com> In-Reply-To: <20170406142527.25835-1-famz@redhat.com> References: <20170406142527.25835-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 06 Apr 2017 14:25:49 +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 for-2.9 1/5] 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 forcing callers to move the aio context first, and assert it. Reported-by: Ed Swierk Signed-off-by: Fam Zheng Reviewed-by: Eric Blake --- block.c | 3 +++ blockdev.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index 927ba89..8893ac1 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); 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 Thu May 2 16:06:33 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 1491488952633753.4051420663275; Thu, 6 Apr 2017 07:29:12 -0700 (PDT) Received: from localhost ([::1]:46185 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cw8PP-0008AD-Bu for importer@patchew.org; Thu, 06 Apr 2017 10:29:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46023) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cw8MM-0005aG-PL for qemu-devel@nongnu.org; Thu, 06 Apr 2017 10:26:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cw8MM-0001le-3e for qemu-devel@nongnu.org; Thu, 06 Apr 2017 10:26:02 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56500) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cw8MH-0001ix-Ic; Thu, 06 Apr 2017 10:25:57 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8C708804F0; Thu, 6 Apr 2017 14:25:56 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-70.pek2.redhat.com [10.72.8.70]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5EFEF9B54F; Thu, 6 Apr 2017 14:25:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8C708804F0 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=famz@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 8C708804F0 From: Fam Zheng To: qemu-devel@nongnu.org Date: Thu, 6 Apr 2017 22:25:24 +0800 Message-Id: <20170406142527.25835-3-famz@redhat.com> In-Reply-To: <20170406142527.25835-1-famz@redhat.com> References: <20170406142527.25835-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 06 Apr 2017 14:25:56 +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 for-2.9 2/5] 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. Signed-off-by: Fam Zheng Reviewed-by: Eric Blake Reviewed-by: Kevin Wolf --- 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 Thu May 2 16:06:33 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 1491489042381336.778345668566; Thu, 6 Apr 2017 07:30:42 -0700 (PDT) Received: from localhost ([::1]:46202 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cw8Qr-0001Kt-Ax for importer@patchew.org; Thu, 06 Apr 2017 10:30:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46110) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cw8MW-0005hO-UJ for qemu-devel@nongnu.org; Thu, 06 Apr 2017 10:26:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cw8MW-0001oi-1U for qemu-devel@nongnu.org; Thu, 06 Apr 2017 10:26:12 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54810) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cw8MR-0001n8-BF; Thu, 06 Apr 2017 10:26:07 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5F05261E64; Thu, 6 Apr 2017 14:26:06 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-70.pek2.redhat.com [10.72.8.70]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3E3D59B54F; Thu, 6 Apr 2017 14:25:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 5F05261E64 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 5F05261E64 From: Fam Zheng To: qemu-devel@nongnu.org Date: Thu, 6 Apr 2017 22:25:25 +0800 Message-Id: <20170406142527.25835-4-famz@redhat.com> In-Reply-To: <20170406142527.25835-1-famz@redhat.com> References: <20170406142527.25835-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 06 Apr 2017 14:26:06 +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 for-2.9 3/5] 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 Signed-off-by: Fam Zheng Reviewed-by: Eric Blake --- block.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index 8893ac1..e70684a 100644 --- a/block.c +++ b/block.c @@ -4395,11 +4395,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 */ } @@ -4412,6 +4415,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 Thu May 2 16:06:33 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 1491488966968702.1065715447822; Thu, 6 Apr 2017 07:29:26 -0700 (PDT) Received: from localhost ([::1]:46186 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cw8Pd-0008Ow-KK for importer@patchew.org; Thu, 06 Apr 2017 10:29:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46172) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cw8Md-0005mZ-7z for qemu-devel@nongnu.org; Thu, 06 Apr 2017 10:26:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cw8Ma-0001pw-13 for qemu-devel@nongnu.org; Thu, 06 Apr 2017 10:26:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36554) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cw8MX-0001oy-SA; Thu, 06 Apr 2017 10:26:13 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DD3ED6AAD0; Thu, 6 Apr 2017 14:26:12 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-70.pek2.redhat.com [10.72.8.70]) by smtp.corp.redhat.com (Postfix) with ESMTP id 38368A1961; Thu, 6 Apr 2017 14:26:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com DD3ED6AAD0 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=famz@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com DD3ED6AAD0 From: Fam Zheng To: qemu-devel@nongnu.org Date: Thu, 6 Apr 2017 22:25:26 +0800 Message-Id: <20170406142527.25835-5-famz@redhat.com> In-Reply-To: <20170406142527.25835-1-famz@redhat.com> References: <20170406142527.25835-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 06 Apr 2017 14:26:13 +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 for-2.9 4/5] block: Drain BH in bdrv_drained_begin 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" During block job completion, nothing is preventing block_job_defer_to_main_loop_bh from being called in a nested aio_poll(), which is a trouble, such as in this code path: qmp_block_commit commit_active_start bdrv_reopen bdrv_reopen_multiple bdrv_reopen_prepare bdrv_flush aio_poll aio_bh_poll aio_bh_call block_job_defer_to_main_loop_bh stream_complete bdrv_reopen block_job_defer_to_main_loop_bh is the last step of the stream job, which should have been "paused" by the bdrv_drained_begin/end in bdrv_reopen_multiple, but it is not done because it's in the form of a main loop BH. Similar to why block jobs should be paused between drained_begin and drained_end, BHs they schedule must be excluded as well. To achieve this, this patch forces draining the BH before leaving bdrv_drained_begin(). Signed-off-by: Fam Zheng Reviewed-by: Eric Blake --- block/io.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block/io.c b/block/io.c index 2709a70..b9cfd18 100644 --- a/block/io.c +++ b/block/io.c @@ -228,7 +228,12 @@ void bdrv_drained_begin(BlockDriverState *bs) bdrv_parent_drained_begin(bs); } =20 - bdrv_drain_recurse(bs); + while (true) { + if (!bdrv_drain_recurse(bs) && + !aio_poll(bdrv_get_aio_context(bs), false)) { + break; + } + } } =20 void bdrv_drained_end(BlockDriverState *bs) --=20 2.9.3 From nobody Thu May 2 16:06:33 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 1491488878774803.3814430846784; Thu, 6 Apr 2017 07:27:58 -0700 (PDT) Received: from localhost ([::1]:46177 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cw8OD-0006xB-B4 for importer@patchew.org; Thu, 06 Apr 2017 10:27:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46345) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cw8Mm-0005tT-GF for qemu-devel@nongnu.org; Thu, 06 Apr 2017 10:26:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cw8Mj-0001uG-6K for qemu-devel@nongnu.org; Thu, 06 Apr 2017 10:26:28 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40686) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cw8Md-0001rD-Jq; Thu, 06 Apr 2017 10:26:19 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 955948123D; Thu, 6 Apr 2017 14:26:18 +0000 (UTC) Received: from lemon.redhat.com (ovpn-8-70.pek2.redhat.com [10.72.8.70]) by smtp.corp.redhat.com (Postfix) with ESMTP id D6A2A9B54F; Thu, 6 Apr 2017 14:26:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 955948123D Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=famz@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 955948123D From: Fam Zheng To: qemu-devel@nongnu.org Date: Thu, 6 Apr 2017 22:25:27 +0800 Message-Id: <20170406142527.25835-6-famz@redhat.com> In-Reply-To: <20170406142527.25835-1-famz@redhat.com> References: <20170406142527.25835-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 06 Apr 2017 14:26:18 +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 for-2.9 5/5] coroutine: Explicitly specify AioContext when creating 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. Make the block layer explicitly specify a desired context for each created coroutine. For the rest, always use qemu_get_aio_context(). Signed-off-by: Fam Zheng Reviewed-by: Eric Blake --- block.c | 9 +++++++- block/blkverify.c | 4 ++-- block/block-backend.c | 4 ++-- block/io.c | 14 ++++++------- block/nbd-client.c | 2 +- block/quorum.c | 6 +++--- block/sheepdog.c | 4 ++-- blockjob.c | 2 +- hw/9pfs/9p.c | 4 ++-- include/block/block.h | 3 +++ include/qemu/coroutine.h | 3 ++- include/qemu/main-loop.h | 2 +- migration/migration.c | 3 ++- nbd/server.c | 6 ++++-- qemu-img.c | 3 ++- qemu-io-cmds.c | 3 ++- tests/test-aio-multithread.c | 12 +++++++---- tests/test-coroutine.c | 50 ++++++++++++++++++++++++++++++----------= ---- tests/test-thread-pool.c | 3 ++- util/qemu-coroutine.c | 6 ++++-- 20 files changed, 92 insertions(+), 51 deletions(-) diff --git a/block.c b/block.c index e70684a..d3598d5 100644 --- a/block.c +++ b/block.c @@ -357,7 +357,8 @@ int bdrv_create(BlockDriver *drv, const char* filename, /* Fast-path if already in coroutine context */ bdrv_create_co_entry(&cco); } else { - co =3D qemu_coroutine_create(bdrv_create_co_entry, &cco); + co =3D qemu_coroutine_create(qemu_get_aio_context(), + bdrv_create_co_entry, &cco); qemu_coroutine_enter(co); while (cco.ret =3D=3D NOT_DONE) { aio_poll(qemu_get_aio_context(), true); @@ -4323,6 +4324,12 @@ AioContext *bdrv_get_aio_context(BlockDriverState *b= s) return bs->aio_context; } =20 +Coroutine *bdrv_coroutine_create(BlockDriverState *bs, + CoroutineEntry *entry, void *opaque) +{ + return qemu_coroutine_create(bdrv_get_aio_context(bs), entry, opaque); +} + static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban) { QLIST_REMOVE(ban, list); diff --git a/block/blkverify.c b/block/blkverify.c index 9a1e21c..df761cf 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -204,8 +204,8 @@ blkverify_co_prwv(BlockDriverState *bs, BlkverifyReques= t *r, uint64_t offset, .request_fn =3D is_write ? bdrv_co_pwritev : bdrv_co_preadv, }; =20 - co_a =3D qemu_coroutine_create(blkverify_do_test_req, r); - co_b =3D qemu_coroutine_create(blkverify_do_raw_req, r); + co_a =3D bdrv_coroutine_create(bs, blkverify_do_test_req, r); + co_b =3D bdrv_coroutine_create(bs, blkverify_do_raw_req, r); =20 qemu_coroutine_enter(co_a); qemu_coroutine_enter(co_b); diff --git a/block/block-backend.c b/block/block-backend.c index 0b63773..6a91514 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1006,7 +1006,7 @@ static int blk_prw(BlockBackend *blk, int64_t offset,= uint8_t *buf, /* Fast-path if already in coroutine context */ co_entry(&rwco); } else { - Coroutine *co =3D qemu_coroutine_create(co_entry, &rwco); + Coroutine *co =3D bdrv_coroutine_create(blk_bs(blk), co_entry, &rw= co); qemu_coroutine_enter(co); BDRV_POLL_WHILE(blk_bs(blk), rwco.ret =3D=3D NOT_DONE); } @@ -1113,7 +1113,7 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, in= t64_t offset, int bytes, acb->bytes =3D bytes; acb->has_returned =3D false; =20 - co =3D qemu_coroutine_create(co_entry, acb); + co =3D bdrv_coroutine_create(blk_bs(blk), co_entry, acb); qemu_coroutine_enter(co); =20 acb->has_returned =3D true; diff --git a/block/io.c b/block/io.c index b9cfd18..41d7d7b 100644 --- a/block/io.c +++ b/block/io.c @@ -620,7 +620,7 @@ static int bdrv_prwv_co(BdrvChild *child, int64_t offse= t, /* Fast-path if already in coroutine context */ bdrv_rw_co_entry(&rwco); } else { - co =3D qemu_coroutine_create(bdrv_rw_co_entry, &rwco); + co =3D bdrv_coroutine_create(child->bs, bdrv_rw_co_entry, &rwco); qemu_coroutine_enter(co); BDRV_POLL_WHILE(child->bs, rwco.ret =3D=3D NOT_DONE); } @@ -1876,7 +1876,7 @@ int64_t bdrv_get_block_status_above(BlockDriverState = *bs, /* Fast-path if already in coroutine context */ bdrv_get_block_status_above_co_entry(&data); } else { - co =3D qemu_coroutine_create(bdrv_get_block_status_above_co_entry, + co =3D bdrv_coroutine_create(bs, bdrv_get_block_status_above_co_en= try, &data); qemu_coroutine_enter(co); BDRV_POLL_WHILE(bs, !data.done); @@ -2002,7 +2002,7 @@ bdrv_rw_vmstate(BlockDriverState *bs, QEMUIOVector *q= iov, int64_t pos, .is_read =3D is_read, .ret =3D -EINPROGRESS, }; - Coroutine *co =3D qemu_coroutine_create(bdrv_co_rw_vmstate_entry, = &data); + Coroutine *co =3D bdrv_coroutine_create(bs, bdrv_co_rw_vmstate_ent= ry, &data); =20 qemu_coroutine_enter(co); while (data.ret =3D=3D -EINPROGRESS) { @@ -2220,7 +2220,7 @@ static BlockAIOCB *bdrv_co_aio_prw_vector(BdrvChild *= child, acb->req.flags =3D flags; acb->is_write =3D is_write; =20 - co =3D qemu_coroutine_create(bdrv_co_do_rw, acb); + co =3D bdrv_coroutine_create(child->bs, bdrv_co_do_rw, acb); qemu_coroutine_enter(co); =20 bdrv_co_maybe_schedule_bh(acb); @@ -2251,7 +2251,7 @@ BlockAIOCB *bdrv_aio_flush(BlockDriverState *bs, acb->need_bh =3D true; acb->req.error =3D -EINPROGRESS; =20 - co =3D qemu_coroutine_create(bdrv_aio_flush_co_entry, acb); + co =3D bdrv_coroutine_create(bs, bdrv_aio_flush_co_entry, acb); qemu_coroutine_enter(co); =20 bdrv_co_maybe_schedule_bh(acb); @@ -2384,7 +2384,7 @@ int bdrv_flush(BlockDriverState *bs) /* Fast-path if already in coroutine context */ bdrv_flush_co_entry(&flush_co); } else { - co =3D qemu_coroutine_create(bdrv_flush_co_entry, &flush_co); + co =3D bdrv_coroutine_create(bs, bdrv_flush_co_entry, &flush_co); qemu_coroutine_enter(co); BDRV_POLL_WHILE(bs, flush_co.ret =3D=3D NOT_DONE); } @@ -2531,7 +2531,7 @@ int bdrv_pdiscard(BlockDriverState *bs, int64_t offse= t, int count) /* Fast-path if already in coroutine context */ bdrv_pdiscard_co_entry(&rwco); } else { - co =3D qemu_coroutine_create(bdrv_pdiscard_co_entry, &rwco); + co =3D bdrv_coroutine_create(bs, bdrv_pdiscard_co_entry, &rwco); qemu_coroutine_enter(co); BDRV_POLL_WHILE(bs, rwco.ret =3D=3D NOT_DONE); } diff --git a/block/nbd-client.c b/block/nbd-client.c index 1e2952f..526e56b 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -421,7 +421,7 @@ int nbd_client_init(BlockDriverState *bs, /* Now that we're connected, set the socket to be non-blocking and * kick the reply mechanism. */ qio_channel_set_blocking(QIO_CHANNEL(sioc), false, NULL); - client->read_reply_co =3D qemu_coroutine_create(nbd_read_reply_entry, = client); + client->read_reply_co =3D bdrv_coroutine_create(bs, nbd_read_reply_ent= ry, client); nbd_client_attach_aio_context(bs, bdrv_get_aio_context(bs)); =20 logout("Established connection with NBD server\n"); diff --git a/block/quorum.c b/block/quorum.c index 40205fb..b34e7eb 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -317,7 +317,7 @@ static bool quorum_rewrite_bad_versions(QuorumAIOCB *ac= b, .idx =3D item->index, }; =20 - co =3D qemu_coroutine_create(quorum_rewrite_entry, &data); + co =3D bdrv_coroutine_create(acb->bs, quorum_rewrite_entry, &d= ata); qemu_coroutine_enter(co); } } @@ -625,7 +625,7 @@ static int read_quorum_children(QuorumAIOCB *acb) .idx =3D i, }; =20 - co =3D qemu_coroutine_create(read_quorum_children_entry, &data); + co =3D bdrv_coroutine_create(acb->bs, read_quorum_children_entry, = &data); qemu_coroutine_enter(co); } =20 @@ -730,7 +730,7 @@ static int quorum_co_pwritev(BlockDriverState *bs, uint= 64_t offset, .idx =3D i, }; =20 - co =3D qemu_coroutine_create(write_quorum_entry, &data); + co =3D bdrv_coroutine_create(bs, write_quorum_entry, &data); qemu_coroutine_enter(co); } =20 diff --git a/block/sheepdog.c b/block/sheepdog.c index 1b71fc8..bb2feca 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -734,7 +734,7 @@ static int do_req(int sockfd, BlockDriverState *bs, She= epdogReq *hdr, if (qemu_in_coroutine()) { do_co_req(&srco); } else { - co =3D qemu_coroutine_create(do_co_req, &srco); + co =3D bdrv_coroutine_create(bs, do_co_req, &srco); if (bs) { qemu_coroutine_enter(co); BDRV_POLL_WHILE(bs, !srco.finished); @@ -939,7 +939,7 @@ static void co_read_response(void *opaque) BDRVSheepdogState *s =3D opaque; =20 if (!s->co_recv) { - s->co_recv =3D qemu_coroutine_create(aio_read_response, opaque); + s->co_recv =3D bdrv_coroutine_create(s->bs, aio_read_response, opa= que); } =20 aio_co_wake(s->co_recv); diff --git a/blockjob.c b/blockjob.c index 9b619f385..487920f 100644 --- a/blockjob.c +++ b/blockjob.c @@ -286,7 +286,7 @@ void block_job_start(BlockJob *job) { assert(job && !block_job_started(job) && job->paused && job->driver && job->driver->start); - job->co =3D qemu_coroutine_create(block_job_co_entry, job); + job->co =3D bdrv_coroutine_create(blk_bs(job->blk), block_job_co_entry= , job); job->pause_count--; job->busy =3D true; job->paused =3D false; diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index c80ba67..5ad4bc7 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -3462,7 +3462,7 @@ void pdu_submit(V9fsPDU *pdu) if (is_ro_export(&s->ctx) && !is_read_only_op(pdu)) { handler =3D v9fs_fs_ro; } - co =3D qemu_coroutine_create(handler, pdu); + co =3D qemu_coroutine_create(qemu_get_aio_context(), handler, pdu); qemu_coroutine_enter(co); } =20 @@ -3595,7 +3595,7 @@ void v9fs_reset(V9fsState *s) aio_poll(qemu_get_aio_context(), true); } =20 - co =3D qemu_coroutine_create(virtfs_co_reset, &data); + co =3D qemu_coroutine_create(qemu_get_aio_context(), virtfs_co_reset, = &data); qemu_coroutine_enter(co); =20 while (!data.done) { diff --git a/include/block/block.h b/include/block/block.h index 5149260..5dc06bf 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -555,6 +555,9 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, cons= t char *tag); */ AioContext *bdrv_get_aio_context(BlockDriverState *bs); =20 +Coroutine *bdrv_coroutine_create(BlockDriverState *bs, + CoroutineEntry *entry, void *opaque); + /** * bdrv_set_aio_context: * diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index e60beaf..57ee53d 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -63,7 +63,8 @@ typedef void coroutine_fn CoroutineEntry(void *opaque); * Use qemu_coroutine_enter() to actually transfer control to the coroutin= e. * The opaque argument is passed as the argument to the entry point. */ -Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque); +Coroutine *qemu_coroutine_create(AioContext *ctx, + CoroutineEntry *entry, void *opaque); =20 /** * Transfer control to a coroutine diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index d7e24af..6680823 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -68,7 +68,7 @@ int qemu_init_main_loop(Error **errp); * } * * ... - * QEMUCoroutine *co =3D qemu_coroutine_create(coroutine_entry, NULL); + * QEMUCoroutine *co =3D qemu_coroutine_create(ctx, coroutine_entry, N= ULL); * QEMUBH *start_bh =3D qemu_bh_new(enter_co_bh, co); * qemu_bh_schedule(start_bh); * while (...) { diff --git a/migration/migration.c b/migration/migration.c index 54060f7..7a9a1c6 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -445,7 +445,8 @@ static void process_incoming_migration_co(void *opaque) =20 void migration_fd_process_incoming(QEMUFile *f) { - Coroutine *co =3D qemu_coroutine_create(process_incoming_migration_co,= f); + Coroutine *co =3D qemu_coroutine_create(qemu_get_aio_context(), + process_incoming_migration_co, f= ); =20 migrate_decompress_threads_create(); qemu_file_set_blocking(f, false); diff --git a/nbd/server.c b/nbd/server.c index 924a1fe..ee639ab 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1363,7 +1363,8 @@ static void nbd_client_receive_next_request(NBDClient= *client) { if (!client->recv_coroutine && client->nb_requests < MAX_NBD_REQUESTS)= { nbd_client_get(client); - client->recv_coroutine =3D qemu_coroutine_create(nbd_trip, client); + client->recv_coroutine =3D qemu_coroutine_create(client->exp->ctx, + nbd_trip, client); aio_co_schedule(client->exp->ctx, client->recv_coroutine); } } @@ -1417,6 +1418,7 @@ void nbd_client_new(NBDExport *exp, client->close =3D close_fn; =20 data->client =3D client; - data->co =3D qemu_coroutine_create(nbd_co_client_start, data); + data->co =3D qemu_coroutine_create(exp ? exp->ctx : qemu_get_aio_conte= xt(), + nbd_co_client_start, data); qemu_coroutine_enter(data->co); } diff --git a/qemu-img.c b/qemu-img.c index b220cf7..9b3dd98 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1894,7 +1894,8 @@ static int convert_do_copy(ImgConvertState *s) =20 qemu_co_mutex_init(&s->lock); for (i =3D 0; i < s->num_coroutines; i++) { - s->co[i] =3D qemu_coroutine_create(convert_co_do_copy, s); + s->co[i] =3D qemu_coroutine_create(qemu_get_aio_context(), + convert_co_do_copy, s); s->wait_sector_num[i] =3D -1; qemu_coroutine_enter(s->co[i]); } diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 883f53b..31944bb 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -520,7 +520,8 @@ static int do_co_pwrite_zeroes(BlockBackend *blk, int64= _t offset, return -ERANGE; } =20 - co =3D qemu_coroutine_create(co_pwrite_zeroes_entry, &data); + co =3D qemu_coroutine_create(qemu_get_aio_context(), + co_pwrite_zeroes_entry, &data); qemu_coroutine_enter(co); while (!data.done) { aio_poll(blk_get_aio_context(blk), true); diff --git a/tests/test-aio-multithread.c b/tests/test-aio-multithread.c index 549d784..325dded 100644 --- a/tests/test-aio-multithread.c +++ b/tests/test-aio-multithread.c @@ -168,7 +168,8 @@ static void test_multi_co_schedule(int seconds) =20 create_aio_contexts(); for (i =3D 0; i < NUM_CONTEXTS; i++) { - Coroutine *co1 =3D qemu_coroutine_create(test_multi_co_schedule_en= try, NULL); + Coroutine *co1 =3D qemu_coroutine_create(ctx[i], + test_multi_co_schedule_entr= y, NULL); aio_co_schedule(ctx[i], co1); } =20 @@ -233,7 +234,8 @@ static void test_multi_co_mutex(int threads, int second= s) assert(threads <=3D NUM_CONTEXTS); running =3D threads; for (i =3D 0; i < threads; i++) { - Coroutine *co1 =3D qemu_coroutine_create(test_multi_co_mutex_entry= , NULL); + Coroutine *co1 =3D qemu_coroutine_create(ctx[i], + test_multi_co_mutex_entry, = NULL); aio_co_schedule(ctx[i], co1); } =20 @@ -352,7 +354,8 @@ static void test_multi_fair_mutex(int threads, int seco= nds) assert(threads <=3D NUM_CONTEXTS); running =3D threads; for (i =3D 0; i < threads; i++) { - Coroutine *co1 =3D qemu_coroutine_create(test_multi_fair_mutex_ent= ry, NULL); + Coroutine *co1 =3D qemu_coroutine_create(ctx[i], + test_multi_fair_mutex_entry= , NULL); aio_co_schedule(ctx[i], co1); } =20 @@ -408,7 +411,8 @@ static void test_multi_mutex(int threads, int seconds) assert(threads <=3D NUM_CONTEXTS); running =3D threads; for (i =3D 0; i < threads; i++) { - Coroutine *co1 =3D qemu_coroutine_create(test_multi_mutex_entry, N= ULL); + Coroutine *co1 =3D qemu_coroutine_create(ctx[i], + test_multi_mutex_entry, NUL= L); aio_co_schedule(ctx[i], co1); } =20 diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c index abd97c2..12a6575 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 @@ -30,7 +31,8 @@ static void test_in_coroutine(void) =20 g_assert(!qemu_in_coroutine()); =20 - coroutine =3D qemu_coroutine_create(verify_in_coroutine, NULL); + coroutine =3D qemu_coroutine_create(qemu_get_aio_context(), + verify_in_coroutine, NULL); qemu_coroutine_enter(coroutine); } =20 @@ -48,7 +50,8 @@ static void test_self(void) { Coroutine *coroutine; =20 - coroutine =3D qemu_coroutine_create(verify_self, &coroutine); + coroutine =3D qemu_coroutine_create(qemu_get_aio_context(), + verify_self, &coroutine); qemu_coroutine_enter(coroutine); } =20 @@ -77,7 +80,8 @@ static void coroutine_fn verify_entered_step_1(void *opaq= ue) =20 g_assert(qemu_coroutine_entered(self)); =20 - coroutine =3D qemu_coroutine_create(verify_entered_step_2, self); + coroutine =3D qemu_coroutine_create(qemu_get_aio_context(), + verify_entered_step_2, self); g_assert(!qemu_coroutine_entered(coroutine)); qemu_coroutine_enter(coroutine); g_assert(!qemu_coroutine_entered(coroutine)); @@ -88,7 +92,8 @@ static void test_entered(void) { Coroutine *coroutine; =20 - coroutine =3D qemu_coroutine_create(verify_entered_step_1, NULL); + coroutine =3D qemu_coroutine_create(qemu_get_aio_context(), + verify_entered_step_1, NULL); g_assert(!qemu_coroutine_entered(coroutine)); qemu_coroutine_enter(coroutine); } @@ -112,7 +117,8 @@ static void coroutine_fn nest(void *opaque) if (nd->n_enter < nd->max) { Coroutine *child; =20 - child =3D qemu_coroutine_create(nest, nd); + child =3D qemu_coroutine_create(qemu_get_aio_context(), + nest, nd); qemu_coroutine_enter(child); } =20 @@ -128,7 +134,8 @@ static void test_nesting(void) .max =3D 128, }; =20 - root =3D qemu_coroutine_create(nest, &nd); + root =3D qemu_coroutine_create(qemu_get_aio_context(), + nest, &nd); qemu_coroutine_enter(root); =20 /* Must enter and return from max nesting level */ @@ -157,7 +164,8 @@ static void test_yield(void) bool done =3D false; int i =3D -1; /* one extra time to return from coroutine */ =20 - coroutine =3D qemu_coroutine_create(yield_5_times, &done); + coroutine =3D qemu_coroutine_create(qemu_get_aio_context(), + yield_5_times, &done); while (!done) { qemu_coroutine_enter(coroutine); i++; @@ -182,8 +190,11 @@ static void test_co_queue(void) Coroutine *c2; Coroutine tmp; =20 - c2 =3D qemu_coroutine_create(c2_fn, NULL); - c1 =3D qemu_coroutine_create(c1_fn, c2); + qemu_init_main_loop(NULL); + c2 =3D qemu_coroutine_create(qemu_get_aio_context(), + c2_fn, NULL); + c1 =3D qemu_coroutine_create(qemu_get_aio_context(), + c1_fn, c2); =20 qemu_coroutine_enter(c1); =20 @@ -213,13 +224,15 @@ static void test_lifecycle(void) bool done =3D false; =20 /* Create, enter, and return from coroutine */ - coroutine =3D qemu_coroutine_create(set_and_exit, &done); + coroutine =3D qemu_coroutine_create(qemu_get_aio_context(), + set_and_exit, &done); qemu_coroutine_enter(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); + coroutine =3D qemu_coroutine_create(qemu_get_aio_context(), + set_and_exit, &done); qemu_coroutine_enter(coroutine); g_assert(done); /* expect done to be true (second time) */ } @@ -254,7 +267,8 @@ static void do_order_test(void) { Coroutine *co; =20 - co =3D qemu_coroutine_create(co_order_test, NULL); + co =3D qemu_coroutine_create(qemu_get_aio_context(), + co_order_test, NULL); record_push(1, 1); qemu_coroutine_enter(co); record_push(1, 2); @@ -296,7 +310,8 @@ static void perf_lifecycle(void) =20 g_test_timer_start(); for (i =3D 0; i < max; i++) { - coroutine =3D qemu_coroutine_create(empty_coroutine, NULL); + coroutine =3D qemu_coroutine_create(qemu_get_aio_context(), + empty_coroutine, NULL); qemu_coroutine_enter(coroutine); } duration =3D g_test_timer_elapsed(); @@ -320,7 +335,8 @@ static void perf_nesting(void) .n_return =3D 0, .max =3D maxnesting, }; - root =3D qemu_coroutine_create(nest, &nd); + root =3D qemu_coroutine_create(qemu_get_aio_context(), + nest, &nd); qemu_coroutine_enter(root); } duration =3D g_test_timer_elapsed(); @@ -350,7 +366,8 @@ static void perf_yield(void) =20 maxcycles =3D 100000000; i =3D maxcycles; - Coroutine *coroutine =3D qemu_coroutine_create(yield_loop, &i); + Coroutine *coroutine =3D qemu_coroutine_create(qemu_get_aio_context(), + yield_loop, &i); =20 g_test_timer_start(); while (i > 0) { @@ -400,7 +417,8 @@ static void perf_cost(void) =20 g_test_timer_start(); while (i++ < maxcycles) { - co =3D qemu_coroutine_create(perf_cost_func, &i); + co =3D qemu_coroutine_create(qemu_get_aio_context(), + perf_cost_func, &i); qemu_coroutine_enter(co); qemu_coroutine_enter(co); } diff --git a/tests/test-thread-pool.c b/tests/test-thread-pool.c index 91b4ec5..86d993a 100644 --- a/tests/test-thread-pool.c +++ b/tests/test-thread-pool.c @@ -92,7 +92,8 @@ static void co_test_cb(void *opaque) static void test_submit_co(void) { WorkerTestData data; - Coroutine *co =3D qemu_coroutine_create(co_test_cb, &data); + Coroutine *co =3D qemu_coroutine_create(qemu_get_aio_context(), + co_test_cb, &data); =20 qemu_coroutine_enter(co); =20 diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c index 72412e5..690d5a4 100644 --- a/util/qemu-coroutine.c +++ b/util/qemu-coroutine.c @@ -43,7 +43,8 @@ static void coroutine_pool_cleanup(Notifier *n, void *val= ue) } } =20 -Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque) +Coroutine *qemu_coroutine_create(AioContext *ctx, + CoroutineEntry *entry, void *opaque) { Coroutine *co =3D NULL; =20 @@ -78,6 +79,7 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, v= oid *opaque) =20 co->entry =3D entry; co->entry_arg =3D opaque; + co->ctx =3D ctx; QSIMPLEQ_INIT(&co->co_queue_wakeup); return co; } @@ -107,6 +109,7 @@ void qemu_coroutine_enter(Coroutine *co) Coroutine *self =3D qemu_coroutine_self(); CoroutineAction ret; =20 + assert(co->ctx); trace_qemu_coroutine_enter(self, co, co->entry_arg); =20 if (co->caller) { @@ -115,7 +118,6 @@ void qemu_coroutine_enter(Coroutine *co) } =20 co->caller =3D self; - co->ctx =3D qemu_get_current_aio_context(); =20 /* Store co->ctx before anything that stores co. Matches * barrier in aio_co_wake and qemu_co_mutex_wake. --=20 2.9.3